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) {
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() {
}
};
+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
*/
// internal state
this.xlabels = new Array();
this.ylabels = new Array();
+ this.annotations = new Array();
this.area = {
x: this.options.yAxisLabelWidth + 2 * this.options.axisTickSize,
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();
};
// Do the ordinary rendering, as before
this._renderLineChart();
this._renderAxis();
+ this._renderAnnotations();
};
};
+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
*/
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();
}
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]);
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;