【问题标题】:D3 force-directed graph - filter nodes and associated linksD3 力有向图 - 过滤节点和关联链接
【发布时间】:2016-10-26 17:09:35
【问题描述】:

我在尝试在力导向图上使用的过滤器时遇到问题。我可以过滤掉节点,但不能使关联的链接消失。我对 JavaScript 的了解非常有限,但我想逻辑应该是:如果节点被隐藏,则隐藏关联的链接。我在正确的道路上吗? 如果有人可以帮助我,将不胜感激!

数据格式:

{
  "nodes": [
{"name":"AA1","group":"Group1","type":"a"},
{"name":"AA2","group":"Group2","type":"b"},
{"name":"AA3","group":"Group3","type":"c"},
{"name":"AA4","group":"Group4","type":"a"},
{"name":"AA5","group":"Group2","type":"b"},
{"name":"AA6","group":"Group4","type":"c"},...
],
  "links": [
{"source":1,"target":59,"value":1},
{"source":1,"target":88,"value":1},
{"source":3,"target":12,"value":1},
{"source":3,"target":16,"value":1},
{"source":3,"target":87,"value":1},
{"source":5,"target":3,"value":1},
{"source":5,"target":16,"value":1},
{"source":5,"target":114,"value":1},...  ]

过滤器代码:

 // call method to create filter
createFilter();
// method to create filter
function createFilter()
{
    d3.select(".filterContainer").selectAll("div")
      .data(["a", "b", "c"])
      .enter()
      .append("div")
          .attr("class", "checkbox-container")
      .append("label")
      .each(function(d) {
         // create checkbox for each data
      d3.select(this).append("input")
        .attr("type", "checkbox")
        .attr("id", function(d) {return "chk_" + d;})
        .attr("checked", true)
        .on("click", function(d, i) {
            // register on click event
            var lVisibility = this.checked? "visible":"hidden";
            filterGraph(d, lVisibility);
        })
        d3.select(this).append("span")
          .text(function(d){return d;});
      });

      $("#sidebar").show();  // show sidebar
}

 // Method to filter graph
function filterGraph(aType, aVisibility)
{   
 // change the visibility of the node

    node.style("visibility", function(o) {
    var lOriginalVisibility = $(this).css("visibility");
    return o.type === aType ? aVisibility : lOriginalVisibility;
    }); 

///////////////////////////////// 隐藏链接所需的代码 ////////////////////////////////

}

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    您需要通过检查是否未选择其源或目标来隐藏链接。所以在你的 filterGraph 部分,添加类​​似的东西(假设你的链接有 class="link"):

    positive = ["Dahlia", "Tholomyes"];
    link.attr("display", function (o) {
    
    ////Here the structure of the the link can vary, sometimes it is o["source"]["name"], sometimes it is o["source"]["name"], check it out before you fill in.
    var source_name = o["source"]["id"];
    var target_name = o["target"]["id"];
    
    var result = positive.indexOf(source_name) != -1 && positive.indexOf(target_name) != -1 ? "auto" : "none"
    
    return result;
    
    });
    

    以 Mike Bostock 的悲惨为例,我已经使用上面的代码过滤掉了所有其他代码,除了连接“Dahlia”和“Tholomyes”的代码。

    这是您的 jsfiddle 示例的 sn-p:

    var hidden_nodes =[];
     // Method to filter graph
    function filterGraph(aType, aVisibility)
    {   
     // change the visibility of the node
     // if all the links with that node are invisibile, the node should also be invisible
    // otherwise if any link related to that node is visibile, the node should be visible
    // change the visibility of the connection link
    
    
        node.style("visibility", function(o) {
            var lOriginalVisibility = $(this).css("visibility");
            if (o.type == aType) {
                if (aVisibility == "hidden")
                    {
                        hidden_nodes.push(o.name);
                    }
                else
                    {
                        index = hidden_nodes.indexOf(o.name);
                        if (index > -1) 
                        {
                            hidden_nodes.splice(index, 1);
                        }
                    }
            }
            return o.type === aType ? aVisibility : lOriginalVisibility;
    
        }); 
    
    
        link.attr("display", function (o) {
        ////Here the structure of the the link can vary, sometimes it is o["source"]["name"], sometimes it is o["source"]["name"], check it out before you fill in.
        var source_name = o["source"]["name"];
        var target_name = o["target"]["name"];
    
    
        var result = hidden_nodes.indexOf(source_name) != -1 || hidden_nodes.indexOf(target_name) != -1 ? "none" : "auto"
    
        return result;
    
        });
    }
    

    【讨论】:

    • 我可以想象你需要一些调整才能让我的代码在你的脚本中工作。你能告诉我错误并显示你的“.link”创建代码吗?
    • 我猜你在拿迈克的悲惨例子 bl.ocks.org/mbostock/4062045?我已经编辑了我的代码,你需要积极的 =["Dahlia", "Tholomyes"] 行
    • 'positive =["Dahlia", "Tholomyes"]' 只是 Mike 示例中的一个演示。在任何情况下,您都需要告诉“显示”设置器显示哪些节点。就我而言,我要求它检查我的“积极”。使“积极”全局,修改您的过滤器部分以填充“积极”列表,其余的将由我的代码完成。要恢复链接,您需要做的就是“link.attr("display", "auto");"当您取消选中复选框时。
    • if (o.type == aType) {positive.push(o.id);}
    • 嗨,您只需要进一步了解逻辑即可。现在我已经更正了它并在上面的答案中发布了解决方案。用我的 sn-p 替换你的。顺便说一句,通过隐藏一些节点,其他一些节点将变得未连接。例如,如果 AA1 仅连接到 AA2,反之亦然。现在如果你隐藏 AA1,我的函数也会隐藏它们之间的连接,有效地使 AA2 成为一个孤独的节点。
    猜你喜欢
    • 2020-09-01
    • 2013-01-14
    • 2019-04-23
    • 2023-03-20
    • 2021-04-03
    • 2018-02-18
    • 2013-09-01
    • 2012-02-03
    相关资源
    最近更新 更多