I'm stuck on a problem where I try to select specific DOM elements with d3.selectAll(). For example let's say I have the following dataset.
const dataset = [3, 7, 9, 5, 4]
Now, I want to create SVG circles from this dataset
d3.selectAll("circle").data(dataset).join("circle").attr("r", 2).attr("cx", (d,i) => i * 10).attr("cy", 100)
Let`s say I have a button with an eventlistener that should select a random number of these circles and change their fill values. How can I implement this?
const button = document.querySelector("button")
button.addEventListener("click", () => {
// what should the code be here?
}
I have tried some of the suggestions from How to access the DOM element that correlates to a D3 SVG object? but these works only for a single dom element. Is there a way to select more than one DOM element by index?
CodePudding user response:
Unfortunately there's an incongruence between your question title and your example: in the title and in the last paragraph you're asking how to select elements by their indices, while in the example you're asking how to select a random number of elements. Thus, I'll answer the title question only.
In D3 selections, the second argument passed to most selections' methods is the index. Thus, supposing you have the desired indices, e.g...
[1, 4, 5, 7]
... all you need is to use filter
, each
or any other direct method to change your elements. Here's a quick example, circles
is my circle selection, and I change their fills according to the indices array:
const circles = d3.select("svg")
.selectAll(null)
.data(d3.range(10))
.enter()
.append("circle")
.attr("r", 10)
.attr("cx", (_, i) => i * 25 10)
.attr("cy", 40);
const indicesArray = [1, 4, 5, 7];
circles.filter((_, i) => indicesArray.includes(i))
.style("fill", "tan");
<script src="https://d3js.org/d3.v7.min.js"></script>
<svg></svg>