[英]How to update multiple elements for each data
There are a lot of articles about how to update dom for each data.关于如何为每个数据更新 dom 的文章很多。 But what if I want to update multiple dom nodes for each data.
但是如果我想为每个数据更新多个dom节点怎么办。
For example, for each data, generate div and span according to the number in the data.比如对于每条数据,根据数据中的数字生成div和span。
[
[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).首先,您的问题标题(“如何为每个数据更新多个元素” )表明您想要更新这些元素,而实际上,通过阅读您的实际问题,您只想创建它们( enter ,在 D3 术语中). Also, pay attention to the fact that you cannot use
data()
following d3.selectAll()
.另外,请注意您不能在
d3.selectAll()
data()
) 。
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.其中之一是将
each()
用于您的外部 div,然后使用d3.range()
附加您想要的元素数量(div 或跨度),这将创建一个数组,其长度基于您传递给它的数字. The actual content of that array is irrelevant, since the text in both divs and spans correspond to the numbers in the inner arrays.该数组的实际内容无关紧要,因为 div 和 span 中的文本对应于内部 arrays 中的数字。
Here is a simple example, pay attention to the colors for each element (outer divs, inner divs and spans):这是一个简单的例子,注意每个元素(外部 div、内部 div 和 span)的 colors:
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:这是生成的 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>
d3 supports nesting of selections . d3 支持选择的嵌套。 The critical bit here is after binding data to the parent elements, call
parent.selectAll()
and then bind the data using a function instead of a variable, eg, parent.selectAll(child).data(d => d)
.这里的关键是在将数据绑定到父元素之后,调用
parent.selectAll()
然后使用 function 而不是变量绑定数据,例如parent.selectAll(child).data(d => d)
。 d3 will automatically bind the nested arrays to each child element. d3 会自动将嵌套的 arrays 绑定到每个子元素。 This is described in the link , which defines a
table
with nested tr
and td
elements:这在链接中有描述,它定义了一个包含嵌套
tr
和td
元素的table
:
The data operator defines the array of data for each group.
数据运算符定义每个组的数据数组。 Here the data function is invoked once per row and successively passed each parent datum.
这里数据 function 每行调用一次,并连续传递每个父数据。 Since the parent data is an array of arrays, the data function simply returns the inner array for each row of cells.
由于父数据是 arrays 的数组,数据 function 只是返回每行单元格的内部数组。
let data = [ [1, 2], [2, 1], ] let selection = d3.selectAll('div.data').data(data).enter().append("div").attr("class", "data") selection.selectAll('span').data(function(d) { return d; }).enter().append('span').text(d => d)
.data span { background: white; border: 1px solid black; padding: 5px; margin: 5px; }.data { background: yellow; margin: 10px; border: 1px solid red; padding: 8px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.