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 @@
+
+
\ No newline at end of file