+ // process sets in reverse order (needed for stacked graphs)
+ for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) {
+ var ctx = e.drawingContext;
+ var setName = setNames[setIdx];
+ if (!g.getBooleanOption('fillGraph', setName)) continue;
+
+ var stepPlot = g.getBooleanOption('stepPlot', setName);
+ var color = colors[setIdx];
+ var axis = g.axisPropertiesForSeries(setName);
+ var axisY = 1.0 + axis.minyval * axis.yscale;
+ if (axisY < 0.0) axisY = 0.0;
+ else if (axisY > 1.0) axisY = 1.0;
+ axisY = area.h * axisY + area.y;
+
+ var points = sets[setIdx];
+ var iter = Dygraph.createIterator(points, 0, points.length,
+ DygraphCanvasRenderer._getIteratorPredicate(
+ g.getBooleanOption("connectSeparatedPoints", setName)));
+
+ // setup graphics context
+ var prevX = NaN;
+ var prevYs = [-1, -1];
+ var newYs;
+ // should be same color as the lines but only 15% opaque.
+ var rgb = Dygraph.toRGB_(color);
+ var err_color =
+ 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
+ ctx.fillStyle = err_color;
+ ctx.beginPath();
+ var last_x, is_first = true;
+
+ // If the point density is high enough, dropping segments on their way to
+ // the canvas justifies the overhead of doing so.
+ if (points.length > 2 * g.width_) {
+ ctx = DygraphCanvasRenderer._fastCanvasProxy(ctx);
+ }
+
+ // For filled charts, we draw points from left to right, then back along
+ // the x-axis to complete a shape for filling.
+ // For stacked plots, this "back path" is a more complex shape. This array
+ // stores the [x, y] values needed to trace that shape.
+ var pathBack = [];
+
+ // TODO(danvk): there are a lot of options at play in this loop.
+ // The logic would be much clearer if some (e.g. stackGraph and
+ // stepPlot) were split off into separate sub-plotters.
+ var point;
+ while (iter.hasNext) {
+ point = iter.next();
+ if (!Dygraph.isOK(point.y) && !stepPlot) {
+ traceBackPath(ctx, prevX, prevYs[1], pathBack);
+ pathBack = [];
+ prevX = NaN;
+ if (point.y_stacked !== null && !isNaN(point.y_stacked)) {
+ baseline[point.canvasx] = area.h * point.y_stacked + area.y;
+ }
+ continue;
+ }
+ if (stackedGraph) {
+ if (!is_first && last_x == point.xval) {
+ continue;
+ } else {
+ is_first = false;
+ last_x = point.xval;
+ }