我正在決議一個 xml 字串并將其顯示為 d3.js 中的樹。我可以在“進入”步驟中構建整個樹,但現在我想讓它互動并將配置拉出到更新步驟中。我正在關注https://stackoverflow.com/a/24912466來實作一般更新模式,但我似乎無法在輸入步驟之外將屬性設定為 g 元素:
const svg = d3.select("#canvas");
const xmlAsText = `
<root attrib1="foo" att2="foO">
<child1 attrib1="ba">zwei</child1>
<child2>eins</child2>
</root>`;
treeDataXml = (new DOMParser()).parseFromString(xmlAsText, "text/xml");
let hierarchy = d3.hierarchy(treeDataXml.children[0], d => d.children);
nodesData = d3.tree()(hierarchy);
var myGroups = svg.selectAll("g").data(nodesData.descendants());
myGroupsEnter = myGroups.enter().append("g")
// 1) works
//myGroupsEnter .attr("class", "x");
// 2) doesn't work
myGroups.select("g").attr("class", "x");
console.log(document.getElementById("canvas").childNodes[0].attributes[0])
alert(document.getElementById("canvas")
.childNodes[0].attributes.length)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg id="canvas"></svg>
1)我得到
<body>
<svg id="canvas">
<g class="x"></g>
<g class="x"></g>
<g class="x"></g>
</svg>
</body>
但對于 2) 它只是:
<body>
<svg id="canvas">
<g></g>
<g></g>
<g></g>
</svg>
</body>
我希望myGroups.select("g").attr("class", "x")之前的entered <g>s 都將被選中并將其屬性class設定為“x”。為什么這不起作用?我怎樣才能解決這個問題?
uj5u.com熱心網友回復:
選擇是不可變的,myGroups是一個空選擇:它還不包含任何 DOM 元素。由于這個選擇是更新選擇,這是有道理的,沒有什么要更新的。
選擇myGroupsEnter包含新創建的元素。輸入元素不會修改myGroups,這仍然是一個空選擇。這解釋了為什么myGroupsEnter.attr("class", "x");有效而myGroups.select("g").attr("class", "x");無效。
D3 v3 和更早版本在更新選擇中添加了新輸入的元素,這就是為什么某些示例可能會產生誤導,但由于此行為不明確,因此已將其洗掉
通常您希望將輸入和更新的元素組合到一個選擇中,您可以使用:
let combined = myGroups.merge(myGroupsEnter);
這樣,無論您是輸入所有元素、更新所有元素,還是輸入一些元素并更新其他元素,您都可以修改所有存在的元素(未退出的元素)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/506792.html
標籤:javascript svg d3.js
上一篇:d3.js條形圖-Y軸NaN
