Support for Google Visualization API compatible setSelection method
[dygraphs.git] / dygraph.js
index 6bacea2..3f8f90e 100644 (file)
@@ -309,6 +309,7 @@ Dygraph.prototype.toDomCoords = function(x, y) {
   return ret;
 };
 
+// TODO(danvk): use these functions throughout dygraphs.
 /**
  * Convert from canvas/div coords to data coordinates.
  * Returns a two-element array: [X, Y]
@@ -850,19 +851,10 @@ Dygraph.prototype.drawZoomRect_ = function(startX, endX, prevEndX) {
  */
 Dygraph.prototype.doZoom_ = function(lowX, highX) {
   // Find the earliest and latest dates contained in this canvasx range.
-  var points = this.layout_.points;
-  var minDate = null;
-  var maxDate = null;
-  // Find the nearest [minDate, maxDate] that contains [lowX, highX]
-  for (var i = 0; i < points.length; i++) {
-    var cx = points[i].canvasx;
-    var x = points[i].xval;
-    if (cx < lowX  && (minDate == null || x > minDate)) minDate = x;
-    if (cx > highX && (maxDate == null || x < maxDate)) maxDate = x;
-  }
-  // Use the extremes if either is missing
-  if (minDate == null) minDate = points[0].xval;
-  if (maxDate == null) maxDate = points[points.length-1].xval;
+  var r = this.toDataCoords(lowX, null);
+  var minDate = r[0];
+  r = this.toDataCoords(highX, null);
+  var maxDate = r[0];
 
   this.dateWindow_ = [minDate, maxDate];
   this.drawGraph_(this.rawData_);
@@ -929,6 +921,18 @@ Dygraph.prototype.mouseMove_ = function(event) {
     }
   }
 
+  // Save last x position for callbacks.
+  this.lastx_ = lastx;
+  
+  this.updateSelection_();
+};
+
+/**
+ * Draw dots over the selectied points in the data series. This function
+ * takes care of cleanup of previously-drawn dots.
+ * @private
+ */
+Dygraph.prototype.updateSelection_ = function() {
   // Clear the previously drawn vertical, if there is one
   var circleSize = this.attr_('highlightCircleSize');
   var ctx = this.canvas_.getContext("2d");
@@ -943,7 +947,7 @@ Dygraph.prototype.mouseMove_ = function(event) {
     var canvasx = this.selPoints_[0].canvasx;
 
     // Set the status message to indicate the selected point(s)
-    var replace = this.attr_('xValueFormatter')(lastx, this) + ":";
+    var replace = this.attr_('xValueFormatter')(this.lastx_, this) + ":";
     var clen = this.colors_.length;
     for (var i = 0; i < this.selPoints_.length; i++) {
       if (!isOK(this.selPoints_[i].canvasy)) continue;
@@ -958,9 +962,6 @@ Dygraph.prototype.mouseMove_ = function(event) {
     }
     this.attr_("labelsDiv").innerHTML = replace;
 
-    // Save last x position for callbacks.
-    this.lastx_ = lastx;
-
     // Draw colored circles over the center of each selected point
     ctx.save();
     for (var i = 0; i < this.selPoints_.length; i++) {
@@ -978,19 +979,55 @@ Dygraph.prototype.mouseMove_ = function(event) {
 };
 
 /**
+ * Set manually set selected dots, and display information about them
+ * @param int row number that should by highlighted
+ *            false value clears the selection
+ * @public
+ */
+Dygraph.prototype.setSelection = function(row) {
+  // Extract the points we've selected
+  this.selPoints_ = [];
+  var pos = 0;
+  
+  if (row !== false) {
+    for (var i in this.layout_.datasets) {
+      this.selPoints_.push(this.layout_.points[pos+row]);
+      pos += this.layout_.datasets[i].length;
+    }
+    
+    this.lastx_ = this.selPoints_[0].xval;
+    this.updateSelection_();
+  } else {
+    this.lastx_ = -1;
+    this.clearSelection();
+  }
+
+};
+
+/**
  * The mouse has left the canvas. Clear out whatever artifacts remain
  * @param {Object} event the mouseout event from the browser.
  * @private
  */
 Dygraph.prototype.mouseOut_ = function(event) {
   if (this.attr_("hideOverlayOnMouseOut")) {
-    // Get rid of the overlay data
-    var ctx = this.canvas_.getContext("2d");
-    ctx.clearRect(0, 0, this.width_, this.height_);
-    this.attr_("labelsDiv").innerHTML = "";
+    this.clearSelection();
   }
 };
 
+/**
+ * Remove all selection from the canvas
+ * @public
+ */
+Dygraph.prototype.clearSelection = function() {
+  // Get rid of the overlay data
+  var ctx = this.canvas_.getContext("2d");
+  ctx.clearRect(0, 0, this.width_, this.height_);
+  this.attr_("labelsDiv").innerHTML = "";
+  this.selPoints_ = [];
+  this.lastx_ = -1;
+}
+
 Dygraph.zeropad = function(x) {
   if (x < 10) return "0" + x; else return "" + x;
 }
@@ -2187,5 +2224,20 @@ Dygraph.GVizChart.prototype.draw = function(data, options) {
   this.date_graph = new Dygraph(this.container, data, options);
 }
 
+/**
+ * Google charts compatible setSelection
+ * Only row selection is supported, all points in the 
+ * row will be highlighted
+ * @param {Array} array of the selected cells
+ * @public
+ */
+Dygraph.GVizChart.prototype.setSelection = function(selection_array) {
+  var row = false;
+  if (selection_array.length) {
+    row = selection_array[0].row;
+  }
+  this.date_graph.setSelection(row);
+}
+
 // Older pages may still use this name.
 DateGraph = Dygraph;