- Added xIsEpochDate option to save redundant encoding to Date objects when X axis...
authorAdil <adilflorida@gmail.com>
Wed, 28 Nov 2012 21:37:06 +0000 (16:37 -0500)
committerAdil <adilflorida@gmail.com>
Wed, 28 Nov 2012 21:37:06 +0000 (16:37 -0500)
- Using requestAnimationFrame to make animatedZooms smoother.
- Made doUnzoom() and predraw() methods public (to allow more graph control).
- Renamed RGBColor to RGBColorParser to avoid a function name collision with: http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-RGBColor

dygraph-canvas.js
dygraph-utils.js
dygraph.js
rgbcolor/rgbcolor.js

index 29e402e..fad3054 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*jshint globalstrict: true */
-/*global Dygraph:false,RGBColor:false */
+/*global Dygraph:false,RGBColorParser:false */
 "use strict";
 
 
@@ -610,7 +610,7 @@ DygraphCanvasRenderer._errorPlotter = function(e) {
   var prevYs = [-1, -1];
   var yscale = axis.yscale;
   // should be same color as the lines but only 15% opaque.
-  var rgb = new RGBColor(color);
+  var rgb = new RGBColorParser(color);
   var err_color =
       'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
   ctx.fillStyle = err_color;
@@ -726,7 +726,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) {
     var newYs;
     var yscale = axis.yscale;
     // should be same color as the lines but only 15% opaque.
-    var rgb = new RGBColor(color);
+    var rgb = new RGBColorParser(color);
     var err_color =
         'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
     ctx.fillStyle = err_color;
index e306b3e..797adce 100644 (file)
@@ -814,19 +814,35 @@ Dygraph.createIterator = function(array, start, length, opt_predicate) {
   return new Dygraph.Iterator(array, start, length, opt_predicate);
 };
 
+// Shim layer with setTimeout fallback.
+// From: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+window.requestAnimFrame = (function(){
+  return window.requestAnimationFrame       ||
+          window.webkitRequestAnimationFrame ||
+          window.mozRequestAnimationFrame    ||
+          window.oRequestAnimationFrame      ||
+          window.msRequestAnimationFrame     ||
+          function (callback) {
+            window.setTimeout(callback, 1000 / 60);
+          };
+})();
+
 /**
- * Call a function N times at a given interval, then call a cleanup function
- * once. repeat_fn is called once immediately, then (times - 1) times
- * asynchronously. If times=1, then cleanup_fn() is also called synchronously.
- * @param {function(number)} repeat_fn Called repeatedly -- takes the number of
- *     calls (from 0 to times-1) as an argument.
- * @param {number} times The number of times to call repeat_fn
- * @param {number} every_ms Milliseconds between calls
- * @param {function()} cleanup_fn A function to call after all repeat_fn calls.
+ * @private
+ * Call a function at most N times at an attempted given interval, then call a
+ * cleanup function once. repeat_fn is called once immediately, then (times - 1)
+ * times asynchronously. If times=1, then cleanup_fn() is also called
+ * synchronously.
+ * @param repeat_fn {Function} Called repeatedly -- takes the number of calls
+ * (from 0 to times-1) as an argument.
+ * @param times {number} The number of times max to call repeat_fn
+ * @param every_ms {number} Milliseconds to schedule between calls
+ * @param cleanup_fn {Function} A function to call after all repeat_fn calls.
  * @private
  */
 Dygraph.repeatAndCleanup = function(repeat_fn, times, every_ms, cleanup_fn) {
   var count = 0;
+  var previous_count;
   var start_time = new Date().getTime();
   repeat_fn(count);
   if (times == 1) {
@@ -836,17 +852,24 @@ Dygraph.repeatAndCleanup = function(repeat_fn, times, every_ms, cleanup_fn) {
 
   (function loop() {
     if (count >= times) return;
-    var target_time = start_time + (1 + count) * every_ms;
-    setTimeout(function() {
-      count++;
-      repeat_fn(count);
-      if (count >= times - 1) {
+    window.requestAnimFrame(function(scheduled_epoch_time_ms) {
+      var delay = (scheduled_epoch_time_ms - start_time);
+      previous_count = count;
+      count = Math.floor(delay / every_ms);
+      if ((count - previous_count) > (times / 2)) {
+        count = previous_count + (times / 2);
+      }
+      if (count > times - 1) {
+        // Ensure call at max times.
+        if (previous_count !== (times - 1)) {
+          repeat_fn(times - 1);
+        }
         cleanup_fn();
       } else {
+        repeat_fn(count);
         loop();
       }
-    }, target_time - new Date().getTime());
-    // TODO(danvk): adjust every_ms to produce evenly-timed function calls.
+    });
   })();
 };
 
index d42bb9f..3366fe3 100644 (file)
@@ -91,7 +91,8 @@ Dygraph.DEFAULT_ROLL_PERIOD = 1;
 Dygraph.DEFAULT_WIDTH = 480;
 Dygraph.DEFAULT_HEIGHT = 320;
 
-Dygraph.ANIMATION_STEPS = 10;
+// For max 60 Hz. animation:
+Dygraph.ANIMATION_STEPS = 12;
 Dygraph.ANIMATION_DURATION = 200;
 
 // These are defined before DEFAULT_ATTRS so that it can refer to them.
@@ -273,6 +274,8 @@ Dygraph.DEFAULT_ATTRS = {
   rangeSelectorPlotStrokeColor: "#808FAB",
   rangeSelectorPlotFillColor: "#A7B1C4",
 
+  xIsEpochDate: false,
+
   // The ordering here ensures that central lines always appear above any
   // fill bars/error bars.
   plotter: [
@@ -1455,6 +1458,10 @@ Dygraph.prototype.doZoomY_ = function(lowY, highY) {
   });
 };
 
+Dygraph.prototype.doUnzoom = function() {
+  this.doUnzoom_();
+};
+
 /**
  * Reset the zoom to the original view coordinates. This is the same as
  * double-clicking on the graph.
@@ -2135,6 +2142,10 @@ Dygraph.prototype.extremeValues_ = function(series) {
   return [minY, maxY];
 };
 
+Dygraph.prototype.predraw = function() {
+  this.predraw_();
+};
+
 /**
  * @private
  * This function is called once when the chart's data is changed or the options
@@ -3095,12 +3106,16 @@ Dygraph.prototype.parseArray_ = function(data) {
     }
   }
 
-  if (Dygraph.isDateLike(data[0][0])) {
+  if (this.attr_("xIsEpochDate") || Dygraph.isDateLike(data[0][0])) {
     // Some intelligent defaults for a date x-axis.
     this.attrs_.axes.x.valueFormatter = Dygraph.dateString_;
     this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter;
     this.attrs_.axes.x.ticker = Dygraph.dateTicker;
 
+    if (this.attr_("xIsEpochDate")) {
+      return data;
+    }
+
     // Assume they're all dates.
     var parsedData = Dygraph.clone(data);
     for (i = 0; i < data.length; i++) {
index 67b730e..5a88244 100644 (file)
@@ -4,13 +4,18 @@
  * NOTE: modified by danvk. I removed the "getHelpXML" function to reduce the
  * file size, added "use strict" and a few "var" declarations where needed.
  *
+ * Modifications by adilh:
+ * Original "RGBColor" function name collides with:
+ *   http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-RGBColor
+ * so renamed to "RGBColorParser"
+ *
  * @author Stoyan Stefanov <sstoo@gmail.com>
  * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
  * @license Use it if you like it
  */
 "use strict";
 
-function RGBColor(color_string)
+function RGBColorParser(color_string)
 {
     this.ok = false;