Hello, I’m working on a view of a data tree and I want to be able to dynamically update the contents of the tree according to return values of Ajax requests. I implemented this before using d3 about 6 years ago, but with the current d3 I get bugs. Here is an example of the data I’m using:
{
"title": "root",
"children": [
{
"title": "First node.",
"children": [
{
"title": "Link to second node.",
"to": 1
}
]
},
{
"title": "Second node.",
"children": [
{
"title": "Link to third node.",
"bla": "One.",
"to": 2
}
]
},
{
"title": "Third node.",
"children": [
{
"title": "Link to first node.",
"to": 0
}
]
}
]
}
These are nodes in a simple triangular graph where each node links to the next one in order, with node 2 looping around to link to node 0. I’m placing them in a collapsible tree similar to this one. When I click on the circle representing a link to another node, I want that node to open underneath it as one of its children. You can explore the graph endlessly by doing this.
In my old codebase, I accomplished this with code similar to the following:
item.on('click', function (d) {
if (!d.children) {
if (d.data.to && !d._children) {
ajaxFetch(d.data.to, function (returned) {
returned.parent = d;
returned.depth = 1 + d.depth;
d.children = [returned];
// also recursively update depth of children
return update(d);
});
} else {
d.children = d._children;
d._children = null;
return update(d);
};
} else {
d._children = d.children;
d.children = null;
return update(d);
};
}
The update
function above is similar to the one used in the collapsible tree example. When I do this in my current codebase, there are many bugs. For one, the new children are not initialized as members of the Qd class. To solve this, I tried calling d3.hierarchy()
on each newly added node to make it a member of the Qd class. I then placed it in the children
array for the link I wanted and I set its depth and parent ids. However, there are still lots of problems. When doing the source and target calculations for new nodes, the source node for newly added nodes always registers as id 0 and not the id of the parent node I set.
This results in a bunch of odd rendering behaviors, like link lines sliding from node to node. When exiting a node, its circle also slides straight down out of the viewport instead of sliding up to the parent node while it fades. I don’t know if the “height” property of nodes has anything to do with this. I don’t think it was there when I last used d3 and from what I can tell it’s the opposite of “depth,” it’s the distance of a node from the furthest leaf, with the root always having the highest height value. Needless to say I can’t accurately specify a node height without iterating over the entire tree, which I would like to avoid for efficiency’s sake.
Can anyone recommend a good approach to something like this? This example is the only thing I’ve found that does something similar but it doesn’t use a hierarchy and its approach involves change the entire chart rather than making the kind of partial changes I’m aiming for. Thanks for reading.