I've got a chart based on this tutorial
It's working very all apart from that when I zoom, the plot works but not the x-axis. The problem lies on my zoom function
const zoomed = (event) => {
xScale.range(
[margin.left, width - margin.right].map((d) =>
event.transform.applyX(d)
)
);
svg
.selectAll(".bars rect")
.attr("x", (d) => xScale(d.name))
.attr("width", xScale.bandwidth());
svg.selectAll(".x-axis").call(xAxis);
};
The last line svg.selectAll(".x-axis").call(xAxis);
throws the error: callback.apply is not a function
.
if I log svg.selectAll(".x-axis")
to the console I get the corresponding nodes with the call
method attached so I don't know why's not working. I'm using d3 7.6.1 so this method might not work in the same way but after researching, I couldn't find an answer.
Here's a sandbox
CodePudding user response:
When you zoom, you want to recreate the x scale inside the g.x-axis element. To do that you need to call an axis generator on that element like that:
axisGenerator(d3.selectAll(".x-axis"))
which is equivalent to execute:
d3.selectAll(".x-axis").call(axisGenerator)
In your code the parameter to call() is not an axis generator. The xAxis variable is a d3 selection. So you first need to create an axis generator:
const xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
And then initialize the x axis by creating a group element and call the axis generator on it:
svg.append("g")
.attr("transform", `translate(0, ${height - margin.bottom})`)
.attr("class", "x-axis")
.call(xAxis)
In your zoomed function, you can then update the x axis like that:
svg.selectAll(".x-axis").call(xAxis);