0
使用D3 v4更新模式時,我無法使某些子代更新其數據。如何使用D3 v4的更新模式更新嵌套的子節點
什麼是正確的方式來獲取更改數據連接傳播給孩子?
下面是一個例子 https://bl.ocks.org/yanofsky/5b30b12582b6b66bc262b165806a6dc5
當你點擊按鈕,只有文字的變化,而不是兩個文本和rects的顏色。
使用D3 v4更新模式時,我無法使某些子代更新其數據。如何使用D3 v4的更新模式更新嵌套的子節點
什麼是正確的方式來獲取更改數據連接傳播給孩子?
下面是一個例子 https://bl.ocks.org/yanofsky/5b30b12582b6b66bc262b165806a6dc5
當你點擊按鈕,只有文字的變化,而不是兩個文本和rects的顏色。
您應該按照添加數據添加每個元素的模式。這樣你總是有一個update
,enter
和exit
的選擇。除去exit
和增加新的元素enter
後,您可以合併update
和enter
和更新的屬性:
//define some data
var data = [
{"location": 1, "month": "Jan", "year": 2017, "value": "#ccc"},
{"location": 2, "month": "Jan", "year": 2017, "value": "#999"},
{"location": 3, "month": "Jan", "year": 2017, "value": "#666"},
{"location": 4, "month": "Jan", "year": 2017, "value": "#333"},
{"location": 1, "month": "Jan", "year": 2018, "value": "#fcc"},
{"location": 2, "month": "Jan", "year": 2018, "value": "#f99"},
{"location": 3, "month": "Jan", "year": 2018, "value": "#f66"},
{"location": 4, "month": "Jan", "year": 2018, "value": "#f33"},
{"location": 1, "month": "Feb", "year": 2017, "value": "#cfc"},
{"location": 2, "month": "Feb", "year": 2017, "value": "#9f9"},
{"location": 3, "month": "Feb", "year": 2017, "value": "#6f6"},
{"location": 4, "month": "Feb", "year": 2017, "value": "#3f3"},
{"location": 1, "month": "Feb", "year": 2018, "value": "#ccf"},
{"location": 2, "month": "Feb", "year": 2018, "value": "#99f"},
{"location": 3, "month": "Feb", "year": 2018, "value": "#66f"},
{"location": 4, "month": "Feb", "year": 2018, "value": "#33f"},
{"location": 5, "month": "Feb", "year": 2018, "value": "#0505ff"},
]
// nest the data by month then year
var by_month = d3.nest()
.key(function(d){return d.month})
.key(function(d){return d.year})
.entries(data)
function render(ident, key_month) {
var w = 500
var h = 100
var container = d3.select(ident)
// select and add a container div for each year in the data
// using only the data for the target month
var year = container
.selectAll("div.year")
var data = by_month.filter(function(d){return d.key == key_month})[0].values;
var yearAll= year.data(data);
yearAll.exit().remove();
var yearEnter= yearAll
.enter()
.append("div")
.classed("year",true);
//Add h2 and svg
yearEnter.append("h2");
yearEnter.append("svg")
.append("g")
.classed("gwrapper",true);
yearEnter = yearEnter.merge(yearAll);
yearEnter.select("h2")
.text(function(d) {return d.values[0].month + " " + d.values[0].year ;});
// update the svg dimensions
yearEnter.select("svg")
.attr("width", w)
.attr("height", h);
// select and add element g location
var gloc = yearEnter.select(".gwrapper").selectAll("g")
.data(function(d){return d.values;});
gloc.exit().remove();
var glocEnter = gloc.enter()
.append("g")
.classed("loc",true);
glocEnter.append("rect");
;
glocEnter = glocEnter.merge(gloc);
// merge and position element wrappers
glocEnter
.attr("transform", function(d,i){return "translate("+[w/5*i]+")"});
var t = d3.transition().duration(1000);
glocEnter.select("rect")
.attr("x", (w/5 - 5)/2)
.attr("y", (w/5 - 5)/2)
.attr("width", 0)
.attr("height", 0)
.attr("fill", "black")
.transition(t)
.attr("x", 5)
.attr("y", 0)
.attr("width", w/5 - 5)
.attr("height", w/5 - 5)
.attr("fill", function(d){return d.value});
}
// on button click change the subset of data being used
d3.selectAll(".month").on("click", function(){
render("#toggle",this.getAttribute("data-month"))
})
d3.selectAll("#clearb").on("click", function(){
d3.selectAll("g.loc").remove();
})
render("#toggle","Jan")
感謝這個,它的偉大工程。雖然如果這是它應該完成的方式,我不太明白這裏的第二個示例如何工作https://github.com/d3/d3-selection/issues/86#issuecomment-289087950而不重新綁定數據 – Yanofsky
@ Yanofsky根據Mike Bostock的消息,我已經更新了答案。 – Marcelo