Don't clear overlay on mouseup if not zooming.
[dygraphs.git] / dygraph-canvas.js
index a8b9807..825a4c2 100644 (file)
@@ -243,23 +243,20 @@ DygraphCanvasRenderer._predicateThatSkipsEmptyPoints =
 };
 
 /**
- *
  * @private
  */
 DygraphCanvasRenderer.prototype._drawStyledLine = function(
-    ctx, i, setName, color, strokeWidth, strokePattern, drawPoints,
+    ctx, setIdx, setName, color, strokeWidth, strokePattern, drawPoints,
     drawPointCallback, pointSize) {
   // TODO(konigsberg): Compute attributes outside this method call.
   var stepPlot = this.attr_("stepPlot");
-  var firstIndexInSet = this.layout.setPointsOffsets[i];
-  var setLength = this.layout.setPointsLengths[i];
-  var points = this.layout.points;
   if (!Dygraph.isArrayLike(strokePattern)) {
     strokePattern = null;
   }
   var drawGapPoints = this.dygraph_.attr_('drawGapEdgePoints', setName);
 
-  var iter = Dygraph.createIterator(points, firstIndexInSet, setLength,
+  var points = this.layout.points[setIdx];
+  var iter = Dygraph.createIterator(points, 0, points.length,
       DygraphCanvasRenderer._getIteratorPredicate(
           this.attr_("connectSeparatedPoints")));
 
@@ -306,6 +303,7 @@ DygraphCanvasRenderer.prototype._drawSeries = function(
   ctx.strokeStyle = color;
   ctx.lineWidth = strokeWidth;
 
+  // NOTE: we break the iterator's encapsulation here for about a 25% speedup.
   var arr = iter.array_;
   var limit = iter.end_;
   var predicate = iter.predicate_;
@@ -354,6 +352,8 @@ DygraphCanvasRenderer.prototype._drawSeries = function(
             ctx.lineTo(point.canvasx, prevCanvasY);
             prevCanvasX = point.canvasx;
           }
+
+          // TODO(danvk): this moveTo is rarely necessary
           ctx.moveTo(prevCanvasX, prevCanvasY);
           ctx.lineTo(point.canvasx, point.canvasy);
         }
@@ -419,11 +419,20 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
   // TODO(bhs): this loop is a hot-spot for high-point-count charts. These
   // transformations can be pushed into the canvas via linear transformation
   // matrices.
-  var points = this.layout.points;
-  for (i = points.length; i--;) {
-    var point = points[i];
-    point.canvasx = this.area.w * point.x + this.area.x;
-    point.canvasy = this.area.h * point.y + this.area.y;
+  // NOTE(danvk): this is trickier than it sounds at first. The transformation
+  // needs to be done before the .moveTo() and .lineTo() calls, but must be
+  // undone before the .stroke() call to ensure that the stroke width is
+  // unaffected.  An alternative is to reduce the stroke width in the
+  // transformed coordinate space, but you can't specify different values for
+  // each dimension (as you can with .scale()). The speedup here is ~12%.
+  var sets = this.layout.points;
+  for (i = sets.length; i--;) {
+    var points = sets[i];
+    for (var j = points.length; j--;) {
+      var point = points[j];
+      point.canvasx = this.area.w * point.x + this.area.x;
+      point.canvasy = this.area.h * point.y + this.area.y;
+    }
   }
 
   // Draw any "fills", i.e. error bars or the filled area under a series.
@@ -465,15 +474,13 @@ DygraphCanvasRenderer.prototype.drawErrorBars_ = function(points) {
 
   var newYs;
 
-  for (var i = 0; i < setCount; i++) {
-    var setName = setNames[i];
+  for (var setIdx = 0; setIdx < setCount; setIdx++) {
+    var setName = setNames[setIdx];
     var axis = this.dygraph_.axisPropertiesForSeries(setName);
     var color = this.colors[setName];
 
-    var firstIndexInSet = this.layout.setPointsOffsets[i];
-    var setLength = this.layout.setPointsLengths[i];
-
-    var iter = Dygraph.createIterator(points, firstIndexInSet, setLength,
+    var points = this.layout.points[setIdx];
+    var iter = Dygraph.createIterator(points, 0, points.length,
         DygraphCanvasRenderer._getIteratorPredicate(
             this.attr_("connectSeparatedPoints")));
 
@@ -495,7 +502,6 @@ DygraphCanvasRenderer.prototype.drawErrorBars_ = function(points) {
         continue;
       }
 
-      // TODO(danvk): here
       if (stepPlot) {
         newYs = [ point.y_bottom, point.y_top ];
         prevY = point.y;
@@ -544,18 +550,17 @@ DygraphCanvasRenderer.prototype.drawFillBars_ = function(points) {
   var currBaseline;
 
   // process sets in reverse order (needed for stacked graphs)
-  for (var i = setCount - 1; i >= 0; i--) {
-    var setName = setNames[i];
+  for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) {
+    var setName = setNames[setIdx];
     var color = this.colors[setName];
     var axis = this.dygraph_.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 = this.area.h * axisY + this.area.y;
-    var firstIndexInSet = this.layout.setPointsOffsets[i];
-    var setLength = this.layout.setPointsLengths[i];
 
-    var iter = Dygraph.createIterator(points, firstIndexInSet, setLength,
+    var points = this.layout.points[setIdx];
+    var iter = Dygraph.createIterator(points, 0, points.length,
         DygraphCanvasRenderer._getIteratorPredicate(
             this.attr_("connectSeparatedPoints")));