Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3js v3: Selecting a Node on click

I think I don't understand how D3 works with its Nodes.

I'm loading a JSON file (hierarchical Array):

d3.json('readme.json', function(error, data){
    nodes = tree.nodes(data); 

And I'm appending groups (and rects and other svg objects) into a svg container:

var gNodes = svgContainer
    .selectAll(".node")
    .data(nodes)
    .enter()
        .append("g")
        .attr("transform", "translate("+2000+","+0+")")
        .on("click", toggle);

What I want to do now is hiding a node's children by clicking on a node (which has a size which is visible via rect svg object) but I could not manage to get it to work.

I have a function toggle:

function toggle(d)

Which is used via click on the node (see var gNodes above).

In toggle I can use d.children and via debugger I can see that he finds the correct nodes.

But how can I remove the nodes and the rects and so on in the svgContainer? it doesn't work like this:

d.children.exit().remove();

I think this .exit().remove() would work on a selection and d.children is not a selection (it is the data inside it?).

But there has to be a way to remove the children of a node in a tree with D3. How can I do that?

like image 432
alloisxp Avatar asked May 18 '26 18:05

alloisxp


1 Answers

Two things:

  1. You are correct: d here refers to the datum, not to the selection (and also not to the DOM element)
  2. exit() depends on the DOM element having no datum. All the elements here have data. Therefore, use remove() alone.

Since you didn't posted your running code, I'll base my answer in this example from Mike Bostock.

You can select the DOM element based on its datum by filtering a selection. In D3 v4, you can use node.descendants() to get all the descendants of the node (children will get only the direct descendants), filtering the node selection itself, and then removing the elements:

node.on("click", function(d) {
    node.filter(function(e) {
        return d.descendants().splice(1).indexOf(e) > -1
    }).remove();
})

Here is the modified bl.ocks, click on the nodes: https://bl.ocks.org/anonymous/269149545ba97c2c0b20c1c2ea0a91d8/72df7ad28935168f07cc33a92f31752849779378

PS: I'm removing only the nodes, not the links.

PPS: remove is different from hide. You have to decide what do you want to do with the DOM element.

like image 79
Gerardo Furtado Avatar answered May 20 '26 06:05

Gerardo Furtado