annotations plugin appears to be working
authorDan Vanderkam <dan@dygraphs.com>
Fri, 6 Jul 2012 02:42:54 +0000 (19:42 -0700)
committerDan Vanderkam <dan@dygraphs.com>
Fri, 6 Jul 2012 02:42:54 +0000 (19:42 -0700)
dygraph-canvas.js
dygraph-dev.js
dygraph.js
generate-combined.sh
plugins/annotations.js [new file with mode: 0644]
plugins/install.js

index cf51f63..8cb0040 100644 (file)
@@ -232,7 +232,7 @@ DygraphCanvasRenderer.prototype.render = function() {
   // Do the ordinary rendering, as before
   this._renderLineChart();
   this._renderAxis();
-  this._renderAnnotations();
+  // this._renderAnnotations();
 };
 
 DygraphCanvasRenderer.prototype._createIEClipArea = function() {
@@ -795,10 +795,10 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
   var setCount = setNames.length;
 
   // TODO(danvk): Move this mapping into Dygraph and get it out of here.
-  this.colors = {};
-  for (i = 0; i < setCount; i++) {
-    this.colors[setNames[i]] = this.colorScheme_[i % this.colorScheme_.length];
-  }
+  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
index e659221..21bc470 100644 (file)
@@ -30,6 +30,7 @@
     "plugins/base.js",
     "plugins/legend.js",
     "plugins/chart-labels.js",
+    "plugins/annotations.js",
     "plugins/install.js",
     "dygraph-options-reference.js"  // Shouldn't be included in generate-combined.sh
   ];
