【问题标题】:D3 Force Layout: Collapse Subset of Child Nodes (Opacity Change)D3 强制布局:折叠子节点的子集(不透明度更改)
【发布时间】:2016-12-24 06:01:02
【问题描述】:

我正在使用 D3 强制布局并尝试折叠子节点,同时保持图形固定,例如只需更改它们及其链接的不透明度即可。但是,我并不想一次折叠所有节点 - 实际上我在每个节点中都有一个名为“组”的属性,可以是 1,2 或 3。

当我单击一个节点时,会出现一个工具提示,其中每个组都有 3 个按钮 - 单击正确的按钮后,我希望该类型的子节点折叠,但它的所有子节点(全部 3组)也可以折叠。

这里是fiddle

到目前为止,我尝试创建节点组 ID 和相应链接 ID 的数组,然后使用 JQuery 隐藏这些 DOM 对象,但这不起作用:

function collapseNodes(node, collapseType, isCollapsed) {
    var collapseData = minimise(node, collapseType);
    var cNodes = collapseData.nodes,
        cLinks = collapseData.links;
    console.log(collapseData);
    var newClass = isCollapsed ? "uncollapsed" : "collapsed";

    cNodes.forEach(function(n) {
        d3.select(n).style("opacity", 0);
    });

    cLinks.forEach(function(l) {
        d3.select(l).style("opacity", 0);
    });
}

function minimise(node, assetMinType = "") {
    // Function to minimise a node
    var minNodes = [];
    var minLinks = [];

    if (node.group == 'asset') {
        node.children.forEach(function(child) {
            if (child.group == assetMinType)
                minimiseRec(child, node.id);
        });
    }
    else {
        minimiseRec(node, "");

        // We want to keep the top node and link
        minNodes.shift();
        minLinks.shift();

    }

    function minimiseRec(node, parentID) {
        minNodes.push("#" + node.id);
        minLinks.push("#parent_" + parentID + "_child_" + node.address);

        node.children.map(function(child) {
            minimise(child, node.id);
        });
    }

    return { nodes: minNodes, links: minLinks };
}

有谁知道如何最好地做到这一点?

谢谢。

【问题讨论】:

    标签: javascript jquery d3.js force-layout


    【解决方案1】:

    如果它只是您希望更改的不透明度,这相当简单。我猜如果你隐藏一个节点孩子你想隐藏他们的孩子的孩子等等?

    首先我设置了一个变量d.hiddenNode。这样我就可以切换不透明度。我把它设置为假。然后点击功能:

    .on('click', function(d) {
        console.log(d);
        if(d.hiddenNode){
            hideChildren(d, false);
          d.hiddenNode = false;
        } else {
            hideChildren(d, true);
          d.hiddenNode = true;
        }
    
      })
    

    现在,因为您希望隐藏孩子的孩子等,您需要一个像这样的递归函数。隐藏链接和节点的一种(我已评论解释):

    function hideChildren(node, hide) {
    
      for (var i = 0; i < node.children.length; i++) {
        recurseChildren(node.children[i]); //loop through children to hide
      }
    
      function recurseChildren(node) {
    
        nodeEnter.each(function(d) { //go through all nodes to check for children
          if (d.index == node.index) { //if child is found
            d3.select(this).style('opacity', function(){ 
            return hide ? 0 : 1;        //toggle opacity depending on d.hiddenNode value
            }) //.remove(); 
          }
        })
    
        link.each(function(d) { //same with links
          if (d.source.index == node.index || d.target.index == node.index ) { //if source or target are hidden hide the link
            d3.select(this).style('opacity', function(){
            return hide ? 0 : 1;        
            }) //.remove(); 
          }
        })   
    
        if (node.children) { //if this node has children, call again but with their children
          for (var i = 0; i < node.children.length; i++) {
            recurseChildren(node.children[i]);
          }
        }
      }
    }
    

    这是更新后的小提琴:http://jsfiddle.net/thatOneGuy/3g4fqfa8/2/

    编辑

    对于弹出窗口,我刚刚创建了一个包含 3 个组 1、2、3 的 div:

    <div id='groupChoice'>
    <div id='group1' class = 'group' onclick='hideGroup(1)'>1</div>
    <div id='group2' class = 'group' onclick='hideGroup(2)'>2</div>
    <div id='group3' class = 'group' onclick='hideGroup(3)'>3</div>
    </div>
    

    在 CSS 中设置为隐藏:

    .group{
      width: 50px;
      height:50px;
      border : 1px solid black;
    }
    
    #groupChoice{
      visibility:hidden;
    }
    

    我稍微改变了逻辑,但这是带有评论的更新小提琴:http://jsfiddle.net/thatOneGuy/3g4fqfa8/3/

    需要对链接进行一些工作。我没有足够的时间来完成它,对不起。但这应该可以帮助您入门。

    基本上,当您单击一个节点时,弹出窗口,您选择一个要隐藏的组,它们会被隐藏。再次点击同一个节点,选择要显示的节点。这完成得非常快,所以它有很多问题,但基础是,所以它应该有所帮助:)

    【讨论】:

    • 对不起,我没有足够的时间来完成它。逻辑很简单,只要检查节点是否属于你要隐藏的组,是否隐藏它及其子节点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2014-10-24
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    相关资源
    最近更新 更多