- ctx.lineWidth = this.options.strokeWidth;
- var prevX = -1;
- var prevYs = [-1, -1];
- var count = 0;
- var yscale = this.layout.yscale;
- // should be same color as the lines but only 15% opaque.
- var rgb = new RGBColor(color);
- var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',0.15)';
- ctx.fillStyle = err_color;
- ctx.beginPath();
- for (var j = 0; j < this.layout.points.length; j++) {
- var point = this.layout.points[j];
- count++;
- if (point.name == setName) {
- if (!point.y || isNaN(point.y)) {
- prevX = -1;
- continue;
- }
- var newYs = [ point.y - point.errorPlus * 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 (prevX >= 0) {
- ctx.moveTo(prevX, prevYs[0]);
- ctx.lineTo(point.canvasx, newYs[0]);
- ctx.lineTo(point.canvasx, newYs[1]);
- ctx.lineTo(prevX, prevYs[1]);
- ctx.closePath();
- }
- prevYs[0] = newYs[0];
- prevYs[1] = newYs[1];
- prevX = point.canvasx;
- }
+ ctx.lineWidth = strokeWidth;
+ p({
+ points: points,
+ setName: setName,
+ drawingContext: ctx,
+ color: color,
+ strokeWidth: strokeWidth,
+ dygraph: this.dygraph_,
+ axis: this.dygraph_.axisPropertiesForSeries(setName),
+ plotArea: this.area,
+ seriesIndex: j,
+ seriesCount: sets.length,
+ allSeriesPoints: sets
+ });
+ ctx.restore();
+ }
+ }
+};
+
+/**
+ * Standard plotters. These may be used by clients via Dygraph.Plotters.
+ * See comments there for more details.
+ */
+DygraphCanvasRenderer._Plotters = {
+ linePlotter: function(e) {
+ DygraphCanvasRenderer._linePlotter(e);
+ },
+
+ fillPlotter: function(e) {
+ DygraphCanvasRenderer._fillPlotter(e);
+ },
+
+ errorPlotter: function(e) {
+ DygraphCanvasRenderer._errorPlotter(e);
+ }
+};
+
+/**
+ * Plotter which draws the central lines for a series.
+ * @private
+ */
+DygraphCanvasRenderer._linePlotter = function(e) {
+ var g = e.dygraph;
+ var setName = e.setName;
+ var strokeWidth = e.strokeWidth;
+
+ // TODO(danvk): Check if there's any performance impact of just calling
+ // getOption() inside of _drawStyledLine. Passing in so many parameters makes
+ // this code a bit nasty.
+ var borderWidth = g.getOption("strokeBorderWidth", setName);
+ var drawPointCallback = g.getOption("drawPointCallback", setName) ||
+ Dygraph.Circles.DEFAULT;
+ var strokePattern = g.getOption("strokePattern", setName);
+ var drawPoints = g.getOption("drawPoints", setName);
+ var pointSize = g.getOption("pointSize", setName);
+
+ if (borderWidth && strokeWidth) {
+ DygraphCanvasRenderer._drawStyledLine(e,
+ g.getOption("strokeBorderColor", setName),
+ strokeWidth + 2 * borderWidth,
+ strokePattern,
+ drawPoints,
+ drawPointCallback,
+ pointSize
+ );
+ }
+
+ DygraphCanvasRenderer._drawStyledLine(e,
+ e.color,
+ strokeWidth,
+ strokePattern,
+ drawPoints,
+ drawPointCallback,
+ pointSize
+ );
+};
+
+/**
+ * Draws the shaded error bars/confidence intervals for each series.
+ * This happens before the center lines are drawn, since the center lines
+ * need to be drawn on top of the error bars for all series.
+ * @private
+ */
+DygraphCanvasRenderer._errorPlotter = function(e) {
+ var g = e.dygraph;
+ var setName = e.setName;
+ var errorBars = g.getOption("errorBars") || g.getOption("customBars");
+ if (!errorBars) return;
+
+ var fillGraph = g.getOption("fillGraph", setName);
+ if (fillGraph) {
+ g.warn("Can't use fillGraph option with error bars");
+ }
+
+ var ctx = e.drawingContext;
+ var color = e.color;
+ var fillAlpha = g.getOption('fillAlpha', setName);
+ var stepPlot = g.getOption('stepPlot'); // TODO(danvk): per-series
+ var axis = e.axis;
+ var points = e.points;
+
+ var iter = Dygraph.createIterator(points, 0, points.length,
+ DygraphCanvasRenderer._getIteratorPredicate(
+ g.getOption("connectSeparatedPoints")));
+
+ var newYs;
+
+ // setup graphics context
+ var prevX = NaN;
+ var prevY = NaN;
+ var prevYs = [-1, -1];
+ var yscale = axis.yscale;
+ // should be same color as the lines but only 15% opaque.
+ var rgb = new RGBColor(color);
+ var err_color =
+ 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
+ ctx.fillStyle = err_color;
+ ctx.beginPath();
+
+ var isNullUndefinedOrNaN = function(x) {
+ return (x === null ||
+ x === undefined ||
+ isNaN(x));
+ };
+
+ while (iter.hasNext) {
+ var point = iter.next();
+ if ((!stepPlot && isNullUndefinedOrNaN(point.y)) ||
+ (stepPlot && !isNaN(prevY) && isNullUndefinedOrNaN(prevY))) {
+ prevX = NaN;
+ continue;
+ }
+
+ if (stepPlot) {
+ newYs = [ point.y_bottom, point.y_top ];
+ prevY = point.y;
+ } else {
+ newYs = [ point.y_bottom, point.y_top ];
+ }
+ newYs[0] = e.plotArea.h * newYs[0] + e.plotArea.y;
+ newYs[1] = e.plotArea.h * newYs[1] + e.plotArea.y;
+ if (!isNaN(prevX)) {
+ if (stepPlot) {
+ ctx.moveTo(prevX, prevYs[0]);
+ ctx.lineTo(point.canvasx, prevYs[0]);
+ ctx.lineTo(point.canvasx, prevYs[1]);
+ } else {
+ ctx.moveTo(prevX, prevYs[0]);
+ ctx.lineTo(point.canvasx, newYs[0]);
+ ctx.lineTo(point.canvasx, newYs[1]);