Commit 6a02cab9 authored by David Schnur's avatar David Schnur

Cleaned up tabs and whitespace.

parent 0945a1cb
...@@ -4,306 +4,338 @@ Pretty handling of time axes. ...@@ -4,306 +4,338 @@ Pretty handling of time axes.
Set axis.mode to "time" to enable. See the section "Time series data" in API.txt Set axis.mode to "time" to enable. See the section "Time series data" in API.txt
for details. for details.
*/ */
(function ($) { (function ($) {
var options = {};
var options = {};
// round to nearby lower multiple of base
function floorInBase(n, base) { // round to nearby lower multiple of base
return base * Math.floor(n / base);
} function floorInBase(n, base) {
return base * Math.floor(n / base);
// Returns a string with the date d formatted according to fmt. }
// A subset of the Open Group's strftime format is supported.
function formatDate(d, fmt, monthNames, dayNames) { // Returns a string with the date d formatted according to fmt.
if (typeof d.strftime == "function") { // A subset of the Open Group's strftime format is supported.
return d.strftime(fmt);
} function formatDate(d, fmt, monthNames, dayNames) {
var leftPad = function(n, pad) {
n = "" + n; if (typeof d.strftime == "function") {
pad = "" + (pad == null ? "0" : pad); return d.strftime(fmt);
return n.length == 1 ? pad + n : n; }
};
var leftPad = function(n, pad) {
var r = []; n = "" + n;
var escape = false; pad = "" + (pad == null ? "0" : pad);
var hours = d.getHours(); return n.length == 1 ? pad + n : n;
var isAM = hours < 12; };
if (monthNames == null)
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; var r = [];
if (dayNames == null) var escape = false;
dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; var hours = d.getHours();
var isAM = hours < 12;
var hours12;
if (hours > 12) { if (monthNames == null)
hours12 = hours - 12; monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
} else if (hours == 0) { if (dayNames == null)
hours12 = 12; dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
} else {
hours12 = hours; var hours12;
}
if (hours > 12) {
for (var i = 0; i < fmt.length; ++i) { hours12 = hours - 12;
var c = fmt.charAt(i); } else if (hours == 0) {
hours12 = 12;
if (escape) { } else {
switch (c) { hours12 = hours;
case 'a': c = "" + dayNames[d.getDay()]; break; }
case 'b': c = "" + monthNames[d.getMonth()]; break;
case 'd': c = leftPad(d.getDate()); break; for (var i = 0; i < fmt.length; ++i) {
case 'e': c = leftPad(d.getDate(), " "); break;
case 'H': c = leftPad(hours); break; var c = fmt.charAt(i);
case 'I': c = leftPad(hours12); break;
case 'l': c = leftPad(hours12, " "); break; if (escape) {
case 'm': c = leftPad(d.getMonth() + 1); break; switch (c) {
case 'M': c = leftPad(d.getMinutes()); break; case 'a': c = "" + dayNames[d.getDay()]; break;
case 'S': c = leftPad(d.getSeconds()); break; case 'b': c = "" + monthNames[d.getMonth()]; break;
case 'y': c = leftPad(d.getFullYear() % 100); break; case 'd': c = leftPad(d.getDate()); break;
case 'Y': c = "" + d.getFullYear(); break; case 'e': c = leftPad(d.getDate(), " "); break;
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; case 'H': c = leftPad(hours); break;
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; case 'I': c = leftPad(hours12); break;
case 'w': c = "" + d.getDay(); break; case 'l': c = leftPad(hours12, " "); break;
} case 'm': c = leftPad(d.getMonth() + 1); break;
r.push(c); case 'M': c = leftPad(d.getMinutes()); break;
escape = false; case 'S': c = leftPad(d.getSeconds()); break;
} case 'y': c = leftPad(d.getFullYear() % 100); break;
else { case 'Y': c = "" + d.getFullYear(); break;
if (c == "%") case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
escape = true; case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
else case 'w': c = "" + d.getDay(); break;
r.push(c); }
} r.push(c);
} escape = false;
return r.join(""); } else {
} if (c == "%")
escape = true;
// To have a consistent view of time-based data independent of which time else
// zone the client happens to be in we need a date-like object independent r.push(c);
// of time zones. This is done through a wrapper that only calls the UTC }
// versions of the accessor methods. }
function makeUtcWrapper(d) {
function addProxyMethod(sourceObj, sourceMethod, targetObj, return r.join("");
targetMethod) { }
sourceObj[sourceMethod] = function() {
return targetObj[targetMethod].apply(targetObj, arguments); // To have a consistent view of time-based data independent of which time
}; // zone the client happens to be in we need a date-like object independent
}; // of time zones. This is done through a wrapper that only calls the UTC
var utc = { // versions of the accessor methods.
date: d
}; function makeUtcWrapper(d) {
// support strftime, if found
if (d.strftime != undefined) function addProxyMethod(sourceObj, sourceMethod, targetObj,
addProxyMethod(utc, "strftime", d, "strftime"); targetMethod) {
addProxyMethod(utc, "getTime", d, "getTime"); sourceObj[sourceMethod] = function() {
addProxyMethod(utc, "setTime", d, "setTime"); return targetObj[targetMethod].apply(targetObj, arguments);
var props = [ "Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds" ]; };
for (var p = 0; p < props.length; p++) { };
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); var utc = {
} date: d
return utc; };
};
// support strftime, if found
// select time zone strategy. This returns a date-like object tied to the
// desired timezone if (d.strftime != undefined)
function dateGenerator(ts, opts) { addProxyMethod(utc, "strftime", d, "strftime");
if (opts.timezone == "browser") {
return new Date(ts); addProxyMethod(utc, "getTime", d, "getTime");
} else if (!opts.timezone || opts.timezone == "utc") { addProxyMethod(utc, "setTime", d, "setTime");
return makeUtcWrapper(new Date(ts));
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { var props = [ "Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds" ];
var d = new timezoneJS.Date();
// timezone-js is fickle, so be sure to set the time zone before for (var p = 0; p < props.length; p++) {
// setting the time. addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
d.setTimezone(opts.timezone); addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
d.setTime(ts); }
return d;
} else { return utc;
return makeUtcWrapper(new Date(ts)); };
}
} // select time zone strategy. This returns a date-like object tied to the
// desired timezone
// map of app. size of time units in milliseconds
var timeUnitSize = { function dateGenerator(ts, opts) {
"second": 1000, if (opts.timezone == "browser") {
"minute": 60 * 1000, return new Date(ts);
"hour": 60 * 60 * 1000, } else if (!opts.timezone || opts.timezone == "utc") {
"day": 24 * 60 * 60 * 1000, return makeUtcWrapper(new Date(ts));
"month": 30 * 24 * 60 * 60 * 1000, } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
"year": 365.2425 * 24 * 60 * 60 * 1000 var d = new timezoneJS.Date();
}; // timezone-js is fickle, so be sure to set the time zone before
// setting the time.
// the allowed tick sizes, after 1 year we use d.setTimezone(opts.timezone);
// an integer algorithm d.setTime(ts);
var spec = [ return d;
[1, "second"], [2, "second"], [5, "second"], [10, "second"], } else {
[30, "second"], return makeUtcWrapper(new Date(ts));
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], }
[30, "minute"], }
[1, "hour"], [2, "hour"], [4, "hour"],
[8, "hour"], [12, "hour"], // map of app. size of time units in milliseconds
[1, "day"], [2, "day"], [3, "day"],
[0.25, "month"], [0.5, "month"], [1, "month"], var timeUnitSize = {
[2, "month"], [3, "month"], [6, "month"], "second": 1000,
[1, "year"] "minute": 60 * 1000,
]; "hour": 60 * 60 * 1000,
"day": 24 * 60 * 60 * 1000,
function init(plot) { "month": 30 * 24 * 60 * 60 * 1000,
plot.hooks.processDatapoints.push(function (plot, series, datapoints) { "year": 365.2425 * 24 * 60 * 60 * 1000
$.each(plot.getAxes(), function(axisName, axis) { };
var opts = axis.options;
if (opts.mode == "time") { // the allowed tick sizes, after 1 year we use
axis.tickGenerator = function(axis) { // an integer algorithm
var ticks = [],
d = dateGenerator(axis.min, opts), var spec = [
minSize = 0; [1, "second"], [2, "second"], [5, "second"], [10, "second"],
[30, "second"],
if (opts.minTickSize != null) { [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
if (typeof opts.tickSize == "number") [30, "minute"],
minSize = opts.tickSize; [1, "hour"], [2, "hour"], [4, "hour"],
else [8, "hour"], [12, "hour"],
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; [1, "day"], [2, "day"], [3, "day"],
} [0.25, "month"], [0.5, "month"], [1, "month"],
[2, "month"], [3, "month"], [6, "month"],
for (var i = 0; i < spec.length - 1; ++i) [1, "year"]
if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] ];
+ spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) function init(plot) {
break; plot.hooks.processDatapoints.push(function (plot, series, datapoints) {
var size = spec[i][0]; $.each(plot.getAxes(), function(axisName, axis) {
var unit = spec[i][1];
var opts = axis.options;
// special-case the possibility of several years
if (unit == "year") { if (opts.mode == "time") {
// if given a minTickSize in years, just use it, axis.tickGenerator = function(axis) {
// ensuring that it's an integer var ticks = [],
if (opts.minTickSize != null && opts.minTickSize[1] == "year") { d = dateGenerator(axis.min, opts),
size = Math.floor(opts.minTickSize[0]); minSize = 0;
} else {
var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); if (opts.minTickSize != null) {
var norm = (axis.delta / timeUnitSize.year) / magn; if (typeof opts.tickSize == "number")
if (norm < 1.5) minSize = opts.tickSize;
size = 1; else
else if (norm < 3) minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
size = 2; }
else if (norm < 7.5)
size = 5; for (var i = 0; i < spec.length - 1; ++i)
else if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
size = 10; + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
size *= magn; break;
}
var size = spec[i][0];
// minimum size for years is 1 var unit = spec[i][1];
if (size < 1)
size = 1; // special-case the possibility of several years
}
if (unit == "year") {
axis.tickSize = opts.tickSize || [size, unit];
var tickSize = axis.tickSize[0]; // if given a minTickSize in years, just use it,
unit = axis.tickSize[1]; // ensuring that it's an integer
var step = tickSize * timeUnitSize[unit]; if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
size = Math.floor(opts.minTickSize[0]);
if (unit == "second") } else {
d.setSeconds(floorInBase(d.getSeconds(), tickSize)); var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
if (unit == "minute") var norm = (axis.delta / timeUnitSize.year) / magn;
d.setMinutes(floorInBase(d.getMinutes(), tickSize)); if (norm < 1.5)
if (unit == "hour") size = 1;
d.setHours(floorInBase(d.getHours(), tickSize)); else if (norm < 3)
if (unit == "month") size = 2;
d.setMonth(floorInBase(d.getMonth(), tickSize)); else if (norm < 7.5)
if (unit == "year") size = 5;
d.setFullYear(floorInBase(d.getFullYear(), tickSize)); else
size = 10;
// reset smaller components
d.setMilliseconds(0); size *= magn;
if (step >= timeUnitSize.minute) }
d.setSeconds(0);
if (step >= timeUnitSize.hour) // minimum size for years is 1
d.setMinutes(0); if (size < 1)
if (step >= timeUnitSize.day) size = 1;
d.setHours(0); }
if (step >= timeUnitSize.day * 4)
d.setDate(1); axis.tickSize = opts.tickSize || [size, unit];
if (step >= timeUnitSize.year) var tickSize = axis.tickSize[0];
d.setMonth(0); unit = axis.tickSize[1];
var step = tickSize * timeUnitSize[unit];
var carry = 0, v = Number.NaN, prev;
do { if (unit == "second")
prev = v; d.setSeconds(floorInBase(d.getSeconds(), tickSize));
v = d.getTime(); if (unit == "minute")
ticks.push(v); d.setMinutes(floorInBase(d.getMinutes(), tickSize));
if (unit == "month") { if (unit == "hour")
if (tickSize < 1) { d.setHours(floorInBase(d.getHours(), tickSize));
// a bit complicated - we'll divide the month if (unit == "month")
// up but we need to take care of fractions d.setMonth(floorInBase(d.getMonth(), tickSize));
// so we don't end up in the middle of a day if (unit == "year")
d.setDate(1); d.setFullYear(floorInBase(d.getFullYear(), tickSize));
var start = d.getTime();
d.setMonth(d.getMonth() + 1); // reset smaller components
var end = d.getTime();
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); d.setMilliseconds(0);
carry = d.getHours();
d.setHours(0); if (step >= timeUnitSize.minute)
} d.setSeconds(0);
else if (step >= timeUnitSize.hour)
d.setMonth(d.getMonth() + tickSize); d.setMinutes(0);
} if (step >= timeUnitSize.day)
else if (unit == "year") { d.setHours(0);
d.setFullYear(d.getFullYear() + tickSize); if (step >= timeUnitSize.day * 4)
} d.setDate(1);
else if (step >= timeUnitSize.year)
d.setTime(v + step); d.setMonth(0);
} while (v < axis.max && v != prev);
var carry = 0, v = Number.NaN, prev;
return ticks;
}; do {
prev = v;
axis.tickFormatter = function (v, axis) { v = d.getTime();
var d = dateGenerator(v, axis.options); ticks.push(v);
if (unit == "month") {
// first check global format if (tickSize < 1) {
if (opts.timeformat != null) // a bit complicated - we'll divide the month
return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); // up but we need to take care of fractions
// so we don't end up in the middle of a day
var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; d.setDate(1);
var span = axis.max - axis.min; var start = d.getTime();
var suffix = (opts.twelveHourClock) ? " %p" : ""; d.setMonth(d.getMonth() + 1);
var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; var end = d.getTime();
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
var fmt; carry = d.getHours();
if (t < timeUnitSize.minute) d.setHours(0);
fmt = hourCode + ":%M:%S" + suffix; }
else if (t < timeUnitSize.day) { else
if (span < 2 * timeUnitSize.day) d.setMonth(d.getMonth() + tickSize);
fmt = hourCode + ":%M" + suffix; }
else else if (unit == "year") {
fmt = "%b %d " + hourCode + ":%M" + suffix; d.setFullYear(d.getFullYear() + tickSize);
} }
else if (t < timeUnitSize.month) else
fmt = "%b %d"; d.setTime(v + step);
else if (t < timeUnitSize.year) { } while (v < axis.max && v != prev);
if (span < timeUnitSize.year)
fmt = "%b"; return ticks;
else };
fmt = "%b %Y";
} axis.tickFormatter = function (v, axis) {
else var d = dateGenerator(v, axis.options);
fmt = "%Y";
// first check global format
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); if (opts.timeformat != null)
return rt; return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
};
} var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
}); var span = axis.max - axis.min;
}); var suffix = (opts.twelveHourClock) ? " %p" : "";
} var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
$.plot.plugins.push({ var fmt;
init: init,
options: options, if (t < timeUnitSize.minute)
name: 'time', fmt = hourCode + ":%M:%S" + suffix;
version: '1.0' else if (t < timeUnitSize.day) {
}); if (span < 2 * timeUnitSize.day)
fmt = hourCode + ":%M" + suffix;
else
fmt = "%b %d " + hourCode + ":%M" + suffix;
}
else if (t < timeUnitSize.month)
fmt = "%b %d";
else if (t < timeUnitSize.year) {
if (span < timeUnitSize.year)
fmt = "%b";
else
fmt = "%b %Y";
}
else
fmt = "%Y";
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
return rt;
};
}
});
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'time',
version: '1.0'
});
})(jQuery); })(jQuery);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment