我已经为使用新的选择合并制定了一致的模式,这对于数据和/或比例可能会更改的可重用图表非常有用。
我也一直在成功使用键功能。
但是,当输入并添加具有多个元素的组时,似乎出现问题。数据已在组中成功更新,但未成功附加元素。
我已经通过添加修复程序来解决这个问题(请参见下文),但是我确定确实很明显,需要对其进行更改以解决它。
有什么想法吗?
//define data group
var my_group = svg.selectAll(".data_group")
.data(my_data,function(d){return d.id});
//enter new groups
var enter = my_group.enter()
.append("g")
.attr("class","data_group");
//append items to group
enter.append("text").attr("class","group_item group_text")
enter.append("circle").attr("class","group_item group_circle");
//merge and remove
my_group.merge(enter);
my_group.exit().remove();
//fix added to reset changing data for bars.
d3.selectAll(".group_item").each(function(d){
d3.select(this)._groups[0][0].__data__ = d3.select(this)._groups[0][0].parentElement.__data__;
});
d3.selectAll(".group_text")
.... add properties to text - ie x,y,fill,text-anchor,text
d3.selectAll(".group_circle")
.... add properties to circle - ie cx,cy,fill,stroke,radius
答案 0 :(得分:1)
绝对不需要选择父组,获取其数据并将其重新绑定到子元素,就像您的问题和其他答案中的代码一样。这是向后弯曲。另外,请勿按照建议删除/重新添加元素,这不是惯用的D3方法。
事情很简单:新数据存在于“输入”选择中的子元素中。您只需要使用父母的选择(与select()
一起传播它们即可。
这是使用(大部分)代码的基本演示。该代码生成1到5个数据对象,并具有一个称为someProperty
的随机属性。您会看到,使用each()
,仅更改了“ enter”选择中的子元素:
var svg = d3.select("svg");
d3.interval(function() {
var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
return {
id: "id" + d,
"someProperty": ~~(Math.random() * 100)
}
});
update(data);
}, 2000);
function update(my_data) {
var my_group = svg.selectAll(".data_group")
.data(my_data, function(d) {
return d.id
});
my_group.exit().remove();
var enter = my_group.enter()
.append("g")
.attr("class", "data_group");
enter.append("text").attr("class", "group_item group_text")
enter.append("circle").attr("class", "group_item group_circle");
my_group = my_group.merge(enter);
console.log("---")
d3.selectAll(".group_text").each(function(d) {
console.log(JSON.stringify(d))
});
}
.as-console-wrapper { max-height: 100% !important;}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
现在,如果我们使用您父母的选择...
my_group.select(".group_text").each(function(d) {
console.log(d)
})
...您会看到所有属性已更新:
var svg = d3.select("svg");
d3.interval(function() {
var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
return {
id: "id" + d,
"someProperty": ~~(Math.random() * 100)
}
});
update(data);
}, 2000);
function update(my_data) {
var my_group = svg.selectAll(".data_group")
.data(my_data, function(d) {
return d.id
});
my_group.exit().remove();
var enter = my_group.enter()
.append("g")
.attr("class", "data_group");
enter.append("text").attr("class", "group_item group_text")
enter.append("circle").attr("class", "group_item group_circle");
my_group = my_group.merge(enter);
console.log("---")
my_group.select(".group_text").each(function(d) {
console.log(d)
})
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
最后,在您现在删除的答案中,您正在使用my_group.selectAll()
。问题是selectAll()
不会传播数据。
看看我做的这张桌子:
+------------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+------------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+------------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+------------------+----------------------------------+----------------------------+
| Data propagation | Propagates data | Doesn't propagate data |
+------------------+----------------------------------+----------------------------+
请注意传播数据与不会传播数据。
答案 1 :(得分:0)
复制绑定到父g
元素的数据的更多d3方法
无需添加修复程序
d3.selectAll(".group_text")
.datum(function () { return d3.select(this.parentNode).datum(); } )
// .... add properties to text - ie x,y,fill,text-anchor,text
d3.selectAll(".group_circle")
.datum(function () { return d3.select(this.parentNode).datum(); } )
// .... add properties to circle - ie cx,cy,fill,stroke,radius