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

时间:2013-07-03 13:07:39

标签: javascript arrays d3.js

我有一个D3.js collapsible tree,它有一堆节点。树中有一些路径,其中只有一个子节点的节点序列。想象一下这棵树:

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

单击1节点时,我希望它成为:

      5
     /
1 - 4 -6
     \
      7

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

我的代码与示例中的代码基本相同,除了我添加的一些与此问题无关的内容。 toggle()函数接收指向node的指针,并使可见的子节点(在children数组中)不可见(通过将它们移动到它们_children数组)。这会将所有子项(以及孙子,曾孙,......)命中到该特定节点,但我需要它继续找到完全 1的节点那么,如果它找到一个没有孩子的节点,我希望它是可见的;如果节点有多个子节点,我希望它从该点开始显示所有节点。

这是在其中一个节点中调用的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;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

该切换功能不进行任何类型的逻辑检查,它只是删除并添加子项。要做你想做的事,你需要使用一些逻辑和数据遍历,但这并非不可能。尝试这样的事情:

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];
    }
}

答案 1 :(得分:0)

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;
}