Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3.js tree layout: collapsing other nodes when expanding one?

On a tree layout using d3.js (example), I'd like to collapse nodes that are not in the branch that has been clicked on.

For example, in the above demo, try the following:

  1. click on "Parent 1" (Child 1 and Child 2 are shown)
  2. click on "Child 1" (Child 1.1 is shown)
  3. click on "Child 2" (Child 2.1 is shown)

Now you should see both the children of "Child 1" and "Child 2".

I would like to have the following happen:

  1. click on "Parent 1" (Child 1 and Child 2 are shown)
  2. click on "Child 1" (Child 1.1 is shown)
  3. click on "Child 2" (Child 2.1 is shown, Child 1.1 is hidden)

So children of nodes other than on the "active" branch should be hidden.

How can I best approach this? (efficiently of course, as I'll be using a fairly large dataset)

like image 368
stephenhay Avatar asked Oct 23 '25 14:10

stephenhay


2 Answers

One simple solution is to modify the click function such that if the node has a parent, the parent's children are each collapsed, but only if the child isn't the node that was clicked on.

function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  // If the node has a parent, then collapse its child nodes
  // except for this clicked node.
  if (d.parent) {
    d.parent.children.forEach(function(element) {
      if (d !== element) {
        collapse(element);
      }
    });
  }
  update(d);
}

Updated jsbin: http://jsbin.com/etIJABU/2/edit

like image 87
t.888 Avatar answered Oct 25 '25 03:10

t.888


if you want to collapse other nodes only when you click on nodes with children, add "&& d.children" in the second IF..

function click(d) {
        if (d.children) {
          d._children = d.children;
          d.children = null;
        } 
        else {
          d.children = d._children;
          d._children = null;
        }
        if (d.parent && d.children) { //add here, 
          d.parent.children.forEach(function(element) {
        if (d !== element) {
        collapse(element);
        }});
      }
        update(d);
      }
like image 25
ramon prata Avatar answered Oct 25 '25 05:10

ramon prata