D3.js可折叠树 - 展开/折叠中间节点

问题描述:

我有一个D3.js collapsible tree它有一堆节点。树中有几条路径,其中只有一个孩子的节点序列。想象一下这棵树:D3.js可折叠树 - 展开/折叠中间节点

   5 
      /
1 - 2 - 3 - 4 -6 
       \ 
       7 

当点击1节点,我希望它变成:

 5 
    /
1 - 4 -6 
    \ 
     7 

现在我的代码扩展和正常崩溃节点。我如何选择这些中间节点节点,以便我可以像我现在那样使用切换功能来定位它们?

我的代码基本上和例子中的一样,除了我添加的一些与这个问题无关的东西。 toggle()函数收到指向node的指针,并使可见子节点(在children数组中)不可见(通过将它们移动到它们的_children数组中)。这对所有特定的节点都有全部孩子(以及孙辈,曾孙,......),但是我需要它继续,而它找到的节点正好是 1孩子,那么,如果它发现一个节点没有孩子,我希望它可以看到;如果节点有一个以上的孩子,我希望它从这一点显示所有人。

这是在一个节点的onclick称为toggle()功能代码:

function toggle(d) { 
    var myLength; 
    if(d.children){myLength = d.children.length;} 
    else{myLength=0;} 

    if (myLength === 1) { 
     //next will be the first node we find with more than one child 
     var next = d.children[0]; 
     for (;;) {if(next.hasOwnProperty('children')){ 
      if (next.children.length === 1) { 
       next = next.children[0]; 
      } else if (next.children.length > 1) { 
       break; 
       } 
      } else { 
       // you'll have to handle nodes with no children 
       break; 
      } 
     } 
     d._children = d.children; 
     d.children = [next]; 
    }else{ 
     if (d.children) { 
      d._children = d.children; 
      d.children = null; 
     } else { 
      d.children = d._children; 
      d._children = null; 
     } 
    } 
} 

那切换功能没有做任何类型的逻辑检查的,它只是删除,并增加了孩子。要做你想做的事,你需要使用一些逻辑和数据遍历,但这不是不可能的。尝试是这样的:

function toggle(d) { 
    if (d.children.length === 1) { 
     //next will be the first node we find with more than one child 
     var next = d.children[0]; 
     for (;;) { 
      if (next.children.length === 1) { 
       next = next.children[0]; 
      } else if (next.children.length > 1) { 
       break; 
      } else { 
       //you'll have to handle nodes with no children 
      } 
     } 

     d._children = d.children; 
     d.children = [next]; 
    } 
} 
+0

谢谢您的回复!无孩子的节点实际上并不需要任何特定的行为 - 即它们不是_toggable_。除了反向操作之外,这大部分都可以工作 - 当我点击一个折叠的序列时,它不会再次展开。另外,如果序列在无子节点结束,我也不能折叠它。有什么想法吗? – Joum

+0

哦!并且有超过1个孩子的节点不再可折叠,或者:.. S – Joum

+0

我对你的例子进行了调整,现在,具有多于1个孩子的节点表现得像他们应该做的那样。单个子节点序列中的节点会崩溃,但不会展开。如果序列以无孩子的节点结束,则不会折叠/展开。检查我上面的更新代码。 – Joum

function toggleChildren(d) { 

    var myLength; 

    if (d.toggle !== "close") { 
     if(d.children){ 
      myLength = d.children.length; 
     }else{ 
      myLength=0; 
     } 
     d._children = d.children; 
     if (myLength === 1){ 
      //next will be the first node we find with more than one child 
      var next = d.children[0]; 
      for (;;) {if(next.hasOwnProperty('children')){ 
       if (next.children.length === 1) { 
        next = next.children[0]; 
       } else if (next.children.length > 1) { 
        break; 
       } 
      } else { 
       // you'll have to handle nodes with no children 
       break; 
      } 
      } 
      d.children = [next]; 
      //d._children = d.children; 
      d.toggle = "close" 
     }else{ 
      if (d.children) { 
       d._children = d.children; 
       d.children = null; 
      } else { 
       d.children = d._children; 
       d._children = null; 
      } 
     } 
    }else{ 
     if(d.toggle == "close"){ 
      var _children = d.children; 
      d.children = d._children; 
      d._children = _children; 
      d.toggle = "open" 
     }else{ 
      if (d.children) { 
       d._children = d.children; 
       d.children = null; 
      } else { 
       d.children = d._children; 
       d._children = null; 
      } 
     } 

    } 
    return d; 
} 
+0

您能否提供更多洞察力来解决您的问题? – lemieuxster