Add 'plotter' option, which allows custom drawing.
[dygraphs.git] / dygraph.js
index 41ad05c..bb74cdc 100644 (file)
@@ -180,6 +180,18 @@ Dygraph.dateAxisFormatter = function(date, granularity) {
   }
 };
 
+/**
+ * Standard plotters. These may be used by clients.
+ * Available plotters are:
+ * - Dygraph.Plotters.linePlotter: draws central lines (most common)
+ * - Dygraph.Plotters.errorPlotter: draws error bars
+ * - Dygraph.Plotters.fillPlotter: draws fills under lines (used with fillGraph)
+ *
+ * By default, the plotter is [fillPlotter, errorPlotter, linePlotter].
+ * This causes all the lines to be drawn over all the fills/error bars.
+ */
+Dygraph.Plotters = DygraphCanvasRenderer._Plotters;
+
 
 // Default attribute values.
 Dygraph.DEFAULT_ATTRS = {
@@ -261,6 +273,14 @@ Dygraph.DEFAULT_ATTRS = {
   rangeSelectorPlotStrokeColor: "#808FAB",
   rangeSelectorPlotFillColor: "#A7B1C4",
 
+  // The ordering here ensures that central lines always appear above any
+  // fill bars/error bars.
+  plotter: [
+    Dygraph.Plotters.fillPlotter,
+    Dygraph.Plotters.errorPlotter,
+    Dygraph.Plotters.linePlotter
+  ],
+
   // per-axis options
   axes: {
     x: {
@@ -409,6 +429,7 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
   this.datasetIndex_ = [];
 
   this.registeredEvents_ = [];
+  this.eventListeners_ = {};
 
   // Create the containing DIV and other interactive elements
   this.createInterface_();
@@ -436,7 +457,6 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
 
   // At this point, plugins can no longer register event handlers.
   // Construct a map from event -> ordered list of [callback, plugin].
-  this.eventListeners_ = {};
   for (var i = 0; i < this.plugins_.length; i++) {
     var plugin_dict = this.plugins_[i];
     for (var eventName in plugin_dict.events) {
@@ -931,7 +951,6 @@ Dygraph.prototype.createInterface_ = function() {
   if (this.attr_('showRangeSelector')) {
     // The range selector must be created here so that its canvases and contexts get created here.
     // For some reason, if the canvases and contexts don't get created here, things don't work in IE.
-    // The range selector also sets xAxisHeight in order to reserve space.
     this.rangeSelector_ = new DygraphRangeSelector(this);
   }
 
@@ -949,12 +968,12 @@ Dygraph.prototype.createInterface_ = function() {
   }
 
   var dygraph = this;
-  
+
   this.mouseMoveHandler = function(e) {
     dygraph.mouseMove_(e);
   };
   this.addEvent(this.mouseEventElement_, 'mousemove', this.mouseMoveHandler);
-  
+
   this.mouseOutHandler = function(e) {
     dygraph.mouseOut_(e);
   };
@@ -983,7 +1002,7 @@ Dygraph.prototype.destroy = function() {
       node.removeChild(node.firstChild);
     }
   };
+
   for (var idx = 0; idx < this.registeredEvents_.length; idx++) {
     var reg = this.registeredEvents_[idx];
     Dygraph.removeEvent(reg.elem, reg.type, reg.fn);
@@ -1853,8 +1872,10 @@ Dygraph.prototype.updateSelection_ = function(opt_animFraction) {
       ctx.fillStyle = 'rgba(255,255,255,' + alpha + ')';
       ctx.fillRect(0, 0, this.width_, this.height_);
     }
-    var setIdx = this.datasetIndexFromSetName_(this.highlightSet_);
-    this.plotter_._drawLine(ctx, setIdx);
+
+    // Redraw only the highlighted series in the interactive canvas (not the
+    // static plot canvas, which is where series are usually drawn).
+    this.plotter_._renderLineChart(this.highlightSet_, ctx);
   } else if (this.previousVerticalX_ >= 0) {
     // Determine the maximum highlight circle size.
     var maxCircleSize = 0;
@@ -2650,7 +2671,7 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
  * This is where undesirable points (i.e. negative values on log scales and
  * missing values through which we wish to connect lines) are dropped.
  * TODO(danvk): the "missing values" bit above doesn't seem right.
- * 
+ *
  * @private
  */
 Dygraph.prototype.extractSeries_ = function(rawData, i, logScale) {