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
});
});