Add optional "locked" arg to setSelection
authorKlaus Weidner <klausw@google.com>
Fri, 27 Jul 2012 23:02:07 +0000 (16:02 -0700)
committerKlaus Weidner <klausw@google.com>
Fri, 27 Jul 2012 23:36:30 +0000 (16:36 -0700)
Locking a series selection temporarily disables the closest-series
logic of the highlighting code, switching it to traditional by-row
selection until unlocked by clearSelection().

This is useful for following values of a single series on mouseover,
see the example use in the "Highlight Closest Series" demo which
toggles this by clicking the graph.

auto_tests/tests/callback.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 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);
 };