From ee53deb9db465f5eea54e102ca755decef005496 Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Thu, 5 Jul 2012 19:42:54 -0700 Subject: [PATCH] annotations plugin appears to be working --- dygraph-canvas.js | 10 ++-- dygraph-dev.js | 1 + dygraph.js | 14 ++++- generate-combined.sh | 1 + plugins/annotations.js | 156 +++++++++++++++++++++++++++++++++++++++++++++++++ plugins/install.js | 3 +- 6 files changed, 176 insertions(+), 9 deletions(-) create mode 100644 plugins/annotations.js diff --git a/dygraph-canvas.js b/dygraph-canvas.js index cf51f63..8cb0040 100644 --- a/dygraph-canvas.js +++ b/dygraph-canvas.js @@ -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 diff --git a/dygraph-dev.js b/dygraph-dev.js index e659221..21bc470 100644 --- a/dygraph-dev.js +++ b/dygraph-dev.js @@ -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 ]; diff --git a/dygraph.js b/dygraph.js index 38c1d05..aa8d848 100644 --- a/dygraph.js +++ b/dygraph.js @@ -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); } diff --git a/generate-combined.sh b/generate-combined.sh index ab3a53d..a065ffa 100755 --- a/generate-combined.sh +++ b/generate-combined.sh @@ -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 index 0000000..a3a13c3 --- /dev/null +++ b/plugins/annotations.js @@ -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; + +})(); diff --git a/plugins/install.js b/plugins/install.js index 9490dfc..4e962a1 100644 --- a/plugins/install.js +++ b/plugins/install.js @@ -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 ); -- 2.7.4