[英]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.