I am doing nesting in D3 and in a nested element, I need to reach data object on its parent.
Right now I am doing
d3.select(this).node().parentNode._
d3.select(this).node() is the same as just this in the context of a function passed to a D3 selection. You could rework it like this d3.select(this.parentNode).datum() and get the correct value back without having to use the ugly double-underscore property.
I found this post when I had exactly the same issue. My solution, was to change the selection to pass on the data that I will need in the child, which I think might be a valid approach if you can live with the data redundancy in the node.
[
{
title: "Google",
link: "www.google.com",
languagePath : "en,fr,it"
},
...
]
To help explain, I've used this in the context of a table, with two columns. The first column has the title and the second column has an a for each of the accept-language items.
So I did a sub selections of the split of languagePath and for each enter call, I would create a a with the text being the language.
So at this point I also need the link, so that the a elements look like:
<a href="www.google.com/en">EN</a>
<a href="www.google.com/fr">FR</a>
But the link is not part of the data passed to this child, so when I did the selection instead of doing:
var langLinks = tableRow
.append("td")
.selectAll("span")
.data(function(d) {
return d.languagePath.split(",")
})
I did
var langLinks = tableRow
.append("td")
.selectAll("span")
.data(function(d) {
return d.languagePath.split(",").map(function(item) {
return {
lang : item,
link : d.link
})
})
And so, when I'm processing data on the enter() of this selection I do have the parent's data.
Hope this is a valid alternative for some of you, it did help me.
The other method I'm familiar with is to use .each() on the parent, and then deal with children within the closure:
d3.selectAll('.parent').each(function(parentDatum) {
d3.select(this).selectAll('.child').each(function(childDatum) {
// do stuff with parentDatum and childDatum here
});
});