Merge pull request #159 from klausw-g/lock-selection
authorDan Vanderkam <danvdk@gmail.com>
Tue, 31 Jul 2012 14:35:56 +0000 (07:35 -0700)
committerDan Vanderkam <danvdk@gmail.com>
Tue, 31 Jul 2012 14:35:56 +0000 (07:35 -0700)
Add optional "locked" arg to setSelection;  Don't clear overlay on mouseup if not zooming.

auto_tests/tests/callback.js
dygraph-interaction-model.js
dygraph.js
gallery/highlighted-series.js

index 6d3df1d..6e59787 100644 (file)
@@ -302,6 +302,27 @@ CallbackTestCase.prototype.testClosestPointCallbackCss2 = function() {
 }
 
 /**
+ * Closest-point highlighting with locked series.
+ */
+CallbackTestCase.prototype.testClosestPointCallbackCss1 = function() {
+  var g = runClosestTest(false, 2, 4);
+
+  // Default behavior, 'b' is closest
+  DygraphOps.dispatchMouseMove(g, 11, 4);
+  assertEquals('b', g.getHighlightSeries());
+
+  // Now lock selection to 'c'
+  g.setSelection(false, 'c', true);
+  DygraphOps.dispatchMouseMove(g, 11, 4);
+  assertEquals('c', g.getHighlightSeries());
+
+  // Unlock, should be back to 'b'
+  g.clearSelection();
+  DygraphOps.dispatchMouseMove(g, 11, 4);
+  assertEquals('b', g.getHighlightSeries());
+}
+
+/**
  * This tests that closest point searches work for data containing NaNs.
  *
  * It's intended to catch a regression where a NaN Y value confuses the
index 9b7feb5..6f860c3 100644 (file)
@@ -220,6 +220,7 @@ Dygraph.Interaction.endPan = function(event, g, context) {
  */
 Dygraph.Interaction.startZoom = function(event, g, context) {
   context.isZooming = true;
+  context.zoomMoved = false;
 };
 
 /**
@@ -236,6 +237,7 @@ Dygraph.Interaction.startZoom = function(event, g, context) {
  * dragStartX/dragStartY/etc. properties). This function modifies the context.
  */
 Dygraph.Interaction.moveZoom = function(event, g, context) {
+  context.zoomMoved = true;
   context.dragEndX = g.dragGetX_(event, context);
   context.dragEndY = g.dragGetY_(event, context);
 
@@ -335,7 +337,7 @@ Dygraph.Interaction.endZoom = function(event, g, context) {
                Math.max(context.dragStartY, context.dragEndY));
     context.cancelNextDblclick = true;
   } else {
-    g.clearZoomRect_();
+    if (zoomMoved) g.clearZoomRect_();
   }
   context.dragStartX = null;
   context.dragStartY = null;
index 2fd2c05..41ad05c 100644 (file)
@@ -1735,7 +1735,7 @@ Dygraph.prototype.mouseMove_ = function(event) {
 
   var highlightSeriesOpts = this.attr_("highlightSeriesOpts");
   var selectionChanged = false;
-  if (highlightSeriesOpts) {
+  if (highlightSeriesOpts && !this.lockedSet_) {
     var closest;
     if (this.attr_("stackedGraph")) {
       closest = this.findStackedPoint(canvasx, canvasy);
@@ -1906,8 +1906,11 @@ Dygraph.prototype.updateSelection_ = function(opt_animFraction) {
  * hover dots on the chart). Set to false to clear any selection.
  * @param { seriesName } optional series name to highlight that series with the
  * the highlightSeriesOpts setting.
+ * @param { locked } optional If true, keep seriesName selected when mousing
+ * over the graph, disabling closest-series highlighting. Call clearSelection()
+ * to unlock it.
  */
-Dygraph.prototype.setSelection = function(row, opt_seriesName) {
+Dygraph.prototype.setSelection = function(row, opt_seriesName, opt_locked) {
   // Extract the points we've selected
   this.selPoints_ = [];
 
@@ -1947,6 +1950,10 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName) {
     this.highlightSet_ = opt_seriesName;
   }
 
+  if (opt_locked !== undefined) {
+    this.lockedSet_ = opt_locked;
+  }
+
   if (changed) {
     this.updateSelection_(undefined);
   }
@@ -1963,7 +1970,7 @@ Dygraph.prototype.mouseOut_ = function(event) {
     this.attr_("unhighlightCallback")(event);
   }
 
-  if (this.attr_("hideOverlayOnMouseOut")) {
+  if (this.attr_("hideOverlayOnMouseOut") && !this.lockedSet_) {
     this.clearSelection();
   }
 };
@@ -1975,6 +1982,7 @@ Dygraph.prototype.mouseOut_ = function(event) {
 Dygraph.prototype.clearSelection = function() {
   this.cascadeEvents_('deselect', {});
 
+  this.lockedSet_ = false;
   // Get rid of the overlay data
   if (this.fadeLevel) {
     this.animateSelection_(-1);
index 8cbe3c8..27a6458 100644 (file)
@@ -27,6 +27,19 @@ var getData = function(numSeries, numRows, isStacked) {
   return data;
 };
 
+var makeClickCallback = function(graph) {
+  var isLocked = false;
+  return function(ev) {
+    if (isLocked) {
+      graph.clearSelection();
+      isLocked = false;
+    } else {
+      graph.setSelection(graph.getSelection(), graph.getHighlightSeries(), true);
+      isLocked = true;
+    }
+  };
+};
+
 var makeGraph = function(className, numSeries, numRows, isStacked) {
   var demo = document.getElementById('demo');
   var div = document.createElement('div');
@@ -60,6 +73,7 @@ var makeGraph = function(className, numSeries, numRows, isStacked) {
           highlightCircleSize: 5,
         },
       });
+  g.updateOptions({clickCallback: makeClickCallback(g)}, true);
   g.setSelection(false, 's005');
   //console.log(g);
 };