From 694ed8f631e09f45a30ad24725c7972407bebcb2 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Wed, 20 May 2020 09:25:35 -0700 Subject: [PATCH 1/3] Ensure that niced domains always span ticks fixes #209 --- src/linear.js | 62 +++++++++++++++++++++------------------------ test/linear-test.js | 30 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 33 deletions(-) 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), []); From 96b8f4b9d6171c19ed4f1c5d8618531ef9634470 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Wed, 20 May 2020 09:50:34 -0700 Subject: [PATCH 2/3] Limit the number of iterations in scaleLinear.nice --- src/linear.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/linear.js b/src/linear.js index 73b3274..f9f91cb 100644 --- a/src/linear.js +++ b/src/linear.js @@ -26,14 +26,14 @@ export function linearish(scale) { let stop = d[i1]; let prestep; let step; + let maxIter = 10; if (stop < start) { step = start, start = stop, stop = step; step = i0, i0 = i1, i1 = step; } - // eslint-disable-next-line no-constant-condition - while (true) { + while (maxIter-- > 0) { const step = tickIncrement(start, stop, count); if (step === prestep) { d[i0] = start @@ -46,10 +46,12 @@ export function linearish(scale) { start = Math.ceil(start * step) / step; stop = Math.floor(stop * step) / step; } else { - return scale; + break; } prestep = step; } + + return scale; }; return scale; From da99948d2fb7a4b7a93fc69be427e5cd7550c8a3 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 15 Jun 2020 08:16:26 -0700 Subject: [PATCH 3/3] Use var --- src/linear.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/linear.js b/src/linear.js index f9f91cb..3617d32 100644 --- a/src/linear.js +++ b/src/linear.js @@ -4,29 +4,29 @@ import {initRange} from "./init.js"; import tickFormat from "./tickFormat.js"; export function linearish(scale) { - const domain = scale.domain; + var domain = scale.domain; scale.ticks = function(count) { - const d = domain(); + var d = domain(); return ticks(d[0], d[d.length - 1], count == null ? 10 : count); }; scale.tickFormat = function(count, specifier) { - const d = domain(); + var d = domain(); return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); }; scale.nice = function(count) { if (count == null) count = 10; - const d = domain(); - let i0 = 0; - let i1 = d.length - 1; - let start = d[i0]; - let stop = d[i1]; - let prestep; - let step; - let maxIter = 10; + var d = domain(); + var i0 = 0; + var i1 = d.length - 1; + var start = d[i0]; + var stop = d[i1]; + var prestep; + var step; + var maxIter = 10; if (stop < start) { step = start, start = stop, stop = step; @@ -34,7 +34,7 @@ export function linearish(scale) { } while (maxIter-- > 0) { - const step = tickIncrement(start, stop, count); + step = tickIncrement(start, stop, count); if (step === prestep) { d[i0] = start d[i1] = stop @@ -58,7 +58,7 @@ export function linearish(scale) { } export default function linear() { - const scale = continuous(); + var scale = continuous(); scale.copy = function() { return copy(scale, linear());