D3力导向图-过滤节点和关联的链接 [英] D3 force-directed graph - filter nodes and associated links

查看:482
本文介绍了D3力导向图-过滤节点和关联的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在力导向图上尝试使用的过滤器遇到困难.我可以过滤出节点,但是不能使关联的链接消失.我对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;
    }); 

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

}

解决方案

您需要通过检查链接的源或目标是否未选中来隐藏该链接.因此,在您的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)的悲惨经历为例,我使用了上面的代码来过滤掉除连接大丽花"和"Tholomyes"的代码之外的所有其他代码.

这是您的jsfiddle示例的代码段:

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;

    });
}

I am having difficulties with the filter that I am trying to use on my force directed graph. I can filter out nodes, but cannot make associated links disappear. My knowledge of JavaScript is pretty limited, but I guess the logic should be: if node is hidden, then hide associated links. Am I on the right path? If someone could help me with it, it would be much appreciated!

Data format:

{
  "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},...  ]

FILTER CODE:

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

/////////////////////////////////////// NEEDED CODE TO HIDE LINKS //////////////////////////////////////

}

解决方案

You need to hide the link by checking if either its source or target is not selected. So in your filterGraph part, add something like (suppose your links have 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;

});

Take Mike Bostock's miserable for instance, I have used the code above to filter out all the others except the one that connects "Dahlia" and "Tholomyes".

Here is the snippet for your jsfiddle example:

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;

    });
}

这篇关于D3力导向图-过滤节点和关联的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