There are a lot of articles about how to update dom for each data. But what if I want to update multiple dom nodes for each data.
For example, for each data, generate div and span according to the number in the data.
[
[1, 2],
[2, 1],
]
I want to yield like
<div class="data">
<div>1</div><span>2</span><span>2</span>
</div>
<div class="data">
<div>2</div><div>2</div><span>1</span>
</div>
Should start with
const selection = d3.selectAll("div.data");
selection.exit().remove();
selection.enter().append("div").attr("class", "data").merge(selection);
// Then I don't know how to add multiple dom according to the data value.
First of all, your question's title ("how to update multiple elements for each data") suggests that you want to update those elements, when in fact, by reading your actual question, you just want to create them (enter, in D3 lingo). Also, pay attention to the fact that you cannot use data() following d3.selectAll().
That being said, there are several solutions. One of them is using each() for your outer divs, and then appending how many elements you want (divs or spans) by using d3.range(), which will create an array whose length is based on the number you pass to it. The actual content of that array is irrelevant, since the text in both divs and spans correspond to the numbers in the inner arrays.
Here is a simple example, pay attention to the colors for each element (outer divs, inner divs and spans):
const body = d3.select("body");
const data = [
[1, 2],
[2, 1],
];
const dataDiv = body.selectAll(null)
.data(data)
.enter()
.append("div")
.attr("class", "data")
.each(function(d) {
d3.select(this).selectAll(null)
.data(d3.range(d[0]))
.enter()
.append("div")
.attr("class", "innerDiv")
.html(d[0]);
d3.select(this).selectAll(null)
.data(d3.range(d[1]))
.enter()
.append("span")
.html(d[1]);
})
.data {
margin: 10px;
padding: 2px;
display: inline-block;
background-color: wheat;
}
.innerDiv {
margin: 10px;
padding: 2px;
display: inline-block;
background-color: yellowgreen;
}
span {
margin: 10px;
padding: 2px;
background-color: salmon;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
And here is the generated HTML:
<div class="data">
<div class="innerDiv">1</div><span>2</span><span>2</span>
</div>
<div class="data">
<div class="innerDiv">2</div>
<div class="innerDiv">2</div><span>1</span>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With