diff --git a/src/linear.js b/src/linear.js index b91f712..73b3274 100644 --- a/src/linear.js +++ b/src/linear.js @@ -4,63 +4,59 @@ import {initRange} from "./init.js"; import tickFormat from "./tickFormat.js"; export function linearish(scale) { - var domain = scale.domain; + const domain = scale.domain; scale.ticks = function(count) { - var d = domain(); + const d = domain(); return ticks(d[0], d[d.length - 1], count == null ? 10 : count); }; scale.tickFormat = function(count, specifier) { - var d = domain(); + const d = domain(); return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); }; scale.nice = function(count) { if (count == null) count = 10; - var d = domain(), - i0 = 0, - i1 = d.length - 1, - start = d[i0], - stop = d[i1], - step; + const d = domain(); + let i0 = 0; + let i1 = d.length - 1; + let start = d[i0]; + let stop = d[i1]; + let prestep; + let step; if (stop < start) { step = start, start = stop, stop = step; step = i0, i0 = i1, i1 = step; } - - step = tickIncrement(start, stop, count); - - if (step > 0) { - start = Math.floor(start / step) * step; - stop = Math.ceil(stop / step) * step; - step = tickIncrement(start, stop, count); - } else if (step < 0) { - start = Math.ceil(start * step) / step; - stop = Math.floor(stop * step) / step; - step = tickIncrement(start, stop, count); + + // eslint-disable-next-line no-constant-condition + while (true) { + const step = tickIncrement(start, stop, count); + if (step === prestep) { + d[i0] = start + d[i1] = stop + return domain(d); + } else if (step > 0) { + start = Math.floor(start / step) * step; + stop = Math.ceil(stop / step) * step; + } else if (step < 0) { + start = Math.ceil(start * step) / step; + stop = Math.floor(stop * step) / step; + } else { + return scale; + } + prestep = step; } - - if (step > 0) { - d[i0] = Math.floor(start / step) * step; - d[i1] = Math.ceil(stop / step) * step; - domain(d); - } else if (step < 0) { - d[i0] = Math.ceil(start * step) / step; - d[i1] = Math.floor(stop * step) / step; - domain(d); - } - - return scale; }; return scale; } export default function linear() { - var scale = continuous(); + const scale = continuous(); scale.copy = function() { return copy(scale, linear()); diff --git a/test/linear-test.js b/test/linear-test.js index 62de558..154760d 100644 --- a/test/linear-test.js +++ b/test/linear-test.js @@ -373,6 +373,36 @@ tape("linear.ticks(count) returns the expected ticks for a polylinear domain", f test.end(); }); +tape("linear.ticks(X) spans linear.nice(X).domain()", function(test) { + function check(domain, count) { + var s = scale.scaleLinear().domain(domain).nice(count); + var ticks = s.ticks(count); + test.deepEqual([ticks[0], ticks[ticks.length - 1]], s.domain()); + } + + check([1, 9], 2); + check([1, 9], 3); + check([1, 9], 4); + + check([8, 9], 2); + check([8, 9], 3); + check([8, 9], 4); + + check([1, 21], 2); + check([2, 21], 2); + check([3, 21], 2); + check([4, 21], 2); + check([5, 21], 2); + check([6, 21], 2); + check([7, 21], 2); + check([8, 21], 2); + check([9, 21], 2); + check([10, 21], 2); + check([11, 21], 2); + + test.end(); +}) + tape("linear.ticks(count) returns the empty array if count is not a positive integer", function(test) { var s = scale.scaleLinear(); test.deepEqual(s.ticks(NaN), []);