我在D3中嵌套,在嵌套元素中,我需要在其父元素上访问数据对象。
现在我正在做
d3.select(this).node().parentNode.__data__;
有更好的方法吗?
答案 0 :(得分:67)
d3.select(this).node()
与传递给D3选择的函数的上下文中的this
相同。您可以像d3.select(this.parentNode).datum()
一样重做它,并获得正确的值,而不必使用丑陋的双下划线属性。
答案 1 :(得分:19)
我熟悉的另一种方法是在父节点上使用.each()
,然后处理封闭内的子节点:
d3.selectAll('.parent').each(function(parentDatum) {
d3.select(this).selectAll('.child').each(function(childDatum) {
// do stuff with parentDatum and childDatum here
});
});
答案 2 :(得分:7)
当我遇到完全相同的问题时,我发现了这篇文章。我的解决方案是更改选择以传递我在子级中需要的数据,如果您可以使用节点中的数据冗余,我认为这可能是一种有效的方法。
[
{
title: "Google",
link: "www.google.com",
languagePath : "en,fr,it"
},
...
]
为了帮助解释,我在一个表的上下文中使用了这个,有两列。第一列包含title
,第二列包含每个a
项的accept-language
。
因此,我对languagePath
的分割进行了子选择,对于每个enter
调用,我会创建一个a
,其中的文字是语言。
所以此时我还需要link
,以便a
元素看起来像:
<a href="www.google.com/en">EN</a>
<a href="www.google.com/fr">FR</a>
但是link
不是传递给这个孩子的数据的一部分,所以当我做选择而不是做:
var langLinks = tableRow
.append("td")
.selectAll("span")
.data(function(d) {
return d.languagePath.split(",")
})
我做了
var langLinks = tableRow
.append("td")
.selectAll("span")
.data(function(d) {
return d.languagePath.split(",").map(function(item) {
return {
lang : item,
link : d.link
})
})
因此,当我在此选择的data
处理enter()
时,我确实拥有了父母的数据。
希望这对你们中的一些人来说是一个有效的选择,它确实帮助了我。