Add dygraph-options.js. Add code to compare behavior. Looks like it's only working...
[dygraphs.git] / dygraph.js
index 64ca4b6..4189750 100644 (file)
@@ -408,6 +408,12 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
     // TODO(nikhilk): Add any other stackedGraph checks here.
   }
 
+  // These two options have a bad interaction. See issue 359.
+  if (attrs.showRangeSelector && attrs.animatedZooms) {
+    this.warn('You should not set animatedZooms=true when using the range selector.');
+    attrs.animatedZooms = false;
+  }
+
   // Dygraphs has many options, some of which interact with one another.
   // To keep track of everything, we maintain two sets of options:
   //
@@ -431,6 +437,8 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
   this.registeredEvents_ = [];
   this.eventListeners_ = {};
 
+  this.attributes_ = new DygraphOptions(this);
+
   // Create the containing DIV and other interactive elements
   this.createInterface_();
 
@@ -562,6 +570,12 @@ Dygraph.prototype.attr_ = function(name, seriesName) {
   }
 // </REMOVE_FOR_COMBINED>
 
+  // Building an array which we peruse in backwards order to find the correct value.
+  // Options are checked in this order:
+  // series, axis, user attrs, global attrs.
+  // TODO(konigsberg): Can this be made faster by starting with the series and working outward,
+  // rather than building an array?
+
   var sources = [];
   sources.push(this.attrs_);
   if (this.user_attrs_) {
@@ -570,6 +584,8 @@ Dygraph.prototype.attr_ = function(name, seriesName) {
       if (this.user_attrs_.hasOwnProperty(seriesName)) {
         sources.push(this.user_attrs_[seriesName]);
       }
+
+      // TODO(konigsberg): This special case ought to be documented.
       if (seriesName === this.highlightSet_ &&
           this.user_attrs_.hasOwnProperty('highlightSeriesOpts')) {
         sources.push(this.user_attrs_.highlightSeriesOpts);
@@ -585,7 +601,15 @@ Dygraph.prototype.attr_ = function(name, seriesName) {
       break;
     }
   }
-  return ret;
+
+  var computedValue = seriesName ? this.attributes_.findForSeries(name, seriesName) : this.attributes_.find(name);
+
+  if (ret !== computedValue) {
+    console.log("Mismatch", name, seriesName, ret, computedValue);
+  } else {
+    console.log("Match", name, seriesName, ret, computedValue);
+  }
+  return computedValue;
 };
 
 /**
@@ -1247,6 +1271,10 @@ Dygraph.prototype.createDragInterface_ = function() {
     boundedDates: null, // [minDate, maxDate]
     boundedValues: null, // [[minValue, maxValue] ...]
 
+    // We cover iframes during mouse interactions. See comments in
+    // dygraph-utils.js for more info on why this is a good idea.
+    tarp: new Dygraph.IFrameTarp(),
+
     // contextB is the same thing as this context object but renamed.
     initializeMouseDown: function(event, g, contextB) {
       // prevents mouse drags from selecting page text.
@@ -1262,6 +1290,7 @@ Dygraph.prototype.createDragInterface_ = function() {
       contextB.dragStartX = g.dragGetX_(event, contextB);
       contextB.dragStartY = g.dragGetY_(event, contextB);
       contextB.cancelNextDblclick = false;
+      contextB.tarp.cover();
     }
   };
 
@@ -1301,9 +1330,11 @@ Dygraph.prototype.createDragInterface_ = function() {
         delete self.axes_[i].dragValueRange;
       }
     }
+
+    context.tarp.uncover();
   };
 
-  this.addEvent(window, 'mouseup', this.mouseUpHandler_);
+  this.addEvent(document, 'mouseup', this.mouseUpHandler_);
 };
 
 /**
@@ -1523,7 +1554,8 @@ Dygraph.prototype.doUnzoom_ = function() {
       newValueRanges = [];
       for (i = 0; i < this.axes_.length; i++) {
         var axis = this.axes_[i];
-        newValueRanges.push(axis.valueRange !== null ?
+        newValueRanges.push((axis.valueRange !== null &&
+                             axis.valueRange !== undefined) ?
                             axis.valueRange : axis.extremeRange);
       }
     }
@@ -2099,7 +2131,7 @@ Dygraph.prototype.extremeValues_ = function(series) {
     // With custom bars, maxY is the max of the high values.
     for (j = 0; j < series.length; j++) {
       y = series[j][1][0];
-      if (!y) continue;
+      if (y === null || isNaN(y)) continue;
       var low = y - series[j][1][1];
       var high = y + series[j][1][2];
       if (low > y) low = y;    // this can happen with custom bars,
@@ -2165,7 +2197,8 @@ Dygraph.prototype.predraw_ = function() {
   // rolling averages.
   this.rolledSeries_ = [null];  // x-axis is the first series and it's special
   for (var i = 1; i < this.numColumns(); i++) {
-    var logScale = this.attr_('logscale', i); // TODO(klausw): this looks wrong
+    // var logScale = this.attr_('logscale', i); // TODO(klausw): this looks wrong // konigsberg thinks so too.
+    var logScale = this.attr_('logscale');
     var series = this.extractSeries_(this.rawData_, i, logScale);
     series = this.rollingAverage(series, this.rollPeriod_);
     this.rolledSeries_.push(series);
@@ -2923,7 +2956,8 @@ Dygraph.prototype.parseFloat_ = function(x, opt_line_no, opt_line) {
  */
 Dygraph.prototype.parseCSV_ = function(data) {
   var ret = [];
-  var lines = data.split("\n");
+  var line_delimiter = Dygraph.detectLineDelimiter(data);
+  var lines = data.split(line_delimiter || "\n");
   var vals, j;
 
   // Use the default delimiter or fall back to a tab if that makes sense.
@@ -3279,7 +3313,8 @@ Dygraph.prototype.start_ = function() {
     this.predraw_();
   } else if (typeof data == 'string') {
     // Heuristic: a newline means it's CSV data. Otherwise it's an URL.
-    if (data.indexOf('\n') >= 0) {
+    var line_delimiter = Dygraph.detectLineDelimiter(data);
+    if (line_delimiter) {
       this.loadedEvent_(data);
     } else {
       var req = new XMLHttpRequest();