Checkpoint: axes fully ported to plugin system. All tests pass.
[dygraphs.git] / dygraph-canvas.js
index 8cb0040..5326673 100644 (file)
@@ -62,10 +62,6 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) {
       throw "Canvas is not supported.";
 
   // internal state
-  this.xlabels = [];
-  this.ylabels = [];
-  this.annotations = [];
-
   this.area = layout.getPlotArea();
   this.container.style.position = "relative";
   this.container.style.width = this.width + "px";
@@ -122,21 +118,6 @@ DygraphCanvasRenderer.prototype.clear = function() {
 
   context = this.elementContext;
   context.clearRect(0, 0, this.width, this.height);
-
-  function removeArray(ary) {
-    for (var i = 0; i < ary.length; i++) {
-      var el = ary[i];
-      if (el.parentNode) el.parentNode.removeChild(el);
-    }
-  }
-
-  removeArray(this.xlabels);
-  removeArray(this.ylabels);
-  removeArray(this.annotations);
-
-  this.xlabels = [];
-  this.ylabels = [];
-  this.annotations = [];
 };
 
 /**
@@ -231,8 +212,6 @@ DygraphCanvasRenderer.prototype.render = function() {
 
   // Do the ordinary rendering, as before
   this._renderLineChart();
-  this._renderAxis();
-  // this._renderAnnotations();
 };
 
 DygraphCanvasRenderer.prototype._createIEClipArea = function() {
@@ -304,283 +283,6 @@ DygraphCanvasRenderer.prototype._createIEClipArea = function() {
   });
 };
 
-DygraphCanvasRenderer.prototype._renderAxis = function() {
-  if (!this.attr_('drawXAxis') && !this.attr_('drawYAxis')) return;
-
-  // Round pixels to half-integer boundaries for crisper drawing.
-  function halfUp(x)  { return Math.round(x) + 0.5; }
-  function halfDown(y){ return Math.round(y) - 0.5; }
-
-  var context = this.elementContext;
-
-  var label, x, y, tick, i;
-
-  var labelStyle = {
-    position: "absolute",
-    fontSize: this.attr_('axisLabelFontSize') + "px",
-    zIndex: 10,
-    color: this.attr_('axisLabelColor'),
-    width: this.attr_('axisLabelWidth') + "px",
-    // height: this.attr_('axisLabelFontSize') + 2 + "px",
-    lineHeight: "normal",  // Something other than "normal" line-height screws up label positioning.
-    overflow: "hidden"
-  };
-  var makeDiv = function(txt, axis, prec_axis) {
-    var div = document.createElement("div");
-    for (var name in labelStyle) {
-      if (labelStyle.hasOwnProperty(name)) {
-        div.style[name] = labelStyle[name];
-      }
-    }
-    var inner_div = document.createElement("div");
-    inner_div.className = 'dygraph-axis-label' +
-                          ' dygraph-axis-label-' + axis +
-                          (prec_axis ? ' dygraph-axis-label-' + prec_axis : '');
-    inner_div.innerHTML=txt;
-    div.appendChild(inner_div);
-    return div;
-  };
-
-  // axis lines
-  context.save();
-  context.strokeStyle = this.attr_('axisLineColor');
-  context.lineWidth = this.attr_('axisLineWidth');
-
-  if (this.attr_('drawYAxis')) {
-    if (this.layout.yticks && this.layout.yticks.length > 0) {
-      var num_axes = this.dygraph_.numAxes();
-      for (i = 0; i < this.layout.yticks.length; i++) {
-        tick = this.layout.yticks[i];
-        if (typeof(tick) == "function") return;
-        x = this.area.x;
-        var sgn = 1;
-        var prec_axis = 'y1';
-        if (tick[0] == 1) {  // right-side y-axis
-          x = this.area.x + this.area.w;
-          sgn = -1;
-          prec_axis = 'y2';
-        }
-        y = this.area.y + tick[1] * this.area.h;
-
-        /* Tick marks are currently clipped, so don't bother drawing them.
-        context.beginPath();
-        context.moveTo(halfUp(x), halfDown(y));
-        context.lineTo(halfUp(x - sgn * this.attr_('axisTickSize')), halfDown(y));
-        context.closePath();
-        context.stroke();
-        */
-
-        label = makeDiv(tick[2], 'y', num_axes == 2 ? prec_axis : null);
-        var top = (y - this.attr_('axisLabelFontSize') / 2);
-        if (top < 0) top = 0;
-
-        if (top + this.attr_('axisLabelFontSize') + 3 > this.height) {
-          label.style.bottom = "0px";
-        } else {
-          label.style.top = top + "px";
-        }
-        if (tick[0] === 0) {
-          label.style.left = (this.area.x - this.attr_('yAxisLabelWidth') - this.attr_('axisTickSize')) + "px";
-          label.style.textAlign = "right";
-        } else if (tick[0] == 1) {
-          label.style.left = (this.area.x + this.area.w +
-                              this.attr_('axisTickSize')) + "px";
-          label.style.textAlign = "left";
-        }
-        label.style.width = this.attr_('yAxisLabelWidth') + "px";
-        this.container.appendChild(label);
-        this.ylabels.push(label);
-      }
-
-      // The lowest tick on the y-axis often overlaps with the leftmost
-      // tick on the x-axis. Shift the bottom tick up a little bit to
-      // compensate if necessary.
-      var bottomTick = this.ylabels[0];
-      var fontSize = this.attr_('axisLabelFontSize');
-      var bottom = parseInt(bottomTick.style.top, 10) + fontSize;
-      if (bottom > this.height - fontSize) {
-        bottomTick.style.top = (parseInt(bottomTick.style.top, 10) -
-            fontSize / 2) + "px";
-      }
-    }
-
-    // draw a vertical line on the left to separate the chart from the labels.
-    var axisX;
-    if (this.attr_('drawAxesAtZero')) {
-      var r = this.dygraph_.toPercentXCoord(0);
-      if (r > 1 || r < 0) r = 0;
-      axisX = halfUp(this.area.x + r * this.area.w);
-    } else {
-      axisX = halfUp(this.area.x);
-    }
-    context.beginPath();
-    context.moveTo(axisX, halfDown(this.area.y));
-    context.lineTo(axisX, halfDown(this.area.y + this.area.h));
-    context.closePath();
-    context.stroke();
-
-    // if there's a secondary y-axis, draw a vertical line for that, too.
-    if (this.dygraph_.numAxes() == 2) {
-      context.beginPath();
-      context.moveTo(halfDown(this.area.x + this.area.w), halfDown(this.area.y));
-      context.lineTo(halfDown(this.area.x + this.area.w), halfDown(this.area.y + this.area.h));
-      context.closePath();
-      context.stroke();
-    }
-  }
-
-  if (this.attr_('drawXAxis')) {
-    if (this.layout.xticks) {
-      for (i = 0; i < this.layout.xticks.length; i++) {
-        tick = this.layout.xticks[i];
-        x = this.area.x + tick[0] * this.area.w;
-        y = this.area.y + this.area.h;
-
-        /* Tick marks are currently clipped, so don't bother drawing them.
-        context.beginPath();
-        context.moveTo(halfUp(x), halfDown(y));
-        context.lineTo(halfUp(x), halfDown(y + this.attr_('axisTickSize')));
-        context.closePath();
-        context.stroke();
-        */
-
-        label = makeDiv(tick[1], 'x');
-        label.style.textAlign = "center";
-        label.style.top = (y + this.attr_('axisTickSize')) + 'px';
-
-        var left = (x - this.attr_('axisLabelWidth')/2);
-        if (left + this.attr_('axisLabelWidth') > this.width) {
-          left = this.width - this.attr_('xAxisLabelWidth');
-          label.style.textAlign = "right";
-        }
-        if (left < 0) {
-          left = 0;
-          label.style.textAlign = "left";
-        }
-
-        label.style.left = left + "px";
-        label.style.width = this.attr_('xAxisLabelWidth') + "px";
-        this.container.appendChild(label);
-        this.xlabels.push(label);
-      }
-    }
-
-    context.beginPath();
-    var axisY;
-    if (this.attr_('drawAxesAtZero')) {
-      var r = this.dygraph_.toPercentYCoord(0, 0);
-      if (r > 1 || r < 0) r = 1;
-      axisY = halfDown(this.area.y + r * this.area.h);
-    } else {
-      axisY = halfDown(this.area.y + this.area.h);
-    }
-    context.moveTo(halfUp(this.area.x), axisY);
-    context.lineTo(halfUp(this.area.x + this.area.w), axisY);
-    context.closePath();
-    context.stroke();
-  }
-
-  context.restore();
-};
-
-
-DygraphCanvasRenderer.prototype._renderAnnotations = function() {
-  var annotationStyle = {
-    "position": "absolute",
-    "fontSize": this.attr_('axisLabelFontSize') + "px",
-    "zIndex": 10,
-    "overflow": "hidden"
-  };
-
-  var bindEvt = function(eventName, classEventName, p, self) {
-    return function(e) {
-      var a = p.annotation;
-      if (a.hasOwnProperty(eventName)) {
-        a[eventName](a, p, self.dygraph_, e);
-      } else if (self.dygraph_.attr_(classEventName)) {
-        self.dygraph_.attr_(classEventName)(a, p, self.dygraph_,e );
-      }
-    };
-  };
-
-  // Get a list of point with annotations.
-  var points = this.layout.annotated_points;
-  for (var i = 0; i < points.length; i++) {
-    var p = points[i];
-    if (p.canvasx < this.area.x || p.canvasx > this.area.x + this.area.w ||
-        p.canvasy < this.area.y || p.canvasy > this.area.y + this.area.h) {
-      continue;
-    }
-
-    var a = p.annotation;
-    var tick_height = 6;
-    if (a.hasOwnProperty("tickHeight")) {
-      tick_height = a.tickHeight;
-    }
-
-    var div = document.createElement("div");
-    for (var name in annotationStyle) {
-      if (annotationStyle.hasOwnProperty(name)) {
-        div.style[name] = annotationStyle[name];
-      }
-    }
-    if (!a.hasOwnProperty('icon')) {
-      div.className = "dygraphDefaultAnnotation";
-    }
-    if (a.hasOwnProperty('cssClass')) {
-      div.className += " " + a.cssClass;
-    }
-
-    var width = a.hasOwnProperty('width') ? a.width : 16;
-    var height = a.hasOwnProperty('height') ? a.height : 16;
-    if (a.hasOwnProperty('icon')) {
-      var img = document.createElement("img");
-      img.src = a.icon;
-      img.width = width;
-      img.height = height;
-      div.appendChild(img);
-    } else if (p.annotation.hasOwnProperty('shortText')) {
-      div.appendChild(document.createTextNode(p.annotation.shortText));
-    }
-    div.style.left = (p.canvasx - width / 2) + "px";
-    if (a.attachAtBottom) {
-      div.style.top = (this.area.h - height - tick_height) + "px";
-    } else {
-      div.style.top = (p.canvasy - height - tick_height) + "px";
-    }
-    div.style.width = width + "px";
-    div.style.height = height + "px";
-    div.title = p.annotation.text;
-    div.style.color = this.colors[p.name];
-    div.style.borderColor = this.colors[p.name];
-    a.div = div;
-
-    this.dygraph_.addEvent(div, 'click',
-        bindEvt('clickHandler', 'annotationClickHandler', p, this));
-    this.dygraph_.addEvent(div, 'mouseover',
-        bindEvt('mouseOverHandler', 'annotationMouseOverHandler', p, this));
-    this.dygraph_.addEvent(div, 'mouseout',
-        bindEvt('mouseOutHandler', 'annotationMouseOutHandler', p, this));
-    this.dygraph_.addEvent(div, 'dblclick',
-        bindEvt('dblClickHandler', 'annotationDblClickHandler', p, this));
-
-    this.container.appendChild(div);
-    this.annotations.push(div);
-
-    var ctx = this.elementContext;
-    ctx.strokeStyle = this.colors[p.name];
-    ctx.beginPath();
-    if (!a.attachAtBottom) {
-      ctx.moveTo(p.canvasx, p.canvasy);
-      ctx.lineTo(p.canvasx, p.canvasy - 2 - tick_height);
-    } else {
-      ctx.moveTo(p.canvasx, this.area.h);
-      ctx.lineTo(p.canvasx, this.area.h - 2 - tick_height);
-    }
-    ctx.closePath();
-    ctx.stroke();
-  }
-};
 
 /**
  * Returns a predicate to be used with an iterator, which will
@@ -794,11 +496,7 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
   var setNames = this.layout.setNames;
   var setCount = setNames.length;
 
-  // TODO(danvk): Move this mapping into Dygraph and get it out of here.
   this.colors = this.dygraph_.colorsMap_;
-  // for (i = 0; i < setCount; i++) {
-  //   this.colors[setNames[i]] = this.colorScheme_[i % this.colorScheme_.length];
-  // }
 
   // Update Points
   // TODO(danvk): here