簡體   English   中英

D3 - 從v3升級到v4時,forEach不是一個功能

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM