[76] | 1 | // TODO nice |
---|
| 2 | function d3_time_scale(methods, format) { |
---|
| 3 | var linear = d3.scale.linear(); |
---|
| 4 | |
---|
| 5 | function scale(x) { |
---|
| 6 | return linear(x); |
---|
| 7 | } |
---|
| 8 | |
---|
| 9 | scale.invert = function(x) { |
---|
| 10 | return d3_time_scaleDate(linear.invert(x)); |
---|
| 11 | }; |
---|
| 12 | |
---|
| 13 | scale.domain = function(x) { |
---|
| 14 | if (!arguments.length) return linear.domain().map(d3_time_scaleDate); |
---|
| 15 | linear.domain(x); |
---|
| 16 | return scale; |
---|
| 17 | }; |
---|
| 18 | |
---|
| 19 | scale.ticks = function(m, k) { |
---|
| 20 | var extent = d3_time_scaleExtent(scale.domain()); |
---|
| 21 | if (typeof m !== "function") { |
---|
| 22 | var span = extent[1] - extent[0], |
---|
| 23 | target = span / m, |
---|
| 24 | i = d3.bisect(d3_time_scaleSteps, target, 1, d3_time_scaleSteps.length - 1); |
---|
| 25 | if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i; |
---|
| 26 | m = methods[i]; |
---|
| 27 | k = m[1]; |
---|
| 28 | m = m[0]; |
---|
| 29 | } |
---|
| 30 | return m(extent[0], extent[1], k); |
---|
| 31 | }; |
---|
| 32 | |
---|
| 33 | scale.tickFormat = function() { |
---|
| 34 | return format; |
---|
| 35 | }; |
---|
| 36 | |
---|
| 37 | // TOOD expose d3_scale_linear_rebind? |
---|
| 38 | scale.range = d3.rebind(scale, linear.range); |
---|
| 39 | scale.rangeRound = d3.rebind(scale, linear.rangeRound); |
---|
| 40 | scale.interpolate = d3.rebind(scale, linear.interpolate); |
---|
| 41 | scale.clamp = d3.rebind(scale, linear.clamp); |
---|
| 42 | |
---|
| 43 | return scale; |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | // TODO expose d3_scaleExtent? |
---|
| 47 | function d3_time_scaleExtent(domain) { |
---|
| 48 | var start = domain[0], stop = domain[domain.length - 1]; |
---|
| 49 | return start < stop ? [start, stop] : [stop, start]; |
---|
| 50 | } |
---|
| 51 | |
---|
| 52 | function d3_time_scaleDate(t) { |
---|
| 53 | return new Date(t); |
---|
| 54 | } |
---|
| 55 | |
---|
| 56 | function d3_time_scaleFormat(formats) { |
---|
| 57 | return function(date) { |
---|
| 58 | var i = formats.length - 1, f = formats[i]; |
---|
| 59 | while (!f[1](date)) f = formats[--i]; |
---|
| 60 | return f[0](date); |
---|
| 61 | }; |
---|
| 62 | } |
---|
| 63 | |
---|
| 64 | var d3_time_scaleSteps = [ |
---|
| 65 | 1e3, // 1-second |
---|
| 66 | 5e3, // 5-second |
---|
| 67 | 15e3, // 15-second |
---|
| 68 | 3e4, // 30-second |
---|
| 69 | 6e4, // 1-minute |
---|
| 70 | 3e5, // 5-minute |
---|
| 71 | 9e5, // 15-minute |
---|
| 72 | 18e5, // 30-minute |
---|
| 73 | 36e5, // 1-hour |
---|
| 74 | 108e5, // 3-hour |
---|
| 75 | 216e5, // 6-hour |
---|
| 76 | 432e5, // 12-hour |
---|
| 77 | 864e5, // 1-day |
---|
| 78 | 1728e5, // 2-day |
---|
| 79 | 6048e5, // 1-week |
---|
| 80 | 1728e6, // 1-month |
---|
| 81 | 7776e6, // 3-month |
---|
| 82 | 31536e6 // 1-year |
---|
| 83 | ]; |
---|
| 84 | |
---|
| 85 | var d3_time_scaleLocalMethods = [ |
---|
| 86 | [d3.time.seconds, 1], |
---|
| 87 | [d3.time.seconds, 5], |
---|
| 88 | [d3.time.seconds, 15], |
---|
| 89 | [d3.time.seconds, 30], |
---|
| 90 | [d3.time.minutes, 1], |
---|
| 91 | [d3.time.minutes, 5], |
---|
| 92 | [d3.time.minutes, 15], |
---|
| 93 | [d3.time.minutes, 30], |
---|
| 94 | [d3.time.hours, 1], |
---|
| 95 | [d3.time.hours, 3], |
---|
| 96 | [d3.time.hours, 6], |
---|
| 97 | [d3.time.hours, 12], |
---|
| 98 | [d3.time.days, 1], |
---|
| 99 | [d3.time.days, 2], |
---|
| 100 | [d3.time.weeks, 1], |
---|
| 101 | [d3.time.months, 1], |
---|
| 102 | [d3.time.months, 3], |
---|
| 103 | [d3.time.years, 1] |
---|
| 104 | ]; |
---|
| 105 | |
---|
| 106 | var d3_time_scaleLocalFormats = [ |
---|
| 107 | [d3.time.format("%Y"), function(d) { return true; }], |
---|
| 108 | [d3.time.format("%B"), function(d) { return d.getMonth(); }], |
---|
| 109 | [d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }], |
---|
| 110 | [d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }], |
---|
| 111 | [d3.time.format("%I %p"), function(d) { return d.getHours(); }], |
---|
| 112 | [d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }], |
---|
| 113 | [d3.time.format(":%S"), function(d) { return d.getSeconds() || d.getMilliseconds(); }] |
---|
| 114 | ]; |
---|
| 115 | |
---|
| 116 | var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); |
---|
| 117 | |
---|
| 118 | d3.time.scale = function() { |
---|
| 119 | return d3_time_scale(d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); |
---|
| 120 | }; |
---|