switch to YUI compressor for making packed JS -- 49k -> 42k
[dygraphs.git] / dygraph.js
index 7cf21ba..8858396 100644 (file)
@@ -526,6 +526,7 @@ Dygraph.prototype.createDragInterface_ = function() {
 
   // Tracks whether the mouse is down right now
   var isZooming = false;
+  var isPanning = false;
   var dragStartX = null;
   var dragStartY = null;
   var dragEndX = null;
@@ -569,10 +570,12 @@ Dygraph.prototype.createDragInterface_ = function() {
     dragStartX = getX(event);
     dragStartY = getY(event);
 
-    if (event.altKey && self.dateWindow_) {
+    if (event.altKey || event.shiftKey) {
+      if (!self.dateWindow_) return;  // have to be zoomed in to pan.
       isPanning = true;
       dateRange = self.dateWindow_[1] - self.dateWindow_[0];
-      draggingDate = (dragStartX / self.width_) * dateRange + self.dateWindow_[0];
+      draggingDate = (dragStartX / self.width_) * dateRange +
+        self.dateWindow_[0];
     } else {
       isZooming = true;
     }
@@ -973,7 +976,7 @@ Dygraph.prototype.GetXAxis = function(start_time, end_time, granularity) {
   if (granularity < Dygraph.MONTHLY) {
     // Generate one tick mark for every fixed interval of time.
     var spacing = Dygraph.SHORT_SPACINGS[granularity];
-    var format = '%d%b';  // e.g. "1 Jan"
+    var format = '%d%b';  // e.g. "1Jan"
     // TODO(danvk): be smarter about making sure this really hits a "nice" time.
     if (granularity < Dygraph.HOURLY) {
       start_time = spacing * Math.floor(0.5 + start_time / spacing);
@@ -1062,12 +1065,20 @@ Dygraph.numericTicks = function(minV, maxV, self) {
   // Try labels every 1, 2, 5, 10, 20, 50, 100, etc.
   // Calculate the resulting tick spacing (i.e. this.height_ / nTicks).
   // The first spacing greater than pixelsPerYLabel is what we use.
-  var mults = [1, 2, 5];
+  if (self.attr_("labelsKMG2")) {
+    var mults = [1, 2, 4, 8];
+  } else {
+    var mults = [1, 2, 5];
+  }
   var scale, low_val, high_val, nTicks;
   // TODO(danvk): make it possible to set this for x- and y-axes independently.
   var pixelsPerTick = self.attr_('pixelsPerYLabel');
   for (var i = -10; i < 50; i++) {
-    var base_scale = Math.pow(10, i);
+    if (self.attr_("labelsKMG2")) {
+      var base_scale = Math.pow(16, i);
+    } else {
+      var base_scale = Math.pow(10, i);
+    }
     for (var j = 0; j < mults.length; j++) {
       scale = base_scale * mults[j];
       low_val = Math.floor(minV / scale) * scale;
@@ -1154,7 +1165,7 @@ Dygraph.prototype.extremeValues_ = function(series) {
   } else {
     for (var j = 0; j < series.length; j++) {
       var y = series[j][1];
-      if (!y) continue;
+      if (y === null || isNaN(y)) continue;
       if (maxY == null || y > maxY) {
         maxY = y;
       }
@@ -1246,11 +1257,12 @@ Dygraph.prototype.drawGraph_ = function(data) {
   this.addXTicks_();
 
   // Tell PlotKit to use this new data and render itself
+  this.layout_.updateOptions({dateWindow: this.dateWindow_});
   this.layout_.evaluateWithError();
   this.plotter_.clear();
   this.plotter_.render();
-  this.canvas_.getContext('2d').clearRect(0, 0,
-                                         this.canvas_.width, this.canvas_.height);
+  this.canvas_.getContext('2d').clearRect(0, 0, this.canvas_.width,
+                                         this.canvas_.height);
 };
 
 /**
@@ -1633,7 +1645,13 @@ Dygraph.prototype.parseDataTable_ = function(data) {
   var ret = [];
   for (var i = 0; i < rows; i++) {
     var row = [];
-    if (!data.getValue(i, 0)) continue;
+    if (typeof(data.getValue(i, 0)) === 'undefined' ||
+        data.getValue(i, 0) === null) {
+      this.warning("Ignoring row " + i +
+                   " of DataTable because of undefined or null first column.");
+      continue;
+    }
+
     if (indepType == 'date') {
       row.push(data.getValue(i, 0).getTime());
     } else {