Add a fast-path setSelection() if the points are in the expected place.
authorAdam Vartanian <flooey@gmail.com>
Tue, 14 Oct 2014 20:24:42 +0000 (16:24 -0400)
committerDan Vanderkam <danvdk@gmail.com>
Wed, 22 Oct 2014 02:31:06 +0000 (22:31 -0400)
In most cases, the appropriate index will contain the point that should
be selected, so check that and use that point if so.  Otherwise, search
for a matching point.

Also add a test that tests the case where the appropriate index doesn't
contain the point we're looking for.

auto_tests/tests/selection.js
dygraph.js

index 2e68c1f..ff220f6 100644 (file)
@@ -48,3 +48,43 @@ SelectionTestCase.prototype.testSetGetSelectionDense = function() {
   g.setSelection(3);
   assertEquals(3, g.getSelection());
 };
+
+SelectionTestCase.prototype.testSetGetSelectionMissingPoints = function() {
+  dataHandler = function() {};
+  dataHandler.prototype = new Dygraph.DataHandlers.DefaultHandler();
+  dataHandler.prototype.seriesToPoints = function(series, setName, boundaryIdStart) {
+    var val = null;
+    if (setName == 'A') {
+      val = 1;
+    } else if (setName == 'B') {
+      val = 2;
+    } else if (setName == 'C') {
+      val = 3;
+    }
+    return [{
+      x: NaN,
+      y: NaN,
+      xval: val,
+      yval: val,
+      name: setName,
+      idx: val - 1
+    }];
+  };
+  var graph = document.getElementById("graph");
+  var g = new Dygraph(graph,
+    "X,A,B,C\n" +
+    "1,1,null,null\n" +
+    "2,null,2,null\n" +
+    "3,null,null,3\n",
+    {
+      dataHandler: dataHandler
+    }
+  );
+
+  g.setSelection(0);
+  assertEquals(0, g.getSelection());
+  g.setSelection(1);
+  assertEquals(1, g.getSelection());
+  g.setSelection(2);
+  assertEquals(2, g.getSelection());
+};
index 2fc527d..06d899a 100644 (file)
@@ -2156,13 +2156,22 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName, opt_locked) {
     this.lastRow_ = row;
     for (var setIdx = 0; setIdx < this.layout_.points.length; ++setIdx) {
       var points = this.layout_.points[setIdx];
-      for (var pointIdx = 0; pointIdx < points.length; ++pointIdx) {
-       var point = points[pointIdx];
-        if (point.idx == row) {
-          if (point.yval !== null) {
-            this.selPoints_.push(point);
+      // Check if the point at the appropriate index is the point we're looking
+      // for.  If it is, just use it, otherwise search the array for a point
+      // in the proper place.
+      var setRow = row - this.getLeftBoundary_(setIdx);
+      if (setRow < points.length && points[setRow].idx == row) {
+        var point = points[setRow];
+        if (point.yval !== null) this.selPoints_.push(point);
+      } else {
+        for (var pointIdx = 0; pointIdx < points.length; ++pointIdx) {
+          var point = points[pointIdx];
+          if (point.idx == row) {
+            if (point.yval !== null) {
+              this.selPoints_.push(point);
+            }
+            break;
           }
-          break;
         }
       }
     }