diff --git a/README.md b/README.md index 6c65e82..8d49489 100644 --- a/README.md +++ b/README.md @@ -189,9 +189,9 @@ axis.ticks(10, ",f"); This has the advantage of setting the format precision automatically based on the tick interval. -# axis.tickSize([size]) · [Source](https://github.com/d3/d3-axis/blob/master/src/axis.js) +# axis.tickSize([value]) · [Source](https://github.com/d3/d3-axis/blob/master/src/axis.js) -If *size* is specified, sets the [inner](#axis_tickSizeInner) and [outer](#axis_tickSizeOuter) tick size to the specified value and returns the axis. If *size* is not specified, returns the current inner tick size, which defaults to 6. +If *value* is a function, it is evaluated for each tick, in order, being passed the current tick datum (*d*), the current index (*i*), and the group of ticks (*nodes*), with *this* as the current DOM element (*nodes*[*i*]), and returns the axis. If *value* is a constant, sets the [inner](#axis_tickSizeInner) and [outer](#axis_tickSizeOuter) tick size to the specified value, removes any previously set tick size function and returns the axis. If *value* is not specified, returns the current tick size function (if specified) or the inner tick size, which defaults to 6. # axis.tickSizeInner([size]) · [Source](https://github.com/d3/d3-axis/blob/master/src/axis.js) diff --git a/src/axis.js b/src/axis.js index 78e1bcb..00194e2 100644 --- a/src/axis.js +++ b/src/axis.js @@ -35,6 +35,7 @@ function axis(orient, scale) { tickSizeInner = 6, tickSizeOuter = 6, tickPadding = 3, + tickSizeFunction = null, offset = typeof window !== "undefined" && window.devicePixelRatio > 1 ? 0 : 0.5, k = orient === top || orient === left ? -1 : 1, x = orient === left || orient === right ? "x" : "y", @@ -68,7 +69,7 @@ function axis(orient, scale) { text = text.merge(tickEnter.append("text") .attr("fill", "currentColor") - .attr(x, k * spacing) + .attr(x, tickSizeFunction == null ? k * spacing : function(d, i, nodes) { return k * spacing + tickSizeFunction(d, i, nodes); }) .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); if (context !== selection) { @@ -98,10 +99,12 @@ function axis(orient, scale) { .attr("transform", function(d) { return transform(position(d) + offset); }); line - .attr(x + "2", k * tickSizeInner); + .attr(x + "2", tickSizeFunction == null ? k * tickSizeInner : tickSizeFunction); text - .attr(x, k * spacing) + .attr(x, function(d, i, nodes) { + return tickSizeFunction == null ? k * spacing : k * spacing + tickSizeFunction(d, i, nodes) + }) .text(format); selection.filter(entering) @@ -135,7 +138,7 @@ function axis(orient, scale) { }; axis.tickSize = function(_) { - return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; + return arguments.length ? (typeof _ === "function" ? (tickSizeInner = tickSizeOuter = null, tickSizeFunction = _, axis) : (tickSizeFunction = null, tickSizeInner = tickSizeOuter = +_, axis)) : tickSizeFunction || tickSizeInner; }; axis.tickSizeInner = function(_) { diff --git a/test/axis-test.js b/test/axis-test.js index 9df3f14..5e1b4c1 100644 --- a/test/axis-test.js +++ b/test/axis-test.js @@ -66,3 +66,14 @@ it("axis.tickValues(values) accepts an iterable", () => { const a = axisLeft(scaleLinear()).tickValues(new Set([1, 2, 3])); assert.deepStrictEqual(a.tickValues(), [1, 2, 3]); }); + +it("axis.tickSize(value) accepts a number", () => { + const a = axisLeft(scaleLinear()).tickSize(5); + assert.strictEqual(a.tickSize(), 5); +}); + +it("axis.tickSize(value) accepts a function", () => { + const v = (d, i) => i * 2; + const a = axisLeft(scaleLinear()).tickSize(v); + assert.strictEqual(a.tickSize(), v); +}); diff --git a/test/snapshots.js b/test/snapshots.js index 7141a9a..b3e7245 100644 --- a/test/snapshots.js +++ b/test/snapshots.js @@ -13,3 +13,12 @@ export function axisLeftScaleLinearNonNumericRange() { svg.append("g").call(axisLeft(scaleLinear().range([0, "500"]))); return svg.node(); } + +export function axisLeftTickSizeFunction() { + const scale = scaleLinear([0, 10], [10, 140]); + const svg = create("svg"); + svg.append("g") + .attr("transform", "translate(20, 0)") + .call(axisLeft(scale).tickSize(function(d, i) { return i * 2 })); + return svg.node(); +} diff --git a/test/snapshots/axisLeftTickSizeFunction.html b/test/snapshots/axisLeftTickSizeFunction.html new file mode 100644 index 0000000..d413bf9 --- /dev/null +++ b/test/snapshots/axisLeftTickSizeFunction.html @@ -0,0 +1,39 @@ + + + + + + 0 + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 9 + + + 10 + + + \ No newline at end of file