Fix bug 428, add test which catches exception. What an annoying little bug.
[dygraphs.git] / dygraph.js
index 43d3011..8e06ba2 100644 (file)
@@ -930,6 +930,8 @@ Dygraph.prototype.createInterface_ = function() {
   this.graphDiv = document.createElement("div");
   this.graphDiv.style.width = this.width_ + "px";
   this.graphDiv.style.height = this.height_ + "px";
+  // TODO(danvk): any other styles that are useful to set here?
+  this.graphDiv.style.textAlign = 'left';  // This is a CSS "reset"
   enclosing.appendChild(this.graphDiv);
 
   // Create the canvas for interactive parts of the chart.
@@ -956,19 +958,20 @@ Dygraph.prototype.createInterface_ = function() {
 
   var dygraph = this;
 
-  // Don't recreate and register the handlers on subsequent calls.
-  // This happens when the graph is resized.
-  if (!this.mouseMoveHandler_) {
-    this.mouseMoveHandler_ = function(e) {
-      dygraph.mouseMove_(e);
-    };
-    this.addEvent(this.mouseEventElement_, 'mousemove', this.mouseMoveHandler_);
+  this.mouseMoveHandler_ = function(e) {
+    dygraph.mouseMove_(e);
+  };
 
-    this.mouseOutHandler_ = function(e) {
-      dygraph.mouseOut_(e);
-    };
-    this.addEvent(this.mouseEventElement_, 'mouseout', this.mouseOutHandler_);
+  this.mouseOutHandler_ = function(e) {
+    dygraph.mouseOut_(e);
+  };
+
+  this.addEvent(this.mouseEventElement_, 'mousemove', this.mouseMoveHandler_);
+  this.addEvent(this.mouseEventElement_, 'mouseout', this.mouseOutHandler_);
 
+  // Don't recreate and register the resize handler on subsequent calls.
+  // This happens when the graph is resized.
+  if (!this.resizeHandler_) {
     this.resizeHandler_ = function(e) {
       dygraph.resize();
     };
@@ -992,10 +995,13 @@ Dygraph.prototype.destroy = function() {
     }
   };
 
-  for (var idx = 0; idx < this.registeredEvents_.length; idx++) {
-    var reg = this.registeredEvents_[idx];
-    Dygraph.removeEvent(reg.elem, reg.type, reg.fn);
+  if (this.registeredEvents_) {
+    for (var idx = 0; idx < this.registeredEvents_.length; idx++) {
+      var reg = this.registeredEvents_[idx];
+      Dygraph.removeEvent(reg.elem, reg.type, reg.fn);
+    }
   }
+
   this.registeredEvents_ = [];
 
   // remove mouse event handlers (This may not be necessary anymore)
@@ -1277,6 +1283,12 @@ Dygraph.prototype.createDragInterface_ = function() {
         bindHandler(interactionModel[eventName]));
   }
 
+  // unregister the handler on subsequent calls.
+  // This happens when the graph is resized.
+  if (this.mouseUpHandler_) {
+    Dygraph.removeEvent(document, 'mouseup', this.mouseUpHandler_);
+  }
+
   // If the user releases the mouse button during a drag, but not over the
   // canvas, then it doesn't count as a zooming action.
   this.mouseUpHandler_ = function(event) {
@@ -2493,6 +2505,10 @@ Dygraph.prototype.axisPropertiesForSeries = function(series) {
  * This fills in the valueRange and ticks fields in each entry of this.axes_.
  */
 Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
+  
+  var isNullUndefinedOrNaN = function(num) {
+    return isNaN(parseFloat(num));
+  };
   var series;
   var numAxes = this.attributes_.numAxes();
 
@@ -2565,7 +2581,10 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
       axis.computedValueRange = [axis.valueWindow[0], axis.valueWindow[1]];
     } else if (axis.valueRange) {
       // This is a user-set value range for this axis.
-      axis.computedValueRange = [axis.valueRange[0], axis.valueRange[1]];
+      axis.computedValueRange = [
+         isNullUndefinedOrNaN(axis.valueRange[0]) ? axis.extremeRange[0] : axis.valueRange[0],
+         isNullUndefinedOrNaN(axis.valueRange[1]) ? axis.extremeRange[1] : axis.valueRange[1]
+      ];
     } else {
       axis.computedValueRange = axis.extremeRange;
     }
@@ -3481,9 +3500,12 @@ Dygraph.prototype.annotations = function() {
 /**
  * Get the list of label names for this graph. The first column is the
  * x-axis, so the data series names start at index 1.
+ *
+ * Returns null when labels have not yet been defined.
  */
 Dygraph.prototype.getLabels = function() {
-  return this.attr_("labels").slice();
+  var labels = this.attr_("labels");
+  return labels ? labels.slice() : null;
 };
 
 /**