*/
/*jshint globalstrict: true */
-/*global Dygraph:false, G_vmlCanvasManager:false, Node:false, printStackTrace: false */
+/*global Dygraph:false, G_vmlCanvasManager:false, Node:false */
"use strict";
Dygraph.LOG_SCALE = 10;
return Math.log(x) / Dygraph.LN_TEN;
};
-// Various logging levels.
-Dygraph.DEBUG = 1;
-Dygraph.INFO = 2;
-Dygraph.WARNING = 3;
-Dygraph.ERROR = 3;
-
-// <REMOVE_FOR_COMBINED>
-// 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;
-// </REMOVE_FOR_COMBINED>
-
/** A dotted line stroke pattern. */
Dygraph.DOTTED_LINE = [2, 2];
/** A dashed line stroke pattern. */
Dygraph.DOT_DASH_LINE = [7, 2, 2, 2];
/**
- * Log an error on the JS console at the given severity.
- * @param {number} severity One of Dygraph.{DEBUG,INFO,WARNING,ERROR}
- * @param {string} message The message to log.
- * @private
- */
-Dygraph.log = function(severity, message) {
- // <REMOVE_FOR_COMBINED>
- var st;
- if (typeof(printStackTrace) != 'undefined') {
- try {
- // Remove uninteresting bits: logging functions and paths.
- 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(/^.*@ ?/, '') + ')';
- } catch(e) {
- // Oh well, it was worth a shot!
- }
- }
- // </REMOVE_FOR_COMBINED>
-
- if (typeof(window.console) != 'undefined') {
- // In older versions of Firefox, only console.log is defined.
- var console = window.console;
- var log = function(console, method, msg) {
- if (method && typeof(method) == 'function') {
- method.call(console, msg);
- } else {
- console.log(msg);
- }
- };
-
- switch (severity) {
- case Dygraph.DEBUG:
- log(console, console.debug, 'dygraphs: ' + message);
- break;
- case Dygraph.INFO:
- log(console, console.info, 'dygraphs: ' + message);
- break;
- case Dygraph.WARNING:
- log(console, console.warn, 'dygraphs: ' + message);
- break;
- case Dygraph.ERROR:
- log(console, console.error, 'dygraphs: ' + message);
- break;
- }
- }
-
- // <REMOVE_FOR_COMBINED>
- if (Dygraph.LOG_STACK_TRACES) {
- window.console.log(st.join('\n'));
- }
- // </REMOVE_FOR_COMBINED>
-};
-
-/**
- * @param {string} message
- * @private
- */
-Dygraph.info = function(message) {
- Dygraph.log(Dygraph.INFO, message);
-};
-
-/**
- * @param {string} message
- * @private
- */
-Dygraph.warn = function(message) {
- Dygraph.log(Dygraph.WARNING, message);
-};
-
-/**
- * @param {string} message
- */
-Dygraph.error = function(message) {
- Dygraph.log(Dygraph.ERROR, message);
-};
-
-/**
* Return the 2d context for a dygraph canvas.
*
* This method is only exposed for the sake of replacing the function in
};
/**
+ * Date accessors to get the parts of a calendar date (year, month,
+ * day, hour, minute, second and millisecond) according to local time,
+ * and factory method to call the Date constructor with an array of arguments.
+ */
+Dygraph.DateAccessorsLocal = {
+ getFullYear: function(d) {return d.getFullYear();},
+ getMonth: function(d) {return d.getMonth();},
+ getDate: function(d) {return d.getDate();},
+ getHours: function(d) {return d.getHours();},
+ getMinutes: function(d) {return d.getMinutes();},
+ getSeconds: function(d) {return d.getSeconds();},
+ getMilliseconds: function(d) {return d.getMilliseconds();},
+ getDay: function(d) {return d.getDay();},
+ makeDate: function(y, m, d, hh, mm, ss, ms) {
+ return new Date(y, m, d, hh, mm, ss, ms);
+ }
+};
+
+/**
+ * Date accessors to get the parts of a calendar date (year, month,
+ * day of month, hour, minute, second and millisecond) according to UTC time,
+ * and factory method to call the Date constructor with an array of arguments.
+ */
+Dygraph.DateAccessorsUTC = {
+ getFullYear: function(d) {return d.getUTCFullYear();},
+ getMonth: function(d) {return d.getUTCMonth();},
+ getDate: function(d) {return d.getUTCDate();},
+ getHours: function(d) {return d.getUTCHours();},
+ getMinutes: function(d) {return d.getUTCMinutes();},
+ getSeconds: function(d) {return d.getUTCSeconds();},
+ getMilliseconds: function(d) {return d.getUTCMilliseconds();},
+ getDay: function(d) {return d.getUTCDay();},
+ makeDate: function(y, m, d, hh, mm, ss, ms) {
+ return new Date(Date.UTC(y, m, d, hh, mm, ss, ms));
+ }
+};
+
+/**
* Return a string version of the hours, minutes and seconds portion of a date.
- *
- * @param {number} date The JavaScript date (ms since epoch)
- * @return {string} A time of the form "HH:MM:SS"
+ * @param {number} hh The hours (from 0-23)
+ * @param {number} mm The minutes (from 0-59)
+ * @param {number} ss The seconds (from 0-59)
+ * @return {string} A time of the form "HH:MM" or "HH:MM:SS"
* @private
*/
-Dygraph.hmsString_ = function(date) {
+Dygraph.hmsString_ = function(hh, mm, ss) {
var zeropad = Dygraph.zeropad;
- var d = new Date(date);
- if (d.getSeconds()) {
- return zeropad(d.getHours()) + ":" +
- zeropad(d.getMinutes()) + ":" +
- zeropad(d.getSeconds());
- } else {
- return zeropad(d.getHours()) + ":" + zeropad(d.getMinutes());
+ var ret = zeropad(hh) + ":" + zeropad(mm);
+ if (ss) {
+ ret += ":" + zeropad(ss);
}
+ return ret;
};
/**
- * Convert a JS date (millis since epoch) to YYYY/MM/DD
- * @param {number} date The JavaScript date (ms since epoch)
- * @return {string} A date of the form "YYYY/MM/DD"
+ * Convert a JS date (millis since epoch) to a formatted string.
+ * @param {number} time The JavaScript time value (ms since epoch)
+ * @param {boolean} utc Wether output UTC or local time
+ * @return {string} A date of one of these forms:
+ * "YYYY/MM/DD", "YYYY/MM/DD HH:MM" or "YYYY/MM/DD HH:MM:SS"
* @private
*/
-Dygraph.dateString_ = function(date) {
+Dygraph.dateString_ = function(time, utc) {
var zeropad = Dygraph.zeropad;
- var d = new Date(date);
-
- // Get the year:
- var year = "" + d.getFullYear();
+ var accessors = utc ? Dygraph.DateAccessorsUTC : Dygraph.DateAccessorsLocal;
+ var date = new Date(time);
+ var y = accessors.getFullYear(date);
+ var m = accessors.getMonth(date);
+ var d = accessors.getDate(date);
+ var hh = accessors.getHours(date);
+ var mm = accessors.getMinutes(date);
+ var ss = accessors.getSeconds(date);
+ // Get a year string:
+ var year = "" + y;
// Get a 0 padded month string
- var month = zeropad(d.getMonth() + 1); //months are 0-offset, sigh
+ var month = zeropad(m + 1); //months are 0-offset, sigh
// Get a 0 padded day string
- var day = zeropad(d.getDate());
-
- var ret = "";
- var frac = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
- if (frac) ret = " " + Dygraph.hmsString_(date);
-
- return year + "/" + month + "/" + day + ret;
+ var day = zeropad(d);
+ var frac = hh * 3600 + mm * 60 + ss;
+ var ret = year + "/" + month + "/" + day;
+ if (frac) {
+ ret += " " + Dygraph.hmsString_(hh, mm, ss);
+ }
+ return ret;
};
/**
}
if (!d || isNaN(d)) {
- Dygraph.error("Couldn't parse " + dateStr + " as a date");
+ console.error("Couldn't parse " + dateStr + " as a date");
}
return d;
};
};
/**
+ * Returns the context's pixel ratio, which is the ratio between the device
+ * pixel ratio and the backing store ratio. Typically this is 1 for conventional
+ * displays, and > 1 for HiDPI displays (such as the Retina MBP).
+ * See http://www.html5rocks.com/en/tutorials/canvas/hidpi/ for more details.
+ *
+ * @param {!CanvasRenderingContext2D} context The canvas's 2d context.
+ * @return {number} The ratio of the device pixel ratio and the backing store
+ * ratio for the specified context.
+ */
+Dygraph.getContextPixelRatio = function(context) {
+ try {
+ var devicePixelRatio = window.devicePixelRatio;
+ var backingStoreRatio = context.webkitBackingStorePixelRatio ||
+ context.mozBackingStorePixelRatio ||
+ context.msBackingStorePixelRatio ||
+ context.oBackingStorePixelRatio ||
+ context.backingStorePixelRatio;
+ if (devicePixelRatio !== undefined &&
+ backingStorePixelRatio !== undefined) {
+ return devicePixelRatio / backingStoreRatio;
+ } else {
+ // If either value is undefined, the ratio is meaningless so we want to
+ // return 1.
+ return 1;
+ }
+ } catch (e) {
+ return 1;
+ }
+};
+
+/**
* Checks whether the user is on an Android browser.
* Android does not fully support the <canvas> tag, e.g. w/r/t/ clipping.
* @return {boolean}
var iframes = document.getElementsByTagName("iframe");
for (var i = 0; i < iframes.length; i++) {
var iframe = iframes[i];
- var x = Dygraph.findPosX(iframe),
- y = Dygraph.findPosY(iframe),
+ var pos = Dygraph.findPos(iframe),
+ x = pos.x,
+ y = pos.y,
width = iframe.offsetWidth,
height = iframe.offsetHeight;
return Math.pow(base, exp);
};
-// For Dygraph.setDateSameTZ, below.
-Dygraph.dateSetters = {
- ms: Date.prototype.setMilliseconds,
- s: Date.prototype.setSeconds,
- m: Date.prototype.setMinutes,
- h: Date.prototype.setHours
-};
-
-/**
- * This is like calling d.setSeconds(), d.setMinutes(), etc, except that it
- * adjusts for time zone changes to keep the date/time parts consistent.
- *
- * For example, d.getSeconds(), d.getMinutes() and d.getHours() will all be
- * the same before/after you call setDateSameTZ(d, {ms: 0}). The same is not
- * true if you call d.setMilliseconds(0).
- *
- * @type {function(!Date, Object.<number>)}
- */
-Dygraph.setDateSameTZ = function(d, parts) {
- var tz = d.getTimezoneOffset();
- for (var k in parts) {
- if (!parts.hasOwnProperty(k)) continue;
- var setter = Dygraph.dateSetters[k];
- if (!setter) throw "Invalid setter: " + k;
- setter.call(d, parts[k]);
- if (d.getTimezoneOffset() != tz) {
- d.setTime(d.getTime() + (tz - d.getTimezoneOffset()) * 60 * 1000);
- }
- }
-};
-
/**
* Converts any valid CSS color (hex, rgb(), named color) to an RGB tuple.
*
div.style.backgroundColor = colorStr;
div.style.visibility = 'hidden';
document.body.appendChild(div);
- var rgbStr = window.getComputedStyle(div).backgroundColor;
+ var rgbStr = window.getComputedStyle(div, null).backgroundColor;
document.body.removeChild(div);
var bits = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(rgbStr);
return {
if (opt_line !== undefined && opt_line_no !== undefined) {
msg += " on line " + (1+(opt_line_no||0)) + " ('" + opt_line + "') of CSV.";
}
- Dygraph.error(msg);
+ console.error(msg);
return null;
};