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

asr*_*srm 3 javascript jquery d3.js

我想在D3.js做这件事,但无法找到办法.

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

让我用图片向你解释一下.

节点图

Ben*_*all 7

你可以做点什么,比如http://bl.ocks.org/benlyall/4fea200ebebb273aa4df

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

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

    还添加了一个.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);
    });
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    
    Run Code Online (Sandbox Code Playgroud)

    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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    在第一部分if的语句,当我们正在崩溃的一个节点,在这种情况下,我们需要通过设置来显示所有的点击节点的兄弟姐妹被称为d.parent.childrend.parent.all_children和设置每个这些节点的.hidden = false.我们需要通过设置d.children = null然后将每个节点设置d._children为隐藏来隐藏所点击节点的所有子节点.

    if当我们扩展节点时调用语句的第二部分,在这种情况下,我们需要隐藏其兄弟(设置.hiddentrue)并更新.children被点击节点的.parent节点的属性,以便只将被点击的节点列为子节点.