[英]D3 - forEach is not a function when upgrading from v3 to v4
我正在嘗試將此可堆疊條形圖升級到v4。 除了一件事,一切都有效。
當我過濾一個類別時,條形不會下降到x軸的起點。 我收到一個錯誤,上面寫着:
state.selectAll(...)。forEach不是一個函數
我嘗試了很多東西,但我無法想出這個。 這是破碎的代碼:
function plotSingle(d) {
class_keep = d.id.split("id").pop();
idx = legendClassArray.indexOf(class_keep);
//erase all but selected bars by setting opacity to 0
d3.selectAll(".bars:not(.class" + class_keep + ")")
.transition()
.duration(1000)
.attr("width", 0) // use because svg has no zindex to hide bars so can't select visible bar underneath
.style("opacity", 0);
//lower the bars to start on x-axis
state.selectAll("rect").forEach(function(d, i) {
//get height and y posn of base bar and selected bar
h_keep = d3.select(d[idx]).attr("height");
y_keep = d3.select(d[idx]).attr("y");
h_base = d3.select(d[0]).attr("height");
y_base = d3.select(d[0]).attr("y");
h_shift = h_keep - h_base;
y_new = y_base - h_shift;
//reposition selected bars
d3.select(d[idx])
.transition()
.ease("bounce")
.duration(1000)
.delay(750)
.attr("y", y_new);
})
}
我覺得奇怪的是,這在D3 v3中完美無缺,為什么這不能在v4中運行?
在d3 v3中,selectAll返回一個數組,在d3 v4中它返回一個對象。
從v3筆記 :
選擇是元素數組 - 字面意思(可能不是字面意思......)。 D3將其他方法綁定到數組,以便您可以將運算符應用於所選元素,例如在所有選定元素上設置屬性。
v4的變化包括:
選擇不再使用原型鏈注入子類化Array; 它們現在是普通物體,提高了性能。 內部字段(selection._groups,selection._parents)是私有的; 請使用記錄的公共API來操作選擇。 新的selection.nodes方法生成選擇中所有節點的數組。
如果要在v4中訪問每個節點,請嘗試:
selection.nodes().forEach( function(d,i) { ... })
但是,這只是節點,以獲取選擇每個節點所需的數據:
var data = [0,1,2]; var svg = d3.select("body").append("svg") .attr("width",500) .attr("height",200) var circles = svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("cx", function(d,i) { return i * 20 + 50 }) .attr("cy", 50) .attr("r", 4); circles.nodes().forEach(function(d,i) { console.log(d3.select(d).data()); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
但是,如果您需要數據或修改選擇屬性,則使用selection.each()會更容易。 d3.each遍歷d3選擇本身的每個元素,並允許您為選擇中的每個元素調用一個函數(請參閱此處的 API文檔):
var data = [0,1,2]; var svg = d3.select("body").append("svg") .attr("width",500) .attr("height",200) var circles = svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("cx", function(d,i) { return i * 20 + 50 }) .attr("cy", 50) .attr("r", 4); circles.each( function() { console.log(d3.select(this).data()); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
在此條形圖的第3版中,在forEach循環中
`states.selectAll("rect").forEach(function(d,i) {`
d是節點數組(每個.g
的矩形)。
但是,在v4中,d3選擇不是數組,您不能以相同的方式使用forEach循環。 但是你仍然可以使用selection.nodes()
獲取其中的節點,而無需進行太多修改,並且讓childNodes在v3版本中復制數組:
state.nodes().forEach(function(d, i) {
var nodes = d.childNodes;
在這里,我們經歷中的每個元素/節點state
,並得到孩子rect
S,作為一個數組返回。 這是一個更新的小提琴 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.