Skip to content

Commit e2187aa

Browse files
committed
Add d3.time.scale.
1 parent e37031a commit e2187aa

8 files changed

Lines changed: 866 additions & 3 deletions

File tree

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ d3.time.js: \
171171
src/time/months.js \
172172
src/time/year.js \
173173
src/time/years.js \
174+
src/time/scale.js \
174175
src/end.js
175176

176177
d3.geom.js: \
@@ -230,6 +231,7 @@ test: \
230231
test/time/test-parse-iso.test \
231232
test/time/test-parse-utc.test \
232233
test/time/test-parse.test \
234+
test/time/test-scale.test \
233235
test/time/test-second.test \
234236
test/time/test-seconds.test \
235237
test/time/test-week.test \

d3.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2280,7 +2280,7 @@ function d3_scale_linearRebind(scale, linear) {
22802280
scale.interpolate = d3.rebind(scale, linear.interpolate);
22812281
scale.clamp = d3.rebind(scale, linear.clamp);
22822282
return scale;
2283-
};
2283+
}
22842284

22852285
function d3_scale_linearNice(dx) {
22862286
dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);

d3.time.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,117 @@ d3.time.years = d3_time_range(d3.time.year, function(date) {
462462
d3.time.years.utc = d3_time_range(d3.time.year.utc, function(date) {
463463
date.setUTCFullYear(date.getUTCFullYear() + 1);
464464
});
465+
// TODO nice
466+
d3.time.scale = function() {
467+
var linear = d3.scale.linear();
468+
469+
function scale(x) {
470+
return linear(x);
471+
}
472+
473+
scale.invert = function(x) {
474+
return d3_scale_time(linear.invert(x));
475+
};
476+
477+
scale.domain = function(x) {
478+
if (!arguments.length) return linear.domain().map(d3_scale_time);
479+
linear.domain(x);
480+
return scale;
481+
};
482+
483+
scale.ticks = function(m) {
484+
var extent = d3_scale_timeExtent(scale.domain()),
485+
span = extent[1] - extent[0],
486+
target = span / m;
487+
i = d3.bisect(d3_scale_timeSteps, target, 1, d3_scale_timeSteps.length - 1);
488+
if (Math.log(target / d3_scale_timeSteps[i - 1]) < Math.log(d3_scale_timeSteps[i] / target)) --i;
489+
return d3_scale_timeMethods[i](extent[0], extent[1]);
490+
};
491+
492+
scale.tickFormat = function() {
493+
return d3_scale_timeFormat;
494+
};
495+
496+
// TOOD expose d3_scale_linear_rebind?
497+
scale.range = d3.rebind(scale, linear.range);
498+
scale.rangeRound = d3.rebind(scale, linear.rangeRound);
499+
scale.interpolate = d3.rebind(scale, linear.interpolate);
500+
scale.clamp = d3.rebind(scale, linear.clamp);
501+
502+
return scale;
503+
};
504+
505+
// TODO expose d3_scaleExtent?
506+
function d3_scale_timeExtent(domain) {
507+
var start = domain[0], stop = domain[domain.length - 1];
508+
return start < stop ? [start, stop] : [stop, start];
509+
}
510+
511+
function d3_scale_time(t) {
512+
return new Date(t);
513+
}
514+
515+
var d3_scale_timeFormats = [
516+
[d3.time.format("%Y"), function(d) { return true; }],
517+
[d3.time.format("%B"), function(d) { return d.getMonth(); }],
518+
[d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
519+
[d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
520+
[d3.time.format("%I %p"), function(d) { return d.getHours(); }],
521+
[d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }],
522+
[d3.time.format(":%S"), function(d) { return d.getSeconds() || d.getMilliseconds(); }]
523+
];
524+
525+
var d3_scale_timeFormat = function(date) {
526+
var i = d3_scale_timeFormats.length - 1, f = d3_scale_timeFormats[i];
527+
while (!f[1](date)) f = d3_scale_timeFormats[--i];
528+
return f[0](date);
529+
};
530+
531+
var d3_scale_timeSteps = [
532+
1e3, // 1-second
533+
5e3, // 5-second
534+
15e3, // 15-second
535+
3e4, // 30-second
536+
6e4, // 1-minute
537+
3e5, // 5-minute
538+
9e5, // 15-minute
539+
18e5, // 30-minute
540+
36e5, // 1-hour
541+
108e5, // 3-hour
542+
216e5, // 6-hour
543+
432e5, // 12-hour
544+
864e5, // 1-day
545+
1728e5, // 2-day
546+
6048e5, // 1-week
547+
1728e6, // 1-month
548+
7776e6, // 3-month
549+
31536e6 // 1-year
550+
];
551+
552+
var d3_scale_timeMethods = [
553+
d3.time.seconds,
554+
function(a, b) { return d3.time.seconds(a, b).filter(function(t) { return !(t.getSeconds() % 5); }); },
555+
function(a, b) { return d3.time.seconds(a, b).filter(function(t) { return !(t.getSeconds() % 15); }); },
556+
function(a, b) { return d3.time.seconds(a, b).filter(function(t) { return !(t.getSeconds() % 30); }); },
557+
d3.time.minutes,
558+
function(a, b) { return d3.time.minutes(a, b).filter(function(t) { return !(t.getMinutes() % 5); }); },
559+
function(a, b) { return d3.time.minutes(a, b).filter(function(t) { return !(t.getMinutes() % 15); }); },
560+
function(a, b) { return d3.time.minutes(a, b).filter(function(t) { return !(t.getMinutes() % 30); }); },
561+
d3.time.hours,
562+
function(a, b) { return d3.time.hours(a, b).filter(function(t) { return !(t.getHours() % 3); }); },
563+
function(a, b) { return d3.time.hours(a, b).filter(function(t) { return !(t.getHours() % 6); }); },
564+
function(a, b) { return d3.time.hours(a, b).filter(function(t) { return !(t.getHours() % 12); }); },
565+
d3.time.days,
566+
function(a, b) { return d3.time.days(a, b).filter(function(t) { return t.getDate() % 2; }); },
567+
d3.time.weeks,
568+
d3.time.months,
569+
function(a, b) { return d3.time.months(a, b).filter(function(t) { return !(t.getMonth() % 3); }); },
570+
d3.time.years
571+
];
572+
573+
function d3_scale_timeFilter(method, filter) {
574+
return function(a, b) {
575+
return method(a, b).filter(filter);
576+
};
577+
}
465578
})();

d3.time.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/scale/linear.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function d3_scale_linearRebind(scale, linear) {
7373
scale.interpolate = d3.rebind(scale, linear.interpolate);
7474
scale.clamp = d3.rebind(scale, linear.clamp);
7575
return scale;
76-
};
76+
}
7777

7878
function d3_scale_linearNice(dx) {
7979
dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);

src/time/scale.js

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

0 commit comments

Comments
 (0)