问题描述
我在力导向图上尝试使用的过滤器遇到困难.我可以过滤出节点,但是不能使关联的链接消失.我对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力导向图-过滤节点和关联的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!