Cleanup of previous commit which included some extraneous lefovers from
authorJeremy Brewer <jeremy.d.brewer@gmail.com>
Fri, 7 Jan 2011 17:40:55 +0000 (12:40 -0500)
committerJeremy Brewer <jeremy.d.brewer@gmail.com>
Fri, 7 Jan 2011 17:40:55 +0000 (12:40 -0500)
the merge.

* Implement %g like formatting in JavaScript.
* Implement related tests for floating point formatting.

dygraph.js

index 3b9a98d..f105576 100644 (file)
@@ -119,7 +119,6 @@ Dygraph.DEFAULT_WIDTH = 480;
 Dygraph.DEFAULT_HEIGHT = 320;
 Dygraph.AXIS_LINE_WIDTH = 0.3;
 
-
 // Default attribute values.
 Dygraph.DEFAULT_ATTRS = {
   highlightCircleSize: 3,
@@ -168,9 +167,7 @@ Dygraph.DEFAULT_ATTRS = {
   hideOverlayOnMouseOut: true,
 
   stepPlot: false,
-  avoidMinZero: false,
-
-  interactionModel: null  // will be set to Dygraph.defaultInteractionModel.
+  avoidMinZero: false
 };
 
 // Various logging levels.
@@ -201,7 +198,7 @@ Dygraph.prototype.__old_init__ = function(div, file, labels, attrs) {
 
 /**
  * Initializes the Dygraph. This creates a new DIV and constructs the PlotKit
- * and context &lt;canvas&gt; inside of it. See the constructor for details.
+ * and interaction &lt;canvas&gt; inside of it. See the constructor for details
  * on the parameters.
  * @param {Element} div the Element to render the graph into.
  * @param {String | Function} file Source data
@@ -357,7 +354,7 @@ Dygraph.prototype.error = function(message) {
 
 /**
  * Returns the current rolling period, as set by the user or an option.
- * @return {Number} The number of days in the rolling window
+ * @return {Number} The number of points in the rolling window
  */
 Dygraph.prototype.rollPeriod = function() {
   return this.rollPeriod_;
@@ -487,23 +484,6 @@ Dygraph.addEvent = function(el, evt, fn) {
   }
 };
 
-
-// Based on the article at
-// http://www.switchonthecode.com/tutorials/javascript-tutorial-the-scroll-wheel
-Dygraph.cancelEvent = function(e) {
-  e = e ? e : window.event;
-  if (e.stopPropagation) {
-    e.stopPropagation();
-  }
-  if (e.preventDefault) {
-    e.preventDefault();
-  }
-  e.cancelBubble = true;
-  e.cancel = true;
-  e.returnValue = false;
-  return false;
-}
-
 /**
  * Generates interface elements for the Dygraph: a containing div, a div to
  * display the current point, and a textbox to adjust the rolling average
@@ -836,347 +816,242 @@ Dygraph.pageY = function(e) {
   }
 };
 
-Dygraph.prototype.dragGetX_ = function(e, context) {
-  return Dygraph.pageX(e) - context.px
-};
-
-Dygraph.prototype.dragGetY_ = function(e, context) {
-  return Dygraph.pageY(e) - context.py
-};
-
-// Called in response to an interaction model operation that
-// should start the default panning behavior.
-//
-// It's used in the default callback for "mousedown" operations.
-// Custom interaction model builders can use it to provide the default
-// panning behavior.
-//
-Dygraph.startPan = function(event, g, context) {
-  // have to be zoomed in to pan.
-  // TODO(konigsberg): Let's loosen this zoom-to-pan restriction, also
-  // perhaps create panning boundaries? A more flexible pan would make it,
-  // ahem, 'pan-useful'.
-  var zoomedY = false;
-  for (var i = 0; i < g.axes_.length; i++) {
-    if (g.axes_[i].valueWindow || g.axes_[i].valueRange) {
-      zoomedY = true;
-      break;
-    }
-  }
-  if (!g.dateWindow_ && !zoomedY) return;
-
-  context.isPanning = true;
-  var xRange = g.xAxisRange();
-  context.dateRange = xRange[1] - xRange[0];
-
-  // Record the range of each y-axis at the start of the drag.
-  // If any axis has a valueRange or valueWindow, then we want a 2D pan.
-  context.is2DPan = false;
-  for (var i = 0; i < g.axes_.length; i++) {
-    var axis = g.axes_[i];
-    var yRange = g.yAxisRange(i);
-    axis.dragValueRange = yRange[1] - yRange[0];
-    var r = g.toDataCoords(null, context.dragStartY, i);
-    axis.draggingValue = r[1];
-    if (axis.valueWindow || axis.valueRange) context.is2DPan = true;
-  }
-
-  // TODO(konigsberg): Switch from all this math to toDataCoords?
-  // Seems to work for the dragging value.
-  context.draggingDate = (context.dragStartX / g.width_) * context.dateRange + xRange[0];
-};
+/**
+ * Set up all the mouse handlers needed to capture dragging behavior for zoom
+ * events.
+ * @private
+ */
+Dygraph.prototype.createDragInterface_ = function() {
+  var self = this;
 
-// Called in response to an interaction model operation that
-// responds to an event that pans the view.
-//
-// It's used in the default callback for "mousemove" operations.
-// Custom interaction model builders can use it to provide the default
-// panning behavior.
-//
-Dygraph.movePan = function(event, g, context) {
-  context.dragEndX = g.dragGetX_(event, context);
-  context.dragEndY = g.dragGetY_(event, context);
+  // Tracks whether the mouse is down right now
+  var isZooming = false;
+  var isPanning = false;  // is this drag part of a pan?
+  var is2DPan = false;    // if so, is that pan 1- or 2-dimensional?
+  var dragStartX = null;
+  var dragStartY = null;
+  var dragEndX = null;
+  var dragEndY = null;
+  var dragDirection = null;
+  var prevEndX = null;
+  var prevEndY = null;
+  var prevDragDirection = null;
 
   // TODO(danvk): update this comment
-  // Want to have it so that:
-  // 1. draggingDate appears at dragEndX, draggingValue appears at dragEndY.
-  // 2. daterange = (dateWindow_[1] - dateWindow_[0]) is unaltered.
-  // 3. draggingValue appears at dragEndY.
-  // 4. valueRange is unaltered.
+  // draggingDate and draggingValue represent the [date,value] point on the
+  // graph at which the mouse was pressed. As the mouse moves while panning,
+  // the viewport must pan so that the mouse position points to
+  // [draggingDate, draggingValue]
+  var draggingDate = null;
 
-  var minDate = context.draggingDate - (context.dragEndX / g.width_) * context.dateRange;
-  var maxDate = minDate + context.dateRange;
-  g.dateWindow_ = [minDate, maxDate];
+  // TODO(danvk): update this comment
+  // The range in second/value units that the viewport encompasses during a
+  // panning operation.
+  var dateRange = null;
 
-  // y-axis scaling is automatic unless this is a full 2D pan.
-  if (context.is2DPan) {
-    // Adjust each axis appropriately.
-    var y_frac = context.dragEndY / g.height_;
-    for (var i = 0; i < g.axes_.length; i++) {
-      var axis = g.axes_[i];
-      var maxValue = axis.draggingValue + y_frac * axis.dragValueRange;
-      var minValue = maxValue - axis.dragValueRange;
-      axis.valueWindow = [ minValue, maxValue ];
-    }
-  }
+  // Utility function to convert page-wide coordinates to canvas coords
+  var px = 0;
+  var py = 0;
+  var getX = function(e) { return Dygraph.pageX(e) - px };
+  var getY = function(e) { return Dygraph.pageY(e) - py };
 
-  g.drawGraph_();
-}
+  // Draw zoom rectangles when the mouse is down and the user moves around
+  Dygraph.addEvent(this.mouseEventElement_, 'mousemove', function(event) {
+    if (isZooming) {
+      dragEndX = getX(event);
+      dragEndY = getY(event);
+
+      var xDelta = Math.abs(dragStartX - dragEndX);
+      var yDelta = Math.abs(dragStartY - dragEndY);
+
+      // drag direction threshold for y axis is twice as large as x axis
+      dragDirection = (xDelta < yDelta / 2) ? Dygraph.VERTICAL : Dygraph.HORIZONTAL;
+
+      self.drawZoomRect_(dragDirection, dragStartX, dragEndX, dragStartY, dragEndY,
+                         prevDragDirection, prevEndX, prevEndY);
+
+      prevEndX = dragEndX;
+      prevEndY = dragEndY;
+      prevDragDirection = dragDirection;
+    } else if (isPanning) {
+      dragEndX = getX(event);
+      dragEndY = getY(event);
+
+      // TODO(danvk): update this comment
+      // Want to have it so that:
+      // 1. draggingDate appears at dragEndX, draggingValue appears at dragEndY.
+      // 2. daterange = (dateWindow_[1] - dateWindow_[0]) is unaltered.
+      // 3. draggingValue appears at dragEndY.
+      // 4. valueRange is unaltered.
+
+      var minDate = draggingDate - (dragEndX / self.width_) * dateRange;
+      var maxDate = minDate + dateRange;
+      self.dateWindow_ = [minDate, maxDate];
+
+
+      // y-axis scaling is automatic unless this is a full 2D pan.
+      if (is2DPan) {
+        // Adjust each axis appropriately.
+        var y_frac = dragEndY / self.height_;
+        for (var i = 0; i < self.axes_.length; i++) {
+          var axis = self.axes_[i];
+          var maxValue = axis.draggingValue + y_frac * axis.dragValueRange;
+          var minValue = maxValue - axis.dragValueRange;
+          axis.valueWindow = [ minValue, maxValue ];
+        }
+      }
 
-// Called in response to an interaction model operation that
-// responds to an event that ends panning.
-//
-// It's used in the default callback for "mouseup" operations.
-// Custom interaction model builders can use it to provide the default
-// panning behavior.
-//
-Dygraph.endPan = function(event, g, context) {
-  context.isPanning = false;
-  context.is2DPan = false;
-  context.draggingDate = null;
-  context.dateRange = null;
-  context.valueRange = null;
-}
+      self.drawGraph_();
+    }
+  });
 
-// Called in response to an interaction model operation that
-// responds to an event that starts zooming.
-//
-// It's used in the default callback for "mousedown" operations.
-// Custom interaction model builders can use it to provide the default
-// zooming behavior.
-//
-Dygraph.startZoom = function(event, g, context) {
-  context.isZooming = true;
-}
+  // Track the beginning of drag events
+  Dygraph.addEvent(this.mouseEventElement_, 'mousedown', function(event) {
+    // prevents mouse drags from selecting page text.
+    if (event.preventDefault) {
+      event.preventDefault();  // Firefox, Chrome, etc.
+    } else {
+      event.returnValue = false;  // IE
+      event.cancelBubble = true;  
+    }
 
-// Called in response to an interaction model operation that
-// responds to an event that defines zoom boundaries.
-//
-// It's used in the default callback for "mousemove" operations.
-// Custom interaction model builders can use it to provide the default
-// zooming behavior.
-//
-Dygraph.moveZoom = function(event, g, context) {
-  context.dragEndX = g.dragGetX_(event, context);
-  context.dragEndY = g.dragGetY_(event, context);
-
-  var xDelta = Math.abs(context.dragStartX - context.dragEndX);
-  var yDelta = Math.abs(context.dragStartY - context.dragEndY);
-
-  // drag direction threshold for y axis is twice as large as x axis
-  context.dragDirection = (xDelta < yDelta / 2) ? Dygraph.VERTICAL : Dygraph.HORIZONTAL;
-
-  g.drawZoomRect_(
-      context.dragDirection,
-      context.dragStartX,
-      context.dragEndX,
-      context.dragStartY,
-      context.dragEndY,
-      context.prevDragDirection,
-      context.prevEndX,
-      context.prevEndY);
-
-  context.prevEndX = context.dragEndX;
-  context.prevEndY = context.dragEndY;
-  context.prevDragDirection = context.dragDirection;
-}
+    px = Dygraph.findPosX(self.canvas_);
+    py = Dygraph.findPosY(self.canvas_);
+    dragStartX = getX(event);
+    dragStartY = getY(event);
 
-// Called in response to an interaction model operation that
-// responds to an event that performs a zoom based on previously defined
-// bounds..
-//
-// It's used in the default callback for "mouseup" operations.
-// Custom interaction model builders can use it to provide the default
-// zooming behavior.
-//
-Dygraph.endZoom = function(event, g, context) {
-  context.isZooming = false;
-  context.dragEndX = g.dragGetX_(event, context);
-  context.dragEndY = g.dragGetY_(event, context);
-  var regionWidth = Math.abs(context.dragEndX - context.dragStartX);
-  var regionHeight = Math.abs(context.dragEndY - context.dragStartY);
-
-  if (regionWidth < 2 && regionHeight < 2 &&
-      g.lastx_ != undefined && g.lastx_ != -1) {
-    // TODO(danvk): pass along more info about the points, e.g. 'x'
-    if (g.attr_('clickCallback') != null) {
-      g.attr_('clickCallback')(event, g.lastx_, g.selPoints_);
-    }
-    if (g.attr_('pointClickCallback')) {
-      // check if the click was on a particular point.
-      var closestIdx = -1;
-      var closestDistance = 0;
-      for (var i = 0; i < g.selPoints_.length; i++) {
-        var p = g.selPoints_[i];
-        var distance = Math.pow(p.canvasx - context.dragEndX, 2) +
-                       Math.pow(p.canvasy - context.dragEndY, 2);
-        if (closestIdx == -1 || distance < closestDistance) {
-          closestDistance = distance;
-          closestIdx = i;
+    if (event.altKey || event.shiftKey) {
+      // have to be zoomed in to pan.
+      var zoomedY = false;
+      for (var i = 0; i < self.axes_.length; i++) {
+        if (self.axes_[i].valueWindow || self.axes_[i].valueRange) {
+          zoomedY = true;
+          break;
         }
       }
+      if (!self.dateWindow_ && !zoomedY) return;
 
-      // Allow any click within two pixels of the dot.
-      var radius = g.attr_('highlightCircleSize') + 2;
-      if (closestDistance <= 5 * 5) {
-        g.attr_('pointClickCallback')(event, g.selPoints_[closestIdx]);
-      }
-    }
-  }
-
-  if (regionWidth >= 10 && context.dragDirection == Dygraph.HORIZONTAL) {
-    g.doZoomX_(Math.min(context.dragStartX, context.dragEndX),
-               Math.max(context.dragStartX, context.dragEndX));
-  } else if (regionHeight >= 10 && context.dragDirection == Dygraph.VERTICAL) {
-    g.doZoomY_(Math.min(context.dragStartY, context.dragEndY),
-               Math.max(context.dragStartY, context.dragEndY));
-  } else {
-    g.canvas_.getContext("2d").clearRect(0, 0,
-                                       g.canvas_.width,
-                                       g.canvas_.height);
-  }
-  context.dragStartX = null;
-  context.dragStartY = null;
-}
+      isPanning = true;
+      var xRange = self.xAxisRange();
+      dateRange = xRange[1] - xRange[0];
 
-Dygraph.defaultInteractionModel = {
-  // Track the beginning of drag events
-  mousedown: function(event, g, context) {
-    context.initializeMouseDown(event, g, context);
+      // Record the range of each y-axis at the start of the drag.
+      // If any axis has a valueRange or valueWindow, then we want a 2D pan.
+      is2DPan = false;
+      for (var i = 0; i < self.axes_.length; i++) {
+        var axis = self.axes_[i];
+        var yRange = self.yAxisRange(i);
+        axis.dragValueRange = yRange[1] - yRange[0];
+        var r = self.toDataCoords(null, dragStartY, i);
+        axis.draggingValue = r[1];
+        if (axis.valueWindow || axis.valueRange) is2DPan = true;
+      }
 
-    if (event.altKey || event.shiftKey) {
-      Dygraph.startPan(event, g, context);
+      // TODO(konigsberg): Switch from all this math to toDataCoords?
+      // Seems to work for the dragging value.
+      draggingDate = (dragStartX / self.width_) * dateRange + xRange[0];
     } else {
-      Dygraph.startZoom(event, g, context);
+      isZooming = true;
     }
-  },
+  });
 
-  // Draw zoom rectangles when the mouse is down and the user moves around
-  mousemove: function(event, g, context) {
-    if (context.isZooming) {
-      Dygraph.moveZoom(event, g, context);
-    } else if (context.isPanning) {
-      Dygraph.movePan(event, g, context);
+  // If the user releases the mouse button during a drag, but not over the
+  // canvas, then it doesn't count as a zooming action.
+  Dygraph.addEvent(document, 'mouseup', function(event) {
+    if (isZooming || isPanning) {
+      isZooming = false;
+      dragStartX = null;
+      dragStartY = null;
     }
-  },
 
-  mouseup: function(event, g, context) {
-    if (context.isZooming) {
-      Dygraph.endZoom(event, g, context);
-    } else if (context.isPanning) {
-      Dygraph.endPan(event, g, context);
+    if (isPanning) {
+      isPanning = false;
+      draggingDate = null;
+      dateRange = null;
+      for (var i = 0; i < self.axes_.length; i++) {
+        delete self.axes_[i].draggingValue;
+        delete self.axes_[i].dragValueRange;
+      }
     }
-  },
+  });
 
   // Temporarily cancel the dragging event when the mouse leaves the graph
-  mouseout: function(event, g, context) {
-    if (context.isZooming) {
-      context.dragEndX = null;
-      context.dragEndY = null;
+  Dygraph.addEvent(this.mouseEventElement_, 'mouseout', function(event) {
+    if (isZooming) {
+      dragEndX = null;
+      dragEndY = null;
     }
-  },
+  });
 
-  // Disable zooming out if panning.
-  dblclick: function(event, g, context) {
-    if (event.altKey || event.shiftKey) {
-      return;
-    }
-    // TODO(konigsberg): replace g.doUnzoom()_ with something that is
-    // friendlier to public use.
-    g.doUnzoom_();
-  }
-};
+  // If the mouse is released on the canvas during a drag event, then it's a
+  // zoom. Only do the zoom if it's over a large enough area (>= 10 pixels)
+  Dygraph.addEvent(this.mouseEventElement_, 'mouseup', function(event) {
+    if (isZooming) {
+      isZooming = false;
+      dragEndX = getX(event);
+      dragEndY = getY(event);
+      var regionWidth = Math.abs(dragEndX - dragStartX);
+      var regionHeight = Math.abs(dragEndY - dragStartY);
+
+      if (regionWidth < 2 && regionHeight < 2 &&
+          self.lastx_ != undefined && self.lastx_ != -1) {
+        // TODO(danvk): pass along more info about the points, e.g. 'x'
+        if (self.attr_('clickCallback') != null) {
+          self.attr_('clickCallback')(event, self.lastx_, self.selPoints_);
+        }
+        if (self.attr_('pointClickCallback')) {
+          // check if the click was on a particular point.
+          var closestIdx = -1;
+          var closestDistance = 0;
+          for (var i = 0; i < self.selPoints_.length; i++) {
+            var p = self.selPoints_[i];
+            var distance = Math.pow(p.canvasx - dragEndX, 2) +
+                           Math.pow(p.canvasy - dragEndY, 2);
+            if (closestIdx == -1 || distance < closestDistance) {
+              closestDistance = distance;
+              closestIdx = i;
+            }
+          }
 
-Dygraph.DEFAULT_ATTRS.interactionModel = Dygraph.defaultInteractionModel;
+          // Allow any click within two pixels of the dot.
+          var radius = self.attr_('highlightCircleSize') + 2;
+          if (closestDistance <= 5 * 5) {
+            self.attr_('pointClickCallback')(event, self.selPoints_[closestIdx]);
+          }
+        }
+      }
 
-/**
- * Set up all the mouse handlers needed to capture dragging behavior for zoom
- * events.
- * @private
- */
-Dygraph.prototype.createDragInterface_ = function() {
-  var context = {
-    // Tracks whether the mouse is down right now
-    isZooming: false,
-    isPanning: false,  // is this drag part of a pan?
-    is2DPan: false,    // if so, is that pan 1- or 2-dimensional?
-    dragStartX: null,
-    dragStartY: null,
-    dragEndX: null,
-    dragEndY: null,
-    dragDirection: null,
-    prevEndX: null,
-    prevEndY: null,
-    prevDragDirection: null,
-
-    // TODO(danvk): update this comment
-    // draggingDate and draggingValue represent the [date,value] point on the
-    // graph at which the mouse was pressed. As the mouse moves while panning,
-    // the viewport must pan so that the mouse position points to
-    // [draggingDate, draggingValue]
-    draggingDate: null,
-
-    // TODO(danvk): update this comment
-    // The range in second/value units that the viewport encompasses during a
-    // panning operation.
-    dateRange: null,
-
-    // Utility function to convert page-wide coordinates to canvas coords
-    px: 0,
-    py: 0,
-
-    initializeMouseDown: function(event, g, context) {
-      // prevents mouse drags from selecting page text.
-      if (event.preventDefault) {
-        event.preventDefault();  // Firefox, Chrome, etc.
+      if (regionWidth >= 10 && dragDirection == Dygraph.HORIZONTAL) {
+        self.doZoomX_(Math.min(dragStartX, dragEndX),
+                     Math.max(dragStartX, dragEndX));
+      } else if (regionHeight >= 10 && dragDirection == Dygraph.VERTICAL){
+        self.doZoomY_(Math.min(dragStartY, dragEndY),
+                      Math.max(dragStartY, dragEndY));
       } else {
-        event.returnValue = false;  // IE
-        event.cancelBubble = true;
+        self.canvas_.getContext("2d").clearRect(0, 0,
+                                           self.canvas_.width,
+                                           self.canvas_.height);
       }
 
-      context.px = Dygraph.findPosX(g.canvas_);
-      context.py = Dygraph.findPosY(g.canvas_);
-      context.dragStartX = g.dragGetX_(event, context);
-      context.dragStartY = g.dragGetY_(event, context);
+      dragStartX = null;
+      dragStartY = null;
     }
-  };
-
-  var interactionModel = this.attr_("interactionModel");
-
-  // Self is the graph.
-  var self = this;
-
-  // Function that binds the graph and context to the handler.
-  var bindHandler = function(handler) {
-    return function(event) {
-      handler(event, self, context);
-    };
-  };
-
-  for (var eventName in interactionModel) {
-    if (!interactionModel.hasOwnProperty(eventName)) continue;
-    Dygraph.addEvent(this.mouseEventElement_, eventName,
-        bindHandler(interactionModel[eventName]));
-  }
 
-  // If the user releases the mouse button during a drag, but not over the
-  // canvas, then it doesn't count as a zooming action.
-  Dygraph.addEvent(document, 'mouseup', function(event) {
-    if (context.isZooming || context.isPanning) {
-      context.isZooming = false;
-      context.dragStartX = null;
-      context.dragStartY = null;
+    if (isPanning) {
+      isPanning = false;
+      is2DPan = false;
+      draggingDate = null;
+      dateRange = null;
+      valueRange = null;
     }
+  });
 
-    if (context.isPanning) {
-      context.isPanning = false;
-      context.draggingDate = null;
-      context.dateRange = null;
-      for (var i = 0; i < self.axes_.length; i++) {
-        delete self.axes_[i].draggingValue;
-        delete self.axes_[i].dragValueRange;
-      }
-    }
+  // Double-clicking zooms back out
+  Dygraph.addEvent(this.mouseEventElement_, 'dblclick', function(event) {
+    // Disable zooming out if panning.
+    if (event.altKey || event.shiftKey) return;
+
+    self.doUnzoom_();
   });
 };
 
@@ -1350,7 +1225,7 @@ Dygraph.prototype.mouseMove_ = function(event) {
   for (var i = 0; i < points.length; i++) {
     var point = points[i];
     if (point == null) continue;
-    var dist = Math.abs(point.canvasx - canvasx);
+    var dist = Math.abs(points[i].canvasx - canvasx);
     if (dist > minDist) continue;
     minDist = dist;
     idx = i;
@@ -1605,9 +1480,7 @@ Dygraph.hmsString_ = function(date) {
  * @private
  */
 Dygraph.dateAxisFormatter = function(date, granularity) {
-  if (granularity >= Dygraph.DECADAL) {
-    return date.strftime('%Y');
-  } else if (granularity >= Dygraph.MONTHLY) {
+  if (granularity >= Dygraph.MONTHLY) {
     return date.strftime('%b %y');
   } else {
     var frac = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() + date.getMilliseconds();
@@ -1644,18 +1517,6 @@ Dygraph.dateString_ = function(date) {
 };
 
 /**
- * Round a number to the specified number of digits past the decimal point.
- * @param {Number} num The number to round
- * @param {Number} places The number of decimals to which to round
- * @return {Number} The rounded number
- * @private
- */
-Dygraph.round_ = function(num, places) {
-  var shift = Math.pow(10, places);
-  return Math.round(num * shift)/shift;
-};
-
-/**
  * Fires when there's data available to be graphed.
  * @param {String} data Raw CSV data to be plotted
  * @private
@@ -1710,8 +1571,7 @@ Dygraph.QUARTERLY = 16;
 Dygraph.BIANNUAL = 17;
 Dygraph.ANNUAL = 18;
 Dygraph.DECADAL = 19;
-Dygraph.CENTENNIAL = 20;
-Dygraph.NUM_GRANULARITIES = 21;
+Dygraph.NUM_GRANULARITIES = 20;
 
 Dygraph.SHORT_SPACINGS = [];
 Dygraph.SHORT_SPACINGS[Dygraph.SECONDLY]        = 1000 * 1;
@@ -1747,7 +1607,6 @@ Dygraph.prototype.NumXTicks = function(start_time, end_time, granularity) {
     if (granularity == Dygraph.BIANNUAL) num_months = 2;
     if (granularity == Dygraph.ANNUAL) num_months = 1;
     if (granularity == Dygraph.DECADAL) { num_months = 1; year_mod = 10; }
-    if (granularity == Dygraph.CENTENNIAL) { num_months = 1; year_mod = 100; }
 
     var msInYear = 365.2524 * 24 * 3600 * 1000;
     var num_years = 1.0 * (end_time - start_time) / msInYear;
@@ -1820,11 +1679,6 @@ Dygraph.prototype.GetXAxis = function(start_time, end_time, granularity) {
     } else if (granularity == Dygraph.DECADAL) {
       months = [ 0 ];
       year_mod = 10;
-    } else if (granularity == Dygraph.CENTENNIAL) {
-      months = [ 0 ];
-      year_mod = 100;
-    } else {
-      this.warn("Span of dates is too long");
     }
 
     var start_year = new Date(start_time).getFullYear();
@@ -2198,12 +2052,9 @@ Dygraph.prototype.drawGraph_ = function() {
     this.layout_.addDataset(this.attr_("labels")[i], datasets[i]);
   }
 
-  // TODO(danvk): this method doesn't need to return anything.
-  var out = this.computeYAxisRanges_(extremes);
-  var axes = out[0];
-  var seriesToAxisMap = out[1];
-  this.layout_.updateOptions( { yAxes: axes,
-                                seriesToAxisMap: seriesToAxisMap
+  this.computeYAxisRanges_(extremes);
+  this.layout_.updateOptions( { yAxes: this.axes_,
+                                seriesToAxisMap: this.seriesToAxisMap_
                               } );
 
   this.addXTicks_();
@@ -2409,8 +2260,6 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
       this.numYDigits_ = ret.numDigits;
     }
   }
-
-  return [this.axes_, this.seriesToAxisMap_];
 };
  
 /**
@@ -2422,7 +2271,8 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
  * Note that this is where fractional input (i.e. '5/10') is converted into
  *   decimal values.
  * @param {Array} originalData The data in the appropriate format (see above)
- * @param {Number} rollPeriod The number of days over which to average the data
+ * @param {Number} rollPeriod The number of points over which to average the
+ *                            data
  */
 Dygraph.prototype.rollingAverage = function(originalData, rollPeriod) {
   if (originalData.length < 2)
@@ -2499,7 +2349,7 @@ Dygraph.prototype.rollingAverage = function(originalData, rollPeriod) {
     }
   } else {
     // Calculate the rolling average for the first rollPeriod - 1 points where
-    // there is not enough data to roll over the full number of days
+    // there is not enough data to roll over the full number of points
     var num_init_points = Math.min(rollPeriod - 1, originalData.length - 2);
     if (!this.attr_("errorBars")){
       if (rollPeriod == 1) {
@@ -3071,9 +2921,9 @@ Dygraph.prototype.resize = function(width, height) {
 };
 
 /**
- * Adjusts the number of days in the rolling average. Updates the graph to
+ * Adjusts the number of points in the rolling average. Updates the graph to
  * reflect the new averaging period.
- * @param {Number} length Number of days over which to average the data.
+ * @param {Number} length Number of points over which to average the data.
  */
 Dygraph.prototype.adjustRoll = function(length) {
   this.rollPeriod_ = length;