From antrob: Single point per pixel, do the optimization in the actual rendering...
authorDan Vanderkam <danvk@google.com>
Wed, 3 Aug 2011 18:19:00 +0000 (21:19 +0300)
committerDan Vanderkam <danvk@google.com>
Wed, 3 Aug 2011 18:19:00 +0000 (21:19 +0300)
This is not as fast as skipping the points altogether, but it still
provides an excellent speed up for large data sets and will not cause
issues with other functions that expect the points to be there.

This is safe with setSelection, annotations, etc.

dygraph-canvas.js
dygraph-layout.js

index 4a5ca44..f08210d 100644 (file)
@@ -592,6 +592,10 @@ DygraphCanvasRenderer.prototype._renderAnnotations = function() {
  * Overrides the CanvasRenderer method to draw error bars
  */
 DygraphCanvasRenderer.prototype._renderLineChart = function() {
+  var isNullOrNaN = function(x) {
+    return (x === null || isNaN(x));
+  };
+  
   // TODO(danvk): use this.attr_ for many of these.
   var context = this.elementContext;
   var fillAlpha = this.attr_('fillAlpha');
@@ -747,11 +751,7 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
     }
   }
 
-  var isNullOrNaN = function(x) {
-    return (x === null || isNaN(x));
-  };
-
-  // Drawing of a graph without error bars.
+  // Drawing the lines.
   var firstIndexInSet = 0;
   var afterLastIndexInSet = 0;
   var setLength = 0;
@@ -790,6 +790,11 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
           prevX = point.canvasx;
           prevY = point.canvasy;
         } else {
+          // Skip over points that will be drawn in the same pixel.
+          if (Math.round(prevX) == Math.round(point.canvasx) &&
+              Math.round(prevY) == Math.round(point.canvasy)) {
+            continue;
+          }
           // TODO(antrob): skip over points that lie on a line that is already
           // going to be drawn. There is no need to have more than 2
           // consecutive points that are collinear.
index c870d3b..28f1f28 100644 (file)
@@ -141,21 +141,8 @@ DygraphLayout.prototype._evaluateLineCharts = function() {
     var dataset = this.datasets[setName];
     var axis = this.dygraph_.axisPropertiesForSeries(setName);
 
-    var graphWidth = this.dygraph_.width_;
-    var graphHeight = this.dygraph_.height_;
-    var prevXPx = NaN;
-    var prevYPx = NaN;
-    var currXPx = NaN;
-    var currYPx = NaN;
     var setPointsLength = 0;
 
-    // Ignore the pixel skipping optimization if there are error bars.
-    // XXX 2011-07-25 temporarily disabled (see autotests/tests/selection.js)
-    var skip_opt = (true ||
-                    this.attr_("errorBars") ||
-                    this.attr_("customBars") ||
-                    this.annotations.length > 0);
-
     for (var j = 0; j < dataset.length; j++) {
       var item = dataset[j];
       var xValue = parseFloat(dataset[j][0]);
@@ -170,27 +157,16 @@ DygraphLayout.prototype._evaluateLineCharts = function() {
       } else {
         yNormal = 1.0 - ((yValue - axis.minyval) * axis.yscale);
       }
-
-      // Current pixel coordinates that the data point would fill.
-      currXPx = Math.round(xNormal * graphWidth);
-      currYPx = Math.round(yNormal * graphHeight);
-
-      // Skip over pushing points that lie on the same pixel.
-      // TODO(antrob): optimize this for graphs with error bars.
-      if (skip_opt || prevXPx != currXPx || prevYPx != currYPx) {
-        var point = {
-          // TODO(danvk): here
-          x: xNormal,
-          y: yNormal,
-          xval: xValue,
-          yval: yValue,
-          name: setName
-        };
-        this.points.push(point);
-        setPointsLength += 1;
-      }
-      prevXPx = currXPx;
-      prevYPx = currYPx;
+      var point = {
+        // TODO(danvk): here
+        x: xNormal,
+        y: yNormal,
+        xval: xValue,
+        yval: yValue,
+        name: setName
+      };
+      this.points.push(point);
+      setPointsLength += 1;
     }
     this.setPointsLengths.push(setPointsLength);
   }