diff -r efd9c589177a -r c0b4a8b5a012 toolkit/javascript/d3/src/time/scale.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/javascript/d3/src/time/scale.js Thu Apr 10 14:20:23 2014 +0200 @@ -0,0 +1,123 @@ +// TODO nice +function d3_time_scale(linear, methods, format) { + + function scale(x) { + return linear(x); + } + + scale.invert = function(x) { + return d3_time_scaleDate(linear.invert(x)); + }; + + scale.domain = function(x) { + if (!arguments.length) return linear.domain().map(d3_time_scaleDate); + linear.domain(x); + return scale; + }; + + scale.ticks = function(m, k) { + var extent = d3_time_scaleExtent(scale.domain()); + if (typeof m !== "function") { + var span = extent[1] - extent[0], + target = span / m, + i = d3.bisect(d3_time_scaleSteps, target, 1, d3_time_scaleSteps.length - 1); + if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i; + m = methods[i]; + k = m[1]; + m = m[0]; + } + return m(extent[0], extent[1], k); + }; + + scale.tickFormat = function() { + return format; + }; + + scale.copy = function() { + return d3_time_scale(linear.copy(), methods, format); + }; + + // TOOD expose d3_scale_linear_rebind? + scale.range = d3.rebind(scale, linear.range); + scale.rangeRound = d3.rebind(scale, linear.rangeRound); + scale.interpolate = d3.rebind(scale, linear.interpolate); + scale.clamp = d3.rebind(scale, linear.clamp); + + return scale; +} + +// TODO expose d3_scaleExtent? +function d3_time_scaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; +} + +function d3_time_scaleDate(t) { + return new Date(t); +} + +function d3_time_scaleFormat(formats) { + return function(date) { + var i = formats.length - 1, f = formats[i]; + while (!f[1](date)) f = formats[--i]; + return f[0](date); + }; +} + +var d3_time_scaleSteps = [ + 1e3, // 1-second + 5e3, // 5-second + 15e3, // 15-second + 3e4, // 30-second + 6e4, // 1-minute + 3e5, // 5-minute + 9e5, // 15-minute + 18e5, // 30-minute + 36e5, // 1-hour + 108e5, // 3-hour + 216e5, // 6-hour + 432e5, // 12-hour + 864e5, // 1-day + 1728e5, // 2-day + 6048e5, // 1-week + 1728e6, // 1-month + 7776e6, // 3-month + 31536e6 // 1-year +]; + +var d3_time_scaleLocalMethods = [ + [d3.time.seconds, 1], + [d3.time.seconds, 5], + [d3.time.seconds, 15], + [d3.time.seconds, 30], + [d3.time.minutes, 1], + [d3.time.minutes, 5], + [d3.time.minutes, 15], + [d3.time.minutes, 30], + [d3.time.hours, 1], + [d3.time.hours, 3], + [d3.time.hours, 6], + [d3.time.hours, 12], + [d3.time.days, 1], + [d3.time.days, 2], + [d3.time.weeks, 1], + [d3.time.months, 1], + [d3.time.months, 3], + [d3.time.years, 1] +]; + +var d3_time_scaleLocalFormats = [ + [d3.time.format("%Y"), function(d) { return true; }], + [d3.time.format("%B"), function(d) { return d.getMonth(); }], + [d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }], + [d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }], + [d3.time.format("%I %p"), function(d) { return d.getHours(); }], + [d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }], + [d3.time.format(":%S"), function(d) { return d.getSeconds() || d.getMilliseconds(); }] +]; + +var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); + +d3.time.scale = function() { + return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); +};