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 | }; |
---|