index 38c1d05..aa8d848 100644 (file)
@@ -1063,8 +1063,10 @@ Dygraph.prototype.createMouseEventElement_ = function() {
  * @private
  */
 Dygraph.prototype.setColors_ = function() {
-  var num = this.attr_("labels").length - 1;
+  var labels = this.getLabels();
+  var num = labels.length - 1;
   this.colors_ = [];
+  this.colorsMap_ = {};
   var colors = this.attr_('colors');
   var i;
   if (!colors) {
@@ -1076,13 +1078,16 @@ Dygraph.prototype.setColors_ = function() {
       // alternate colors for high contrast.
       var idx = i % 2 ? Math.ceil(i / 2) : (half + i / 2);
       var hue = (1.0 * idx/ (1 + num));
-      this.colors_.push(Dygraph.hsvToRGB(hue, sat, val));
+      var colorStr = Dygraph.hsvToRGB(hue, sat, val);
+      this.colors_.push(colorStr);
+      this.colorsMap_[labels[i]] = colorStr;
     }
   } else {
     for (i = 0; i < num; i++) {
       if (!this.visibility()[i]) continue;
       var colorStr = colors[i % colors.length];
       this.colors_.push(colorStr);
+      this.colorsMap_[labels[1 + i]] = colorStr;
     }
   }
 
@@ -2349,7 +2354,10 @@ Dygraph.prototype.renderGraph_ = function(is_initial_draw) {
     this.rangeSelector_.renderInteractiveLayer();
   }
 
-  this.cascadeEvents_('drawChart');
+  this.cascadeEvents_('drawChart', {
+    canvas: this.hidden_,
+    drawingContext: this.hidden_ctx_,
+  });
   if (this.attr_("drawCallback") !== null) {
     this.attr_("drawCallback")(this, is_initial_draw);
   }
index ab3a53d..a065ffa 100755 (executable)
@@ -19,6 +19,7 @@ strftime/strftime-min.js \
 plugins/base.js \
 plugins/legend.js \
 plugins/chart-labels \
+plugins/annotations.js \
 plugins/install.js \
 | perl -ne 'print unless m,REMOVE_FOR_COMBINED,..m,/REMOVE_FOR_COMBINED,' \
 > /tmp/dygraph.js
diff --git a/plugins/annotations.js b/plugins/annotations.js
new file mode 100644 (file)
index 0000000..a3a13c3
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * @license
+ * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
+ * MIT-licensed (http://opensource.org/licenses/MIT)
+ */
+
+Dygraph.Plugins.Annotations = (function() {
+
+/**
+Current bits of jankiness:
+- Uses dygraph.layout_ to get the parsed annotations.
+- Uses dygraph.plotter_.area
+*/
+
+var annotations = function() {
+  this.annotations_ = [];
+};
+
+annotations.prototype.toString = function() {
+  return "Annotations Plugin";
+};
+
+annotations.prototype.activate = function(g) {
+  return {
+    clearChart: this.clearChart,
+    drawChart: this.drawChart
+  };
+};
+
+annotations.prototype.detachLabels = function() {
+  for (var i = 0; i < this.annotations_.length; i++) {
+    var a = this.annotations_[i];
+    if (a.parentNode) a.parentNode.removeChild(a);
+    this.annotations_[i] = null;
+  }
+  this.annotations_ = [];
+};
+
+annotations.prototype.clearChart = function(e) {
+  this.detachLabels();
+};
+
+annotations.prototype.drawChart = function(e) {
+  var g = e.dygraph;
+
+  // Early out in the (common) case of zero annotations.
+  var points = g.layout_.annotated_points;
+  if (!points || points.length == 0) return;
+
+  var containerDiv = e.canvas.parentNode;
+  var annotationStyle = {
+    "position": "absolute",
+    "fontSize": g.getOption('axisLabelFontSize') + "px",
+    "zIndex": 10,
+    "overflow": "hidden"
+  };
+
+  var bindEvt = function(eventName, classEventName, pt) {
+    return function(annotation_event) {
+      var a = pt.annotation;
+      if (a.hasOwnProperty(eventName)) {
+        a[eventName](a, pt, g, annotation_event);
+      } else if (g.getOption(classEventName)) {
+        g.getOption(classEventName)(a, pt, g, annotation_event );
+      }
+    };
+  };
+
+  // Add the annotations one-by-one.
+  var area = e.dygraph.plotter_.area;
+  for (var i = 0; i < points.length; i++) {
+    var p = points[i];
+    if (p.canvasx < area.x || p.canvasx > area.x + area.w ||
+        p.canvasy < area.y || p.canvasy > area.y + 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 = (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 = g.colorsMap_[p.name];
+    div.style.borderColor = g.colorsMap_[p.name];
+    a.div = div;
+
+    g.addEvent(div, 'click',
+        bindEvt('clickHandler', 'annotationClickHandler', p, this));
+    g.addEvent(div, 'mouseover',
+        bindEvt('mouseOverHandler', 'annotationMouseOverHandler', p, this));
+    g.addEvent(div, 'mouseout',
+        bindEvt('mouseOutHandler', 'annotationMouseOutHandler', p, this));
+    g.addEvent(div, 'dblclick',
+        bindEvt('dblClickHandler', 'annotationDblClickHandler', p, this));
+
+    containerDiv.appendChild(div);
+    this.annotations_.push(div);
+
+    var ctx = e.drawingContext;
+    ctx.save();
+    ctx.strokeStyle = g.colorsMap_[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, area.h);
+      ctx.lineTo(p.canvasx, area.h - 2 - tick_height);
+    }
+    ctx.closePath();
+    ctx.stroke();
+    ctx.restore();
+  }
+};
+
+annotations.prototype.destroy = function() {
+  this.detachLabels();
+};
+
+return annotations;
+
+})();
index 9490dfc..4e962a1 100644 (file)
@@ -1,5 +1,6 @@
 // TODO(danvk): move this into the top-level directory. Only plugins here.
 Dygraph.PLUGINS.push(
   Dygraph.Plugins.Legend,
-  Dygraph.Plugins.ChartLabels
+  Dygraph.Plugins.ChartLabels,
+  Dygraph.Plugins.Annotations
 );