隐藏不相关的父节点,但在D3.js中隐藏子节点

时间:2015-04-26 04:59:30

标签: javascript jquery d3.js

我正试图在D3.js中做这件事,但无法找到办法。

我想要做的是,当一个人点击根节点(级别0)时,它应该显示子元素(级别1)。当一个人点击其中一个子节点(级别1)时,它应该显示其子级(级别2)和父级和父级父级(级别1,这是用户单击的),但隐藏所有不相关的父级(从1级开始。

让我用图片向你解释。

Node Diagram

1 个答案:

答案 0 :(得分:7)

您可以执行http://bl.ocks.org/benlyall/4fea200ebebb273aa4df

之类的操作

我分叉http://bl.ocks.org/mbostock/4339083并进行了一些更改:

  1. 为每个节点.all_children添加了一个新属性,用于跟踪所有子节点。我们需要这个或类似的东西,因为.children包含当前显示的子节点,并且现有代码使用._children来确定节点是否包含子节点(并相应地设置样式)。 / p>

    还添加了.hidden属性,以帮助确定是否应显示该节点。

    加载数据后添加:

    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. 更新了update函数以反映新的更改,并仅绘制应该绘制的节点:

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

    nodes变量设置为仅包含未隐藏的节点。

  3. 更新了click处理程序,以正确设置显示中节点的状态:

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

    当我们折叠节点时调用if语句的第一部分,在这种情况下,我们需要通过将d.parent.children设置为{{来显示所单击节点的所有兄弟节点1}}并将每个节点设置为d.parent.all_children。我们需要设置.hidden = false,然后将d.children = null中的每个节点设置为隐藏,隐藏所点击节点的所有子节点。

    我们在扩展节点时会调用d._children语句的第二部分,在这种情况下,我们需要隐藏其兄弟节点(将if设置为.hidden)并更新单击节点的true节点的.children属性,以便仅将单击的节点列为子节点。