Fix bug 329 which accumulates clipping rectangles on subsequent draws.
[dygraphs.git] / dygraph-canvas.js
index 29e402e..e531ece 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*jshint globalstrict: true */
-/*global Dygraph:false,RGBColor:false */
+/*global Dygraph:false,RGBColorParser:false */
 "use strict";
 
 
@@ -57,6 +57,8 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) {
   this.height = this.element.height;
   this.width = this.element.width;
 
+  this.elementContext.save();
+
   // --- check whether everything is ok before we return
   if (!this.isIE && !(DygraphCanvasRenderer.isSupported(this.element)))
       throw "Canvas is not supported.";
@@ -125,6 +127,11 @@ DygraphCanvasRenderer.prototype.clear = function() {
   context.clearRect(0, 0, this.width, this.height);
 };
 
+DygraphCanvasRenderer.prototype.onDoneDrawing = function() {
+  // balances the save called in the constructor.
+  this.elementContext.restore();
+}
+
 /**
  * Checks whether the browser supports the <canvas> tag.
  * @private
@@ -261,7 +268,8 @@ DygraphCanvasRenderer._drawStyledLine = function(e,
     drawPointCallback, pointSize) {
   var g = e.dygraph;
   // TODO(konigsberg): Compute attributes outside this method call.
-  var stepPlot = g.getOption("stepPlot");  // TODO(danvk): per-series
+  var stepPlot = g.getOption("stepPlot", e.setName);
+
   if (!Dygraph.isArrayLike(strokePattern)) {
     strokePattern = null;
   }
@@ -343,7 +351,7 @@ DygraphCanvasRenderer._drawSeries = function(e,
       isIsolated = false;
       if (drawGapPoints || !prevCanvasX) {
         iter.nextIdx_ = i;
-        var peek = iter.next();
+        iter.next();
         nextCanvasY = iter.hasNext ? iter.peek.canvasy : null;
 
         var isNextCanvasYNullOrNaN = nextCanvasY === null ||
@@ -444,13 +452,10 @@ DygraphCanvasRenderer.prototype._updatePoints = function() {
  */
 DygraphCanvasRenderer.prototype._renderLineChart = function(opt_seriesName, opt_ctx) {
   var ctx = opt_ctx || this.elementContext;
-  var errorBars = this.attr_("errorBars") || this.attr_("customBars");
-  var fillGraph = this.attr_("fillGraph");
   var i;
 
   var sets = this.layout.points;
   var setNames = this.layout.setNames;
-  var setCount = setNames.length;
   var setName;
 
   this.colors = this.dygraph_.colorsMap_;
@@ -477,7 +482,7 @@ DygraphCanvasRenderer.prototype._renderLineChart = function(opt_seriesName, opt_
 
     for (var j = 0; j < sets.length; j++) {
       setName = setNames[j];
-      if (opt_seriesName && setName != opt_seriesName) continue;
+      if (opt_seriesName && !(is_last && setName == opt_seriesName)) continue;
 
       var points = sets[j];
 
@@ -594,8 +599,7 @@ DygraphCanvasRenderer._errorPlotter = function(e) {
   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 stepPlot = g.getOption("stepPlot", setName);
   var points = e.points;
 
   var iter = Dygraph.createIterator(points, 0, points.length,
@@ -608,9 +612,8 @@ DygraphCanvasRenderer._errorPlotter = function(e) {
   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 rgb = new RGBColorParser(color);
   var err_color =
       'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
   ctx.fillStyle = err_color;
@@ -696,18 +699,19 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
   var setCount = sets.length;
 
   var fillAlpha = g.getOption('fillAlpha');
-  var stepPlot = g.getOption('stepPlot');
   var stackedGraph = g.getOption("stackedGraph");
   var colors = g.getColors();
 
   var baseline = {};  // for stacked graphs: baseline for filling
   var currBaseline;
+  var prevStepPlot;  // for different line drawing modes (line/step) per series
 
   // process sets in reverse order (needed for stacked graphs)
   for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) {
     var setName = setNames[setIdx];
     if (!g.getOption('fillGraph', setName)) continue;
-
+    
+    var stepPlot = g.getOption('stepPlot', setName);
     var color = colors[setIdx];
     var axis = g.axisPropertiesForSeries(setName);
     var axisY = 1.0 + axis.minyval * axis.yscale;
@@ -724,9 +728,8 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
     var prevX = NaN;
     var prevYs = [-1, -1];
     var newYs;
-    var yscale = axis.yscale;
     // should be same color as the lines but only 15% opaque.
-    var rgb = new RGBColor(color);
+    var rgb = new RGBColorParser(color);
     var err_color =
         'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
     ctx.fillStyle = err_color;
@@ -743,7 +746,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
         if (currBaseline === undefined) {
           lastY = axisY;
         } else {
-          if(stepPlot) {
+          if(prevStepPlot) {
             lastY = currBaseline[0];
           } else {
             lastY = currBaseline;
@@ -768,17 +771,18 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
       }
       if (!isNaN(prevX)) {
         ctx.moveTo(prevX, prevYs[0]);
-
+        
+        // Move to top fill point
         if (stepPlot) {
           ctx.lineTo(point.canvasx, prevYs[0]);
-          if(currBaseline) {
-            // Draw to the bottom of the baseline
-            ctx.lineTo(point.canvasx, currBaseline[1]);
-          } else {
-            ctx.lineTo(point.canvasx, newYs[1]);
-          }
         } else {
           ctx.lineTo(point.canvasx, newYs[0]);
+        }
+        // Move to bottom fill point
+        if (prevStepPlot && currBaseline) {
+          // Draw to the bottom of the baseline
+          ctx.lineTo(point.canvasx, currBaseline[1]);
+        } else {
           ctx.lineTo(point.canvasx, newYs[1]);
         }
 
@@ -788,6 +792,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
       prevYs = newYs;
       prevX = point.canvasx;
     }
+    prevStepPlot = stepPlot;
     ctx.fill();
   }
 };