Skip to content

Commit 7133162

Browse files
committed
Fix nice implementation for time scales.
The previous implementation didn't handle polylinear domains correctly.
1 parent 108d65d commit 7133162

8 files changed

Lines changed: 40 additions & 24 deletions

File tree

d3.v2.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,15 +2104,10 @@
21042104
function d3_scale_nice(domain, nice) {
21052105
var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
21062106
if (x1 < x0) {
2107-
dx = i0;
2108-
i0 = i1;
2109-
i1 = dx;
2110-
dx = x0;
2111-
x0 = x1;
2112-
x1 = dx;
2113-
}
2114-
if (dx = x1 - x0) {
2115-
nice = nice(dx);
2107+
dx = i0, i0 = i1, i1 = dx;
2108+
dx = x0, x0 = x1, x1 = dx;
2109+
}
2110+
if (nice = nice(x1 - x0)) {
21162111
domain[i0] = nice.floor(x0);
21172112
domain[i1] = nice.ceil(x1);
21182113
}
@@ -2181,7 +2176,7 @@
21812176
}
21822177
function d3_scale_linearNice(dx) {
21832178
dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
2184-
return {
2179+
return dx && {
21852180
floor: function(x) {
21862181
return Math.floor(x / dx) * dx;
21872182
},
@@ -6784,8 +6779,9 @@
67846779
return scale;
67856780
};
67866781
scale.nice = function(m) {
6787-
var extent = d3_time_scaleExtent(scale.domain());
6788-
return scale.domain([ m.floor(extent[0]), m.ceil(extent[1]) ]);
6782+
return scale.domain(d3_scale_nice(scale.domain(), function() {
6783+
return m;
6784+
}));
67896785
};
67906786
scale.ticks = function(m, k) {
67916787
var extent = d3_time_scaleExtent(scale.domain());

d3.v2.min.js

Lines changed: 4 additions & 4 deletions
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
@@ -77,7 +77,7 @@ function d3_scale_linearRebind(scale, linear) {
7777

7878
function d3_scale_linearNice(dx) {
7979
dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
80-
return {
80+
return dx && {
8181
floor: function(x) { return Math.floor(x / dx) * dx; },
8282
ceil: function(x) { return Math.ceil(x / dx) * dx; }
8383
};

src/scale/nice.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ function d3_scale_nice(domain, nice) {
66
dx;
77

88
if (x1 < x0) {
9-
dx = i0; i0 = i1; i1 = dx;
10-
dx = x0; x0 = x1; x1 = dx;
9+
dx = i0, i0 = i1, i1 = dx;
10+
dx = x0, x0 = x1, x1 = dx;
1111
}
1212

13-
if (dx = x1 - x0) {
14-
nice = nice(dx);
13+
if (nice = nice(x1 - x0)) {
1514
domain[i0] = nice.floor(x0);
1615
domain[i1] = nice.ceil(x1);
1716
}

src/time/scale.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ function d3_time_scale(linear, methods, format) {
1515
};
1616

1717
scale.nice = function(m) {
18-
var extent = d3_time_scaleExtent(scale.domain());
19-
return scale.domain([m.floor(extent[0]), m.ceil(extent[1])]);
18+
return scale.domain(d3_scale_nice(scale.domain(), function() { return m; }));
2019
};
2120

2221
scale.ticks = function(m, k) {

test/scale/linear-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ suite.addBatch({
211211
assert.deepEqual(x.domain(), [130, 0]);
212212
var x = linear().domain([0, .49]).nice();
213213
assert.deepEqual(x.domain(), [0, .5]);
214+
},
215+
"has no effect on degenerate domains": function(linear) {
214216
var x = linear().domain([0, 0]).nice();
215217
assert.deepEqual(x.domain(), [0, 0]);
216218
var x = linear().domain([.5, .5]).nice();

test/scale/log-test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,12 @@ suite.addBatch({
228228
assert.deepEqual(x.domain(), [1000, 1]);
229229
var x = log().domain([.01, .49]).nice();
230230
assert.deepEqual(x.domain(), [.01, 1]);
231+
},
232+
"works on degenerate domains": function(log) {
231233
var x = log().domain([0, 0]).nice();
232234
assert.deepEqual(x.domain(), [0, 0]);
233235
var x = log().domain([.5, .5]).nice();
234-
assert.inDelta(x.domain(), [.5, .5], 1e-6);
236+
assert.inDelta(x.domain(), [.1, 1], 1e-6);
235237
},
236238
"nicing a polylog domain only affects the extent": function(log) {
237239
var x = log().domain([1.1, 1.5, 10.9]).nice();

test/time/scale-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ suite.addBatch({
1414
return d3.time.scale;
1515
},
1616

17+
"nice": {
18+
"rounds using the specified time interval": function(scale) {
19+
var x = scale().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 23, 48)]);
20+
assert.deepEqual(x.nice(d3.time.day).domain(), [local(2009, 0, 1), local(2009, 0, 2)]);
21+
assert.deepEqual(x.nice(d3.time.week).domain(), [local(2008, 11, 28), local(2009, 0, 4)]);
22+
assert.deepEqual(x.nice(d3.time.month).domain(), [local(2008, 11, 1), local(2009, 1, 1)]);
23+
assert.deepEqual(x.nice(d3.time.year).domain(), [local(2008, 0, 1), local(2010, 0, 1)]);
24+
},
25+
"works on degenerate domains": function(scale) {
26+
var x = scale().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 0, 12)]);
27+
assert.deepEqual(x.nice(d3.time.day).domain(), [local(2009, 0, 1), local(2009, 0, 2)]);
28+
},
29+
"nicing a polylinear domain only affects the extent": function(linear) {
30+
var x = linear().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 23, 48), local(2009, 0, 2, 23, 48)]).nice(d3.time.day);
31+
assert.deepEqual(x.domain(), [local(2009, 0, 1), local(2009, 0, 1, 23, 48), local(2009, 0, 3)]);
32+
}
33+
},
34+
1735
"copy": {
1836
"changes to the domain are isolated": function(scale) {
1937
var x = scale().domain([local(2009, 0, 1), local(2010, 0, 1)]), y = x.copy();

0 commit comments

Comments
 (0)