2013-03-14 113 views
43

我正在做嵌套在D3和嵌套元素,我需要达到它的父母的数据对象。如何获取父节点的数据在d3.js

现在我做

d3.select(this).node().parentNode.__data__; 

有没有更好的办法?

+0

是不是'd3.select(this).node()'与'this'完全相同?我只是简单地使用'this.parentNode .__ data__'。 – 2015-11-16 22:10:35

回答

61

d3.select(this).node()是一样的只是this在函数传递的上下文到D3选择。您可以像这样将其重写为d3.select(this.parentNode).datum(),并且无需使用丑陋的双下划线属性即可获取正确的值。

+1

唉,这只有在父节点有附加数据时才可行。如果在两个节点之间有数据的中间节点(即,使用完全虚构的符号),则必须执行'parentNode.parentNode ',协商DOM而不是数据树。 – 2015-06-03 01:01:18

17

另一种方法是我所熟悉的是对父母使用.each(),然后关闭内的儿童打交道:

d3.selectAll('.parent').each(function(parentDatum) { 
    d3.select(this).selectAll('.child').each(function(childDatum) { 
     // do stuff with parentDatum and childDatum here 
    }); 
}); 
7

我发现这个职位,当我有完全相同的问题。我的解决方案是改变选择以传递我在孩子需要的数据,如果您可以接受节点中的数据冗余,我认为这可能是一种有效的方法。

[ 
    { 
    title: "Google", 
    link: "www.google.com", 
    languagePath : "en,fr,it" 
    }, 

    ... 
] 

为了有助于解释,我已经在一个表的上下文中使用了这个函数,它有两列。第一列为title,第二列为accept-language项目中的每一个都有a

所以我做了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()我有父母的数据。

希望这对你们中的一些人来说是一个有效的选择,它的确帮助了我。