nulls in array data
[dygraphs.git] / dygraph.js
index 94b536d..30ea8f6 100644 (file)
@@ -155,6 +155,10 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
   this.wilsonInterval_ = attrs.wilsonInterval || true;
   this.customBars_ = attrs.customBars || false;
 
+  // Clear the div. This ensure that, if multiple dygraphs are passed the same
+  // div, then only one will be drawn.
+  div.innerHTML = "";
+
   // If the div isn't already sized then give it a default size.
   if (div.style.width == '') {
     div.style.width = Dygraph.DEFAULT_WIDTH + "px";
@@ -607,6 +611,8 @@ Dygraph.prototype.mouseMove_ = function(event) {
     ctx.clearRect(px - circleSize - 1, 0, 2 * circleSize + 2, this.height_);
   }
 
+  var isOK = function(x) { return x && !isNaN(x); };
+
   if (selPoints.length > 0) {
     var canvasx = selPoints[0].canvasx;
 
@@ -614,6 +620,7 @@ Dygraph.prototype.mouseMove_ = function(event) {
     var replace = this.attr_('xValueFormatter')(lastx, this) + ":";
     var clen = this.colors_.length;
     for (var i = 0; i < selPoints.length; i++) {
+      if (!isOK(selPoints[i].canvasy)) continue;
       if (this.attr_("labelsSeparateLines")) {
         replace += "<br/>";
       }
@@ -630,6 +637,7 @@ Dygraph.prototype.mouseMove_ = function(event) {
     // Draw colored circles over the center of each selected point
     ctx.save()
     for (var i = 0; i < selPoints.length; i++) {
+      if (!isOK(selPoints[i%clen].canvasy)) continue;
       ctx.beginPath();
       ctx.fillStyle = this.colors_[i%clen].toRGBString();
       ctx.arc(canvasx, selPoints[i%clen].canvasy, circleSize, 0, 360, false);
@@ -963,7 +971,7 @@ Dygraph.prototype.addYTicks_ = function(minY, maxY) {
  * @private
  */
 Dygraph.prototype.drawGraph_ = function(data) {
-  var maxY = null;
+  var minY = null, maxY = null;
   this.layout_.removeAllDatasets();
   this.setColors_();
 
@@ -986,7 +994,9 @@ Dygraph.prototype.drawGraph_ = function(data) {
         if (series[k][0] >= low && series[k][0] <= high) {
           pruned.push(series[k]);
           var y = bars ? series[k][1][0] : series[k][1];
+          if (!y) continue;
           if (maxY == null || y > maxY) maxY = y;
+          if (minY == null || y < minY) minY = y;
         }
       }
       series = pruned;
@@ -994,9 +1004,13 @@ Dygraph.prototype.drawGraph_ = function(data) {
       if (!this.customBars_) {
         for (var j = 0; j < series.length; j++) {
           var y = bars ? series[j][1][0] : series[j][1];
+          if (!y) continue;
           if (maxY == null || y > maxY) {
             maxY = bars ? y + series[j][1][1] : y;
           }
+          if (minY == null || y < minY) {
+            minY = bars ? y + series[j][1][1] : y;
+          }
         }
       } else {
         // With custom bars, maxY is the max of the high values.
@@ -1007,6 +1021,9 @@ Dygraph.prototype.drawGraph_ = function(data) {
           if (maxY == null || y > maxY) {
             maxY = y;
           }
+          if (minY == null || y < minY) {
+            minY = y;
+          }
         }
       }
     }
@@ -1028,9 +1045,20 @@ Dygraph.prototype.drawGraph_ = function(data) {
     this.addYTicks_(this.valueRange_[0], this.valueRange_[1]);
   } else {
     // Add some padding and round up to an integer to be human-friendly.
-    maxY *= 1.1;
-    if (maxY <= 0.0) maxY = 1.0;
-    this.addYTicks_(0, maxY);
+    var span = maxY - minY;
+    var maxAxisY = maxY + 0.1 * span;
+    var minAxisY = minY - 0.1 * span;
+
+    // Try to include zero and make it minAxisY (or maxAxisY) if it makes sense.
+    if (minAxisY < 0 && minY >= 0) minAxisY = 0;
+    if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;
+
+    if (this.attr_("includeZero")) {
+      if (maxY < 0) maxAxisY = 0;
+      if (minY > 0) minAxisY = 0;
+    }
+
+    this.addYTicks_(minAxisY, maxAxisY);
   }
 
   this.addXTicks_();
@@ -1124,6 +1152,10 @@ Dygraph.prototype.rollingAverage = function(originalData, rollPeriod) {
                                               1.0 * (high - mid) / count ]];
     }
   } else {
+    if (rollPeriod == 1) {
+      return originalData;
+    }
+
     // Calculate the rolling average for the first rollPeriod - 1 points where
     // there is not enough data to roll over the full number of days
     var num_init_points = Math.min(rollPeriod - 1, originalData.length - 2);
@@ -1410,15 +1442,18 @@ Dygraph.prototype.parseDataTable_ = function(data) {
   var ret = [];
   for (var i = 0; i < rows; i++) {
     var row = [];
+    if (!data.getValue(i, 0)) continue;
     if (indepType == 'date') {
       row.push(data.getValue(i, 0).getTime());
     } else {
       row.push(data.getValue(i, 0));
     }
+    var any_data = false;
     for (var j = 1; j < cols; j++) {
       row.push(data.getValue(i, j));
+      if (data.getValue(i, j)) any_data = true;
     }
-    ret.push(row);
+    if (any_data) ret.push(row);
   }
   return ret;
 }