diff --git a/src/nice.js b/src/nice.js index 579b418..ba31011 100644 --- a/src/nice.js +++ b/src/nice.js @@ -1,9 +1,9 @@ import {tickIncrement} from "./ticks.js"; -export default function nice(start, stop, count) { +export default function nice(start, stop, count, log) { let prestep; while (true) { - const step = tickIncrement(start, stop, count); + const step = tickIncrement(start, stop, count, log); if (step === prestep || step === 0 || !isFinite(step)) { return [start, stop]; } else if (step > 0) { diff --git a/src/ticks.js b/src/ticks.js index 5868d8d..d4ad08b 100644 --- a/src/ticks.js +++ b/src/ticks.js @@ -2,35 +2,42 @@ const e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2); -function tickSpec(start, stop, count) { +const logParams = { + binary: [Math.log2, 2], + natural: [(n) => Math.log1p(n - 1), Math.E], + common: [Math.log10, 10], +} + +function tickSpec(start, stop, count, log = 'common') { + const [logFn, base] = logParams[log] || logParams.common; const step = (stop - start) / Math.max(0, count), - power = Math.floor(Math.log10(step)), - error = step / Math.pow(10, power), - factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1; + power = Math.floor(logFn(step)), + error = step / Math.pow(base, power), + factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1; let i1, i2, inc; if (power < 0) { - inc = Math.pow(10, -power) / factor; + inc = Math.pow(base, -power) / factor; i1 = Math.round(start * inc); i2 = Math.round(stop * inc); if (i1 / inc < start) ++i1; if (i2 / inc > stop) --i2; inc = -inc; } else { - inc = Math.pow(10, power) * factor; + inc = Math.pow(base, power) * factor; i1 = Math.round(start / inc); i2 = Math.round(stop / inc); if (i1 * inc < start) ++i1; if (i2 * inc > stop) --i2; } - if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2); + if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2, log); return [i1, i2, inc]; } -export default function ticks(start, stop, count) { +export default function ticks(start, stop, count, log) { stop = +stop, start = +start, count = +count; if (!(count > 0)) return []; if (start === stop) return [start]; - const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count); + const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count, log) : tickSpec(start, stop, count, log); if (!(i2 >= i1)) return []; const n = i2 - i1 + 1, ticks = new Array(n); if (reverse) { @@ -43,13 +50,16 @@ export default function ticks(start, stop, count) { return ticks; } -export function tickIncrement(start, stop, count) { - stop = +stop, start = +start, count = +count; - return tickSpec(start, stop, count)[2]; +export function tickIncrement(start, stop, count, log) { + (stop = +stop), (start = +start), (count = +count); + return tickSpec(start, stop, count, log)[2]; } -export function tickStep(start, stop, count) { +export function tickStep(start, stop, count, log) { stop = +stop, start = +start, count = +count; - const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count); + const reverse = stop < start, + inc = reverse + ? tickIncrement(stop, start, count, log) + : tickIncrement(start, stop, count, log); return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc); } diff --git a/test/nice-test.js b/test/nice-test.js index bbc4f70..400f92a 100644 --- a/test/nice-test.js +++ b/test/nice-test.js @@ -44,3 +44,24 @@ it("nice(start, stop, count) returns the expected values", () => { assert.deepStrictEqual(nice(132, 876, 5), [0, 1000]); assert.deepStrictEqual(nice(132, 876, 1), [0, 1000]); }); + +it("nice(start, stop, count, base) returns the expected values for binary log", () => { + assert.deepStrictEqual(nice(0.126, 0.51, 32, 'binary'), [0.125, 0.515625]); + assert.deepStrictEqual(nice(0.126, 0.48, 10, 'binary'), [0.125, 0.5]); + assert.deepStrictEqual(nice(0.126, 0.48, 6, 'binary'), [0.125, 0.5]); + assert.deepStrictEqual(nice(0.126, 0.48, 5, 'binary'), [0.125, 0.5]); + assert.deepStrictEqual(nice(0.126, 0.48, 1, 'binary'), [0, 0.5]); + assert.deepStrictEqual(nice(129, 876, 1000, 'binary'), [129, 876]); + assert.deepStrictEqual(nice(129, 876, 100, 'binary'), [128, 880]); + assert.deepStrictEqual(nice(129, 876, 30, 'binary'), [128, 896]); + assert.deepStrictEqual(nice(129, 876, 10, 'binary'), [128, 896]); + assert.deepStrictEqual(nice(129, 876, 6, 'binary'), [128, 896]); + assert.deepStrictEqual(nice(129, 876, 5, 'binary'), [128, 896]); + assert.deepStrictEqual(nice(129, 876, 1, 'binary'), [0, 1024]); +}); + +it("nice(start, stop, count, base) returns the expected values for natural log", () => { + assert.deepStrictEqual(nice(Math.E + 0.1, Math.E * 3 + 0.1, 2, 'natural'), [0, Math.E * 4]); + assert.deepStrictEqual(nice(-Math.E - 0.1, Math.E + 0.1, 2, 'natural'), [-Math.E * 2, Math.E * 2]); + assert.deepStrictEqual(nice(-Math.E * 10 - 0.5, Math.E * 20 - 0.5, 30, 'natural'), [-Math.E * 11, Math.E * 20]); +}); diff --git a/test/tickIncrement-test.js b/test/tickIncrement-test.js index 68c64de..3e36b18 100644 --- a/test/tickIncrement-test.js +++ b/test/tickIncrement-test.js @@ -60,3 +60,98 @@ it("tickIncrement(start, stop, count) returns approximately count + 1 tickIncrem assert.strictEqual(tickIncrement(-10, 10, 2), 10); assert.strictEqual(tickIncrement(-10, 10, 1), 20); }); + + +describe("tickIncrement(start, stop, count, base) returns approximately count + 1 tickIncrement when start < stop", () => { + it("common", () => { + assert.strictEqual(tickIncrement( 0, 1, 10), -10); + assert.strictEqual(tickIncrement( 0, 1, 9), -10); + assert.strictEqual(tickIncrement( 0, 1, 8), -10); + assert.strictEqual(tickIncrement( 0, 1, 7), -5); + assert.strictEqual(tickIncrement( 0, 1, 6), -5); + assert.strictEqual(tickIncrement( 0, 1, 5), -5); + assert.strictEqual(tickIncrement( 0, 1, 4), -5); + assert.strictEqual(tickIncrement( 0, 1, 3), -2); + assert.strictEqual(tickIncrement( 0, 1, 2), -2); + assert.strictEqual(tickIncrement( 0, 1, 1), 1); + assert.strictEqual(tickIncrement( 0, 10, 10), 1); + assert.strictEqual(tickIncrement( 0, 10, 9), 1); + assert.strictEqual(tickIncrement( 0, 10, 8), 1); + assert.strictEqual(tickIncrement( 0, 10, 7), 2); + assert.strictEqual(tickIncrement( 0, 10, 6), 2); + assert.strictEqual(tickIncrement( 0, 10, 5), 2); + assert.strictEqual(tickIncrement( 0, 10, 4), 2); + assert.strictEqual(tickIncrement( 0, 10, 3), 5); + assert.strictEqual(tickIncrement( 0, 10, 2), 5); + assert.strictEqual(tickIncrement( 0, 10, 1), 10); + assert.strictEqual(tickIncrement(-10, 10, 10), 2); + assert.strictEqual(tickIncrement(-10, 10, 9), 2); + assert.strictEqual(tickIncrement(-10, 10, 8), 2); + assert.strictEqual(tickIncrement(-10, 10, 7), 2); + assert.strictEqual(tickIncrement(-10, 10, 6), 5); + assert.strictEqual(tickIncrement(-10, 10, 5), 5); + assert.strictEqual(tickIncrement(-10, 10, 4), 5); + assert.strictEqual(tickIncrement(-10, 10, 3), 5); + assert.strictEqual(tickIncrement(-10, 10, 2), 10); + assert.strictEqual(tickIncrement(-10, 10, 1), 20); + }); + + it("binary", () => { + assert.strictEqual(tickIncrement(0, 1, 10, "binary"), -8); + assert.strictEqual(tickIncrement(0, 1, 9, "binary"), -8); + assert.strictEqual(tickIncrement(0, 1, 8, "binary"), -8); + assert.strictEqual(tickIncrement(0, 1, 7, "binary"), -8); + assert.strictEqual(tickIncrement(0, 1, 6, "binary"), -8); + assert.strictEqual(tickIncrement(0, 1, 5, "binary"), -4); + assert.strictEqual(tickIncrement(0, 1, 4, "binary"), -4); + assert.strictEqual(tickIncrement(0, 1, 3, "binary"), -4); + assert.strictEqual(tickIncrement(0, 1, 2, "binary"), -2); + assert.strictEqual(tickIncrement(0, 1, 1, "binary"), 1); + assert.strictEqual(tickIncrement(0, 10, 10, "binary"), 1); + assert.strictEqual(tickIncrement(0, 10, 9, "binary"), 1); + assert.strictEqual(tickIncrement(0, 10, 8, "binary"), 1); + assert.strictEqual(tickIncrement(0, 10, 7, "binary"), 2); + assert.strictEqual(tickIncrement(0, 10, 6, "binary"), 2); + assert.strictEqual(tickIncrement(0, 10, 5, "binary"), 2); + assert.strictEqual(tickIncrement(0, 10, 4, "binary"), 2); + assert.strictEqual(tickIncrement(0, 10, 3, "binary"), 4); + assert.strictEqual(tickIncrement(0, 10, 2, "binary"), 4); + assert.strictEqual(tickIncrement(0, 10, 1, "binary"), 8); + assert.strictEqual(tickIncrement(-10, 10, 10, "binary"), 2); + assert.strictEqual(tickIncrement(-10, 10, 9, "binary"), 2); + assert.strictEqual(tickIncrement(-10, 10, 8, "binary"), 2); + assert.strictEqual(tickIncrement(-10, 10, 7, "binary"), 4); + assert.strictEqual(tickIncrement(-10, 10, 6, "binary"), 4); + assert.strictEqual(tickIncrement(-10, 10, 5, "binary"), 4); + assert.strictEqual(tickIncrement(-10, 10, 4, "binary"), 4); + assert.strictEqual(tickIncrement(-10, 10, 3, "binary"), 8); + assert.strictEqual(tickIncrement(-10, 10, 2, "binary"), 8); + assert.strictEqual(tickIncrement(-10, 10, 1, "binary"), 16); + }); + + it("natural", () => { + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E / 100, 10, 'natural')), -1); + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E / 10, 10, 'natural')), -0.5); + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E / 10, 1, 'natural')), -0.5); + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E, 3, 'natural')), -0.5); + assert.strictEqual(normalizeLn(tickIncrement( -Math.E, Math.E, 2, 'natural')), 1); + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E * 10, 10, 'natural')), 1); + assert.strictEqual(normalizeLn(tickIncrement( 1, Math.E * 10, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickIncrement( -Math.E * 10, Math.E * 10, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickIncrement( Math.E, Math.E * 100, 10, 'natural')), 1); + assert.strictEqual(normalizeLn(tickIncrement( -Math.E * 100, Math.E * 100, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickIncrement( 0, Math.E * 100, 10, 'natural')), 1); + assert.strictEqual(tickIncrement( 0, 10, 10, 'natural'), 1); + assert.strictEqual(tickIncrement( -10, 10, 10, 'natural'), 2); + }); +}) + +export function normalizeLn(value) { + let tries = 0, normValue = value; + while (tries++ < 10 && normValue % 0.5 !== 0) normValue *= Math.E; + if (tries > 10) { + tries = 0, normValue = value + while (tries++ < 10 && normValue % 0.5 !== 0) normValue /= Math.E; + } + return tries > 10 ? NaN : normValue; +} diff --git a/test/tickStep-test.js b/test/tickStep-test.js index 79b7ca7..9561d24 100644 --- a/test/tickStep-test.js +++ b/test/tickStep-test.js @@ -1,4 +1,5 @@ import assert from "assert"; +import {normalizeLn} from "./tickIncrement-test.js"; import {tickStep} from "../src/index.js"; it("tickStep(start, stop, count) returns NaN if any argument is NaN", () => { @@ -93,3 +94,118 @@ it("tickStep(start, stop, count) returns -tickStep(stop, start, count)", () => { assert.strictEqual(tickStep(-10, 10, 2), -tickStep(10, -10, 2)); assert.strictEqual(tickStep(-10, 10, 1), -tickStep(10, -10, 1)); }); + +it("tickStep(start, stop, count, base) with binary log returns approximately count + 1 tickStep when start < stop", () => { + assert.strictEqual(tickStep( 0, 1, 10, 'binary'), 0.125); + assert.strictEqual(tickStep( 0, 1, 9, 'binary'), 0.125); + assert.strictEqual(tickStep( 0, 1, 8, 'binary'), 0.125); + assert.strictEqual(tickStep( 0, 1, 7, 'binary'), 0.125); + assert.strictEqual(tickStep( 0, 1, 6, 'binary'), 0.125); + assert.strictEqual(tickStep( 0, 1, 5, 'binary'), 0.25); + assert.strictEqual(tickStep( 0, 1, 4, 'binary'), 0.25); + assert.strictEqual(tickStep( 0, 1, 3, 'binary'), 0.25); + assert.strictEqual(tickStep( 0, 1, 2, 'binary'), 0.5); + assert.strictEqual(tickStep( 0, 1, 1, 'binary'), 1); + assert.strictEqual(tickStep( 0, 10, 10, 'binary'), 1); + assert.strictEqual(tickStep( 0, 10, 9, 'binary'), 1); + assert.strictEqual(tickStep( 0, 10, 8, 'binary'), 1); + assert.strictEqual(tickStep( 0, 10, 7, 'binary'), 2); + assert.strictEqual(tickStep( 0, 10, 6, 'binary'), 2); + assert.strictEqual(tickStep( 0, 10, 5, 'binary'), 2); + assert.strictEqual(tickStep( 0, 10, 4, 'binary'), 2); + assert.strictEqual(tickStep( 0, 10, 3, 'binary'), 4); + assert.strictEqual(tickStep( 0, 10, 2, 'binary'), 4); + assert.strictEqual(tickStep( 0, 10, 1, 'binary'), 8); + assert.strictEqual(tickStep(-10, 10, 10, 'binary'), 2); + assert.strictEqual(tickStep(-10, 10, 9, 'binary'), 2); + assert.strictEqual(tickStep(-10, 10, 8, 'binary'), 2); + assert.strictEqual(tickStep(-10, 10, 7, 'binary'), 4); + assert.strictEqual(tickStep(-10, 10, 6, 'binary'), 4); + assert.strictEqual(tickStep(-10, 10, 5, 'binary'), 4); + assert.strictEqual(tickStep(-10, 10, 4, 'binary'), 4); + assert.strictEqual(tickStep(-10, 10, 3, 'binary'), 8); + assert.strictEqual(tickStep(-10, 10, 2, 'binary'), 8); + assert.strictEqual(tickStep(-10, 10, 1, 'binary'), 16); +}); + +it("tickStep(start, stop, count, base) with natural log returns approximately count + 1 tickStep when start < stop", () => { + assert.strictEqual(normalizeLn(tickStep( 0, Math.E / 100, 10, 'natural')), 1); + assert.strictEqual(normalizeLn(tickStep( 0, Math.E / 10, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( 0, Math.E / 10, 1, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( 0, Math.E, 3, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( -Math.E, Math.E, 2, 'natural')), 1); + assert.strictEqual(normalizeLn(tickStep( 0, Math.E * 10, 10, 'natural')), 1); + assert.strictEqual(normalizeLn(tickStep( 1, Math.E * 10, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( -Math.E * 10, Math.E * 10, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( Math.E, Math.E * 100, 10, 'natural')), 1); + assert.strictEqual(normalizeLn(tickStep( -Math.E * 100, Math.E * 100, 10, 'natural')), 2); + assert.strictEqual(normalizeLn(tickStep( 0, Math.E * 100, 10, 'natural')), 1); + assert.strictEqual(tickStep( 0, 10, 10, 'natural'), 1); + assert.strictEqual(tickStep( -10, 10, 10, 'natural'), 2); +}); + +it("tickStep(start, stop, count, base) with binary log returns -tickStep(stop, start, count)", () => { + assert.strictEqual(tickStep( 0, 1, 10, 'binary'), -tickStep( 1, 0, 10, 'binary')); + assert.strictEqual(tickStep( 0, 1, 9, 'binary'), -tickStep( 1, 0, 9, 'binary')); + assert.strictEqual(tickStep( 0, 1, 8, 'binary'), -tickStep( 1, 0, 8, 'binary')); + assert.strictEqual(tickStep( 0, 1, 7, 'binary'), -tickStep( 1, 0, 7, 'binary')); + assert.strictEqual(tickStep( 0, 1, 6, 'binary'), -tickStep( 1, 0, 6, 'binary')); + assert.strictEqual(tickStep( 0, 1, 5, 'binary'), -tickStep( 1, 0, 5, 'binary')); + assert.strictEqual(tickStep( 0, 1, 4, 'binary'), -tickStep( 1, 0, 4, 'binary')); + assert.strictEqual(tickStep( 0, 1, 3, 'binary'), -tickStep( 1, 0, 3, 'binary')); + assert.strictEqual(tickStep( 0, 1, 2, 'binary'), -tickStep( 1, 0, 2, 'binary')); + assert.strictEqual(tickStep( 0, 1, 1, 'binary'), -tickStep( 1, 0, 1, 'binary')); + assert.strictEqual(tickStep( 0, 10, 10, 'binary'), -tickStep(10, 0, 10, 'binary')); + assert.strictEqual(tickStep( 0, 10, 9, 'binary'), -tickStep(10, 0, 9, 'binary')); + assert.strictEqual(tickStep( 0, 10, 8, 'binary'), -tickStep(10, 0, 8, 'binary')); + assert.strictEqual(tickStep( 0, 10, 7, 'binary'), -tickStep(10, 0, 7, 'binary')); + assert.strictEqual(tickStep( 0, 10, 6, 'binary'), -tickStep(10, 0, 6, 'binary')); + assert.strictEqual(tickStep( 0, 10, 5, 'binary'), -tickStep(10, 0, 5, 'binary')); + assert.strictEqual(tickStep( 0, 10, 4, 'binary'), -tickStep(10, 0, 4, 'binary')); + assert.strictEqual(tickStep( 0, 10, 3, 'binary'), -tickStep(10, 0, 3, 'binary')); + assert.strictEqual(tickStep( 0, 10, 2, 'binary'), -tickStep(10, 0, 2, 'binary')); + assert.strictEqual(tickStep( 0, 10, 1, 'binary'), -tickStep(10, 0, 1, 'binary')); + assert.strictEqual(tickStep(-10, 10, 10, 'binary'), -tickStep(10, -10, 10, 'binary')); + assert.strictEqual(tickStep(-10, 10, 9, 'binary'), -tickStep(10, -10, 9, 'binary')); + assert.strictEqual(tickStep(-10, 10, 8, 'binary'), -tickStep(10, -10, 8, 'binary')); + assert.strictEqual(tickStep(-10, 10, 7, 'binary'), -tickStep(10, -10, 7, 'binary')); + assert.strictEqual(tickStep(-10, 10, 6, 'binary'), -tickStep(10, -10, 6, 'binary')); + assert.strictEqual(tickStep(-10, 10, 5, 'binary'), -tickStep(10, -10, 5, 'binary')); + assert.strictEqual(tickStep(-10, 10, 4, 'binary'), -tickStep(10, -10, 4, 'binary')); + assert.strictEqual(tickStep(-10, 10, 3, 'binary'), -tickStep(10, -10, 3, 'binary')); + assert.strictEqual(tickStep(-10, 10, 2, 'binary'), -tickStep(10, -10, 2, 'binary')); + assert.strictEqual(tickStep(-10, 10, 1, 'binary'), -tickStep(10, -10, 1, 'binary')); +}); + +it("tickStep(start, stop, count, base) with natural log returns -tickStep(stop, start, count)", () => { + assert.strictEqual(tickStep( 0, 1, 10, 'natural'), -tickStep( 1, 0, 10, 'natural')); + assert.strictEqual(tickStep( 0, 1, 9, 'natural'), -tickStep( 1, 0, 9, 'natural')); + assert.strictEqual(tickStep( 0, 1, 8, 'natural'), -tickStep( 1, 0, 8, 'natural')); + assert.strictEqual(tickStep( 0, 1, 7, 'natural'), -tickStep( 1, 0, 7, 'natural')); + assert.strictEqual(tickStep( 0, 1, 6, 'natural'), -tickStep( 1, 0, 6, 'natural')); + assert.strictEqual(tickStep( 0, 1, 5, 'natural'), -tickStep( 1, 0, 5, 'natural')); + assert.strictEqual(tickStep( 0, 1, 4, 'natural'), -tickStep( 1, 0, 4, 'natural')); + assert.strictEqual(tickStep( 0, 1, 3, 'natural'), -tickStep( 1, 0, 3, 'natural')); + assert.strictEqual(tickStep( 0, 1, 2, 'natural'), -tickStep( 1, 0, 2, 'natural')); + assert.strictEqual(tickStep( 0, 1, 1, 'natural'), -tickStep( 1, 0, 1, 'natural')); + assert.strictEqual(tickStep( 0, 10, 10, 'natural'), -tickStep(10, 0, 10, 'natural')); + assert.strictEqual(tickStep( 0, 10, 9, 'natural'), -tickStep(10, 0, 9, 'natural')); + assert.strictEqual(tickStep( 0, 10, 8, 'natural'), -tickStep(10, 0, 8, 'natural')); + assert.strictEqual(tickStep( 0, 10, 7, 'natural'), -tickStep(10, 0, 7, 'natural')); + assert.strictEqual(tickStep( 0, 10, 6, 'natural'), -tickStep(10, 0, 6, 'natural')); + assert.strictEqual(tickStep( 0, 10, 5, 'natural'), -tickStep(10, 0, 5, 'natural')); + assert.strictEqual(tickStep( 0, 10, 4, 'natural'), -tickStep(10, 0, 4, 'natural')); + assert.strictEqual(tickStep( 0, 10, 3, 'natural'), -tickStep(10, 0, 3, 'natural')); + assert.strictEqual(tickStep( 0, 10, 2, 'natural'), -tickStep(10, 0, 2, 'natural')); + assert.strictEqual(tickStep( 0, 10, 1, 'natural'), -tickStep(10, 0, 1, 'natural')); + assert.strictEqual(tickStep(-10, 10, 10, 'natural'), -tickStep(10, -10, 10, 'natural')); + assert.strictEqual(tickStep(-10, 10, 9, 'natural'), -tickStep(10, -10, 9, 'natural')); + assert.strictEqual(tickStep(-10, 10, 8, 'natural'), -tickStep(10, -10, 8, 'natural')); + assert.strictEqual(tickStep(-10, 10, 7, 'natural'), -tickStep(10, -10, 7, 'natural')); + assert.strictEqual(tickStep(-10, 10, 6, 'natural'), -tickStep(10, -10, 6, 'natural')); + assert.strictEqual(tickStep(-10, 10, 5, 'natural'), -tickStep(10, -10, 5, 'natural')); + assert.strictEqual(tickStep(-10, 10, 4, 'natural'), -tickStep(10, -10, 4, 'natural')); + assert.strictEqual(tickStep(-10, 10, 3, 'natural'), -tickStep(10, -10, 3, 'natural')); + assert.strictEqual(tickStep(-10, 10, 2, 'natural'), -tickStep(10, -10, 2, 'natural')); + assert.strictEqual(tickStep(-10, 10, 1, 'natural'), -tickStep(10, -10, 1, 'natural')); +}); diff --git a/test/ticks-test.js b/test/ticks-test.js index 4793e65..05db95e 100644 --- a/test/ticks-test.js +++ b/test/ticks-test.js @@ -125,3 +125,39 @@ it("ticks(start, stop, count) tries to return at least one tick if count >= 0.5" assert.deepStrictEqual(ticks(-0.001, -0.364, 0.5), [-0.2]); assert.deepStrictEqual(ticks(-0.364, -0.001, 0.5), [-0.2]); }); + +it("ticks(start, stop, count, base) returns ticks for binary log", () => { + assert.deepStrictEqual(ticks(0, 10, 5, 'binary'), [0, 2, 4, 6, 8, 10]); + assert.deepStrictEqual( + ticks(0, 1024, 10, 'binary'), + [0, 128, 256, 384, 512, 640, 768, 896, 1024] + ); + assert.deepStrictEqual( + ticks(-1024, 1024, 20, 'binary'), + [ + -1024, -896, -768, -640, -512, -384, -256, -128, 0, 128, 256, 384, 512, + 640, 768, 896, 1024, + ] + ); + assert.deepStrictEqual(ticks(0, 2000, 5, 'binary'), [0, 512, 1024, 1536]); +}); + +it("ticks(start, stop, count, base) returns ticks for natural log", () => { + assert.deepStrictEqual(ticks(0, 10, 5, Math.E), [0, 2, 4, 6, 8, 10]); + assert.deepStrictEqual( + ticks(0, 10, 10, 'natural'), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ); + assert.deepStrictEqual( + ticks(0, Math.E * 10, 10, 'natural'), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((v) => (v *= Math.E)) + ); + assert.deepStrictEqual( + ticks(-Math.E * 10, Math.E * 10, 10, 'natural'), + [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10].map((v) => (v *= Math.E)) + ); + assert.deepStrictEqual( + ticks(-Math.E * 10, 0, 10, 'natural'), + [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0].map((v) => (v *= Math.E)) + ); +});