简体   繁体   中英

Hide unrelated parent nodes but child node in D3.js

I'm trying to do this thing in D3.js but unable to find a way to do it.

What I want to do is, when a person clicks on the root node (level 0), it should show the child elements (level 1). When a person clicks on one of the child nodes (level 1) it should show its childrens (level 2) and the parent and parent-of-parent (level 1, this what the user clicked), but hide all the unrelated parents (from level 1).

Let me explain you this with pictures.

节点图

You could do something like http://bl.ocks.org/benlyall/4fea200ebebb273aa4df

I forked http://bl.ocks.org/mbostock/4339083 and made a few changes:

  1. Added a new property to each node .all_children which keeps track of all children. We need this, or something similar since .children contains the child nodes currently displayed, and ._children is used by the existing code to determine if a node contains children or not (and sets the style accordingly).

    Also added a .hidden property that helps to determine whether or not the node should be displayed.

    These are added after loading the data:

     d3.json("flare.json", function(error, flare) { root = flare; root.x0 = height / 2; root.y0 = 0; function collapse(d) { if (d.children) { d.all_children = d.children; d._children = d.children; d._children.forEach(collapse); d.children = null; d.hidden = true; } } root.all_children = root.children; root.children.forEach(collapse); root.children.forEach(function(d) { d.hidden = false; }); root.hidden = false; update(root); }); 
  2. Updated the update function to reflect the new changes and only draw the nodes that are supposed to be drawn:

     function update(source) { // Compute the new tree layout. var nodes = tree.nodes(root).filter(function(d) { return !d.hidden; }).reverse(), links = tree.links(nodes); 

    The nodes variable is set to only contain nodes that are NOT hidden.

  3. Updated the click handler to correctly set the state of the nodes in the display:

     // Toggle children on click. function click(d) { if (d.children) { d._children = d.children; d.children = null; if (d._children) { d._children.forEach(function(n) { n.hidden = true; }); if (d.parent) { d.parent.children = d.parent.all_children; d.parent.children.forEach(function(n) { n.hidden = false; }); } } } else { d.children = d._children; d._children = null; if (d.children) { d.children.forEach(function(n) { n.hidden = false; }); if (d.parent) { d.parent.children = [d,]; d.parent.children.filter(function(n) { return n !== d; }).forEach(function(n) { n.hidden = true; }); } } } update(d); } 

    The first part of the if statement is called when we're collapsing a node, in which case, we need to display all of the siblings of the clicked node by setting d.parent.children to d.parent.all_children and setting each of those nodes to .hidden = false . And we need to hide all the children of the clicked node by setting d.children = null and then setting each node in d._children to hidden.

    The second part of the if statement is called when we're expanding a node, in which case, we need to hide its siblings (set .hidden to true ) and update the .children property of the clicked node's .parent node so that only the clicked node is listed as a child.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM