* search) and generic DOM-manipulation functions.
*/
+"use strict";
+
Dygraph.LOG_SCALE = 10;
Dygraph.LN_TEN = Math.log(Dygraph.LOG_SCALE);
Dygraph.WARNING = 3;
Dygraph.ERROR = 3;
-// TODO(danvk): any way I can get the line numbers to be this.warn call?
+// Set this to log stack traces on warnings, etc.
+// This requires stacktrace.js, which is up to you to provide.
+// A copy can be found in the dygraphs repo, or at
+// https://github.com/eriwen/javascript-stacktrace
+Dygraph.LOG_STACK_TRACES = false;
+
/**
* @private
* Log an error on the JS console at the given severity.
* @param { String } The message to log.
*/
Dygraph.log = function(severity, message) {
+ var st;
+ if (typeof(printStackTrace) != 'undefined') {
+ // Remove uninteresting bits: logging functions and paths.
+ var st = printStackTrace({guess:false});
+ while (st[0].indexOf("stacktrace") != -1) {
+ st.splice(0, 1);
+ }
+
+ st.splice(0, 2);
+ for (var i = 0; i < st.length; i++) {
+ st[i] = st[i].replace(/\([^)]*\/(.*)\)/, '@$1')
+ .replace(/\@.*\/([^\/]*)/, '@$1')
+ .replace('[object Object].', '');
+ }
+ var top_msg = st.splice(0, 1)[0];
+ message += ' (' + top_msg.replace(/^.*@ ?/, '') + ')';
+ }
+
if (typeof(console) != 'undefined') {
switch (severity) {
case Dygraph.DEBUG:
break;
}
}
+
+ if (Dygraph.LOG_STACK_TRACES) {
+ console.log(st.join('\n'));
+ }
};
/** @private */
Dygraph.dateParser = function(dateStr) {
var dateStrSlashed;
var d;
+
+ // Let the system try the format first.
+ d = Dygraph.dateStrToMillis(dateStr);
+ if (d && !isNaN(d)) return d;
+
if (dateStr.search("-") != -1) { // e.g. '2009-7-12' or '2009-07-12'
dateStrSlashed = dateStr.replace("-", "/", "g");
while (dateStrSlashed.search("-") != -1) {
Dygraph.createCanvas = function() {
var canvas = document.createElement("canvas");
- isIE = (/MSIE/.test(navigator.userAgent) && !window.opera);
+ var isIE = (/MSIE/.test(navigator.userAgent) && !window.opera);
if (isIE && (typeof(G_vmlCanvasManager) != 'undefined')) {
canvas = G_vmlCanvasManager.initElement(canvas);
}
/**
* @private
+ * Checks whether the user is on an Android browser.
+ * Android does not fully support the <canvas> tag, e.g. w/r/t/ clipping.
+ */
+Dygraph.isAndroid = function() {
+ return /Android/.test(navigator.userAgent);
+};
+
+/**
+ * @private
+ * 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 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 to call repeat_fn
+ * @param every_ms {number} Milliseconds 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 start_time = new Date().getTime();
+ repeat_fn(count);
+ if (times == 1) {
+ cleanup_fn();
+ return;
+ }
+
+ (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();
+ } else {
+ loop();
+ }
+ }, target_time - new Date().getTime());
+ // TODO(danvk): adjust every_ms to produce evenly-timed function calls.
+ })();
+};
+
+/**
+ * @private
* This function will scan the option list and determine if they
* require us to recalculate the pixel positions of each point.
* @param { List } a list of options to check.
'axisLineColor': true,
'axisLineWidth': true,
'clickCallback': true,
- 'colorSaturation': true,
- 'colorValue': true,
- 'colors': true,
- 'connectSeparatedPoints': true,
'digitsAfterDecimal': true,
'drawCallback': true,
'drawPoints': true,
}
// Iterate through the list of updated options.
- for (property in attrs) {
+ for (var property in attrs) {
// Break early if we already know we need new points from a previous option.
if (requiresNewPoints) {
break;
if (seriesNamesDictionary[property]) {
// This property value is a list of options for this series.
// If any of these sub properties are not pixel safe, set the flag.
- for (subProperty in attrs[property]) {
+ for (var subProperty in attrs[property]) {
// Break early if we already know we need new points from a previous option.
if (requiresNewPoints) {
break;