[英]How to update multiple elements for each data
关于如何为每个数据更新 dom 的文章很多。 但是如果我想为每个数据更新多个dom节点怎么办。
比如对于每条数据,根据数据中的数字生成div和span。
[
[1, 2],
[2, 1],
]
我想屈服
<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>
应该从
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.
首先,您的问题标题(“如何为每个数据更新多个元素” )表明您想要更新这些元素,而实际上,通过阅读您的实际问题,您只想创建它们( enter ,在 D3 术语中). 另外,请注意您不能在d3.selectAll()
data()
) 。
话虽如此,有几种解决方案。 其中之一是将each()
用于您的外部 div,然后使用d3.range()
附加您想要的元素数量(div 或跨度),这将创建一个数组,其长度基于您传递给它的数字. 该数组的实际内容无关紧要,因为 div 和 span 中的文本对应于内部 arrays 中的数字。
这是一个简单的例子,注意每个元素(外部 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>
这是生成的 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 支持选择的嵌套。 这里的关键是在将数据绑定到父元素之后,调用parent.selectAll()
然后使用 function 而不是变量绑定数据,例如parent.selectAll(child).data(d => d)
。 d3 会自动将嵌套的 arrays 绑定到每个子元素。 这在链接中有描述,它定义了一个包含嵌套tr
和td
元素的table
:
数据运算符定义每个组的数据数组。 这里数据 function 每行调用一次,并连续传递每个父数据。 由于父数据是 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.