X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph-canvas.js;h=4f5bd6cd807c60709147fd0c05088f7bc545e9f4;hb=5c528fa23539203d0bfaa3fa1b3792c45b2a0d04;hp=09ce16b2ff7b85f14f0cdeb74077d3e1571e9056;hpb=afdc483f63032d8bba075b5a424ab48b32f9d332;p=dygraphs.git diff --git a/dygraph-canvas.js b/dygraph-canvas.js index 09ce16b..4f5bd6c 100644 --- a/dygraph-canvas.js +++ b/dygraph-canvas.js @@ -19,6 +19,7 @@ DygraphLayout = function(dygraph, options) { this.options = {}; // TODO(danvk): remove, use attr_ instead. Dygraph.update(this.options, options ? options : {}); this.datasets = new Array(); + this.annotations = new Array() }; DygraphLayout.prototype.attr_ = function(name) { @@ -29,10 +30,28 @@ DygraphLayout.prototype.addDataset = function(setname, set_xy) { this.datasets[setname] = set_xy; }; +// TODO(danvk): CONTRACT remove +DygraphLayout.prototype.setAnnotations = function(ann) { + // The Dygraph object's annotations aren't parsed. We parse them here and + // save a copy. + var parse = this.attr_('xValueParser'); + for (var i = 0; i < ann.length; i++) { + var a = {}; + if (!ann[i].x) { + this.dygraph_.error("Annotations must have an 'x' property"); + return; + } + Dygraph.update(a, ann[i]); + a.xval = parse(a.x); + this.annotations.push(a); + } +}; + DygraphLayout.prototype.evaluate = function() { this._evaluateLimits(); this._evaluateLineCharts(); this._evaluateLineTicks(); + this._evaluateAnnotations(); }; DygraphLayout.prototype._evaluateLimits = function() { @@ -141,6 +160,26 @@ DygraphLayout.prototype.evaluateWithError = function() { } }; +DygraphLayout.prototype._evaluateAnnotations = function() { + // Add the annotations to the point to which they belong. + // Make a map from (setName, xval) to annotation for quick lookups. + var annotations = {}; + for (var i = 0; i < this.annotations.length; i++) { + var a = this.annotations[i]; + annotations[a.xval + "," + a.series] = a; + } + + this.annotated_points = []; + for (var i = 0; i < this.points.length; i++) { + var p = this.points[i]; + var k = p.xval + "," + p.name; + if (k in annotations) { + p.annotation = annotations[k]; + this.annotated_points.push(p); + } + } +}; + /** * Convenience function to remove all the data sets from a graph */ @@ -205,6 +244,7 @@ DygraphCanvasRenderer = function(dygraph, element, layout, options) { // internal state this.xlabels = new Array(); this.ylabels = new Array(); + this.annotations = new Array(); this.area = { x: this.options.yAxisLabelWidth + 2 * this.options.axisTickSize, @@ -247,8 +287,13 @@ DygraphCanvasRenderer.prototype.clear = function() { var el = this.ylabels[i]; el.parentNode.removeChild(el); } + for (var i = 0; i < this.annotations.length; i++) { + var el = this.annotations[i]; + el.parentNode.removeChild(el); + } this.xlabels = new Array(); this.ylabels = new Array(); + this.annotations = new Array(); }; @@ -317,6 +362,7 @@ DygraphCanvasRenderer.prototype.render = function() { // Do the ordinary rendering, as before this._renderLineChart(); this._renderAxis(); + this._renderAnnotations(); }; @@ -444,6 +490,41 @@ DygraphCanvasRenderer.prototype._renderAxis = function() { }; +DygraphCanvasRenderer.prototype._renderAnnotations = function() { + var annotationStyle = { + "position": "absolute", + "fontSize": this.options.axisLabelFontSize + "px", + "zIndex": 10, + "width": "20px", + "overflow": "hidden", + }; + + // 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]; + var div = document.createElement("div"); + for (var name in annotationStyle) { + if (annotationStyle.hasOwnProperty(name)) { + div.style[name] = annotationStyle[name]; + } + } + div.className = "dygraphDefaultAnnotation"; + if (p.annotation.hasOwnProperty('cssClass')) { + div.className += " " + p.annotation.cssClass; + } + div.appendChild(document.createTextNode(p.annotation.shortText)); + div.style.left = (p.canvasx - 10) + "px"; + div.style.top = p.canvasy + "px"; + div.title = p.annotation.text; + div.style.color = this.colors[p.name]; + div.style.borderColor = this.colors[p.name]; + this.container.appendChild(div); + this.annotations.push(div); + } +}; + + /** * Overrides the CanvasRenderer method to draw error bars */ @@ -510,29 +591,30 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() { prevX = NaN; continue; } + // TODO(danvk): here if (stepPlot) { var newYs = [ prevY - point.errorPlus * yscale, - prevY + point.errorMinus * yscale ]; + prevY + point.errorMinus * yscale ]; prevY = point.y; } else { var newYs = [ point.y - point.errorPlus * yscale, - point.y + point.errorMinus * yscale ]; + point.y + point.errorMinus * yscale ]; } newYs[0] = this.area.h * newYs[0] + this.area.y; newYs[1] = this.area.h * newYs[1] + this.area.y; if (!isNaN(prevX)) { if (stepPlot) { - ctx.moveTo(prevX, newYs[0]); + ctx.moveTo(prevX, newYs[0]); } else { - ctx.moveTo(prevX, prevYs[0]); + ctx.moveTo(prevX, prevYs[0]); } ctx.lineTo(point.canvasx, newYs[0]); ctx.lineTo(point.canvasx, newYs[1]); if (stepPlot) { - ctx.lineTo(prevX, newYs[1]); + ctx.lineTo(prevX, newYs[1]); } else { - ctx.lineTo(prevX, prevYs[1]); + ctx.lineTo(prevX, prevYs[1]); } ctx.closePath(); } @@ -585,9 +667,9 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() { if (!isNaN(prevX)) { ctx.moveTo(prevX, prevYs[0]); if (stepPlot) { - ctx.lineTo(point.canvasx, prevYs[0]); + ctx.lineTo(point.canvasx, prevYs[0]); } else { - ctx.lineTo(point.canvasx, newYs[0]); + ctx.lineTo(point.canvasx, newYs[0]); } ctx.lineTo(point.canvasx, newYs[1]); ctx.lineTo(prevX, prevYs[1]); @@ -633,7 +715,7 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() { ctx.lineWidth = this.options.strokeWidth; ctx.moveTo(prevX, prevY); if (stepPlot) { - ctx.lineTo(point.canvasx, prevY); + ctx.lineTo(point.canvasx, prevY); } prevX = point.canvasx; prevY = point.canvasy;