Merge remote-tracking branch 'upstream/master' into rgbcolor_change
authorAdil <adilflorida@gmail.com>
Wed, 12 Dec 2012 18:24:30 +0000 (13:24 -0500)
committerAdil <adilflorida@gmail.com>
Wed, 12 Dec 2012 18:24:30 +0000 (13:24 -0500)
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..086d8f8 100644 (file)
@@ -814,39 +814,71 @@ 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/
+// Should be called with the window context:
+//   Dygraph.requestAnimFrame.call(window, function() {})
+Dygraph.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.
+ * Call a function at most maxFrames times at an attempted interval of
+ * framePeriodInMillis, then call a cleanup function once. repeatFn is called
+ * once immediately, then at most (maxFrames - 1) times asynchronously. If
+ * maxFrames==1, then cleanup_fn() is also called synchronously.  This function
+ * is used to sequence animation.
+ * @param {function(number)} repeatFn Called repeatedly -- takes the frame
+ *     number (from 0 to maxFrames-1) as an argument.
+ * @param {number} maxFrames The max number of times to call repeatFn
+ * @param {number} framePeriodInMillis Max requested time between frames.
+ * @param {function()} cleanupFn A function to call after all repeatFn calls.
  * @private
  */
-Dygraph.repeatAndCleanup = function(repeat_fn, times, every_ms, cleanup_fn) {
-  var count = 0;
-  var start_time = new Date().getTime();
-  repeat_fn(count);
-  if (times == 1) {
-    cleanup_fn();
+Dygraph.repeatAndCleanup = function(repeatFn, maxFrames, framePeriodInMillis,
+  cleanupFn) {
+  var frameNumber = 0;
+  var previousFrameNumber;
+  var startTime = new Date().getTime();
+  repeatFn(frameNumber);
+  if (maxFrames == 1) {
+    cleanupFn();
     return;
   }
+  var maxFrameArg = maxFrames - 1;
 
   (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) {
-        cleanup_fn();
+    if (frameNumber >= maxFrames) return;
+    Dygraph.requestAnimFrame.call(window, function() {
+      // Determine which frame to draw based on the delay so far.  Will skip
+      // frames if necessary.
+      var currentTime = new Date().getTime();
+      var delayInMillis = currentTime - startTime;
+      previousFrameNumber = frameNumber;
+      frameNumber = Math.floor(delayInMillis / framePeriodInMillis);
+      var frameDelta = frameNumber - previousFrameNumber;
+      // If we predict that the subsequent repeatFn call will overshoot our
+      // total frame target, so our last call will cause a stutter, then jump to
+      // the last call immediately.  If we're going to cause a stutter, better
+      // to do it faster than slower.
+      var predictOvershootStutter = (frameNumber + frameDelta) > maxFrameArg;
+      if (predictOvershootStutter || (frameNumber >= maxFrameArg)) {
+        repeatFn(maxFrameArg);  // Ensure final call with maxFrameArg.
+        cleanupFn();
       } else {
+        if (frameDelta != 0) {  // Don't call repeatFn with duplicate frames.
+          repeatFn(frameNumber);
+        }
         loop();
       }
-    }, target_time - new Date().getTime());
-    // TODO(danvk): adjust every_ms to produce evenly-timed function calls.
+    });
   })();
 };
 
index 4bef1e4..72a459f 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.
@@ -3027,7 +3028,7 @@ Dygraph.prototype.parseArray_ = function(data) {
     }
   }
 
-  if (Dygraph.isDateLike(data[0][0])) {
+  if (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;
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;