Javascript 过滤并停用强制布局中的链接和文本
我使用D3.js中的force布局。 现在,我可以使用过滤器从任何移动中停用一些节点。在我的例子中,我过滤掉的节点是循环的Javascript 过滤并停用强制布局中的链接和文本,javascript,d3.js,nodes,simulation,force-layout,Javascript,D3.js,Nodes,Simulation,Force Layout,我使用D3.js中的force布局。 现在,我可以使用过滤器从任何移动中停用一些节点。在我的例子中,我过滤掉的节点是循环的else部分中的蓝色节点。 现在,单击“按钮”时,所有红色节点都会增加forceCollide值的大小 借助下面可以看到的if部分中的循环,如果firstTime为“true”,则可以使所有节点正常移动。 现在,我的问题是,我还没有找到,如何去激活连接到过滤后的蓝色节点的链接和文本?这意味着,我希望过滤节点的文本也得到过滤和停用,以及链接也得到过滤和停用。那么,我如何从属性节
else
部分中的蓝色节点。
现在,单击“按钮”时,所有红色节点都会增加forceCollide值的大小
借助下面可以看到的if
部分中的循环,如果firstTime
为“true”,则可以使所有节点正常移动。
现在,我的问题是,我还没有找到,如何去激活连接到过滤后的蓝色节点的链接和文本?这意味着,我希望过滤节点的文本也得到过滤和停用,以及链接也得到过滤和停用。那么,我如何从属性节点过滤得到链接和文本的连接呢?
谢谢大家
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
</style>
<div class="centre jumbotron">
</div>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<button>Click me</button>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var g = svg.append("g");
var firstTime = true;
var colours = ["blue", "red", "green", "yellow"];
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collide", d3.forceCollide(function(d) {
return d.r + 1;
}));
d3.json("https://jsonblob.com/api/6e520635-d35c-11e6-b16a-6b255c15b1a3", function(error, graph) {
if (error) throw error;
var link = g.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", 1);
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", (d, i) => colours[i % 2])
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var text = svg.append("g")
.attr("class", "labels")
.selectAll("text")
.data(graph.nodes)
.enter().append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.style("fill", (d, i) => colours[i % 2])
.text(function(d) { return d.group });
d3.select("button").on("click", function(d) {
firstTime = false;
node.filter(function() {
return d3.select(this).attr("fill") === "red"
}).each(d => d.r = 60);
simulation.nodes(graph.nodes);
simulation.alpha(0.8).restart();
})
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
link
.attr("x1", function(d) {return d.source.x;})
.attr("y1", function(d) {return d.source.y;})
.attr("x2", function(d) {return d.target.x;})
.attr("y2", function(d) {return d.target.y;});
if (firstTime) {
node.attr("cx", d => d.x).attr("cy", d => d.y);
} else {
node.filter(function(e) {
return d3.select(this).attr("fill") != "blue"
}).attr("cx", d => d.x).attr("cy", d => d.y);
}
text
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
}
});
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
</script>
.连接线{
行程:#999;
笔划不透明度:0.6;
}
.节点圆{
冲程:#fff;
笔划宽度:1.5px;
}
点击我
var svg=d3。选择(“svg”),
宽度=+svg.attr(“宽度”),
高度=+svg.attr(“高度”);
var g=svg.append(“g”);
var firstTime=true;
变量颜色=[“蓝色”、“红色”、“绿色”、“黄色”];
var simulation=d3.forceSimulation()
.force(“link”,d3.forceLink().id(函数(d){
返回d.id;
}))
.force(“电荷”,d3.forceManyBody())
.力(“中心”,d3.力中心(宽度/2,高度/2))
.力(“碰撞”,d3.力碰撞(功能(d){
返回d.r+1;
}));
d3.json(“https://jsonblob.com/api/6e520635-d35c-11e6-b16a-6b255c15b1a3,函数(错误,图形){
如果(错误)抛出错误;
var link=g.append(“g”)
.attr(“类”、“链接”)
.selectAll(“行”)
.数据(图表.链接)
.enter().append(“行”)
.attr(“笔划宽度”,1);
var节点=g.append(“g”)
.attr(“类”、“节点”)
.selectAll(“圆圈”)
.数据(图.节点)
.enter().append(“圆”)
.attr(“r”,5)
.attr(“填充”,(d,i)=>颜色[i%2])
.call(d3.drag()
.on(“开始”,拖动开始)
.打开(“拖动”,拖动)
。在(“结束”,dragended));
var text=svg.append(“g”)
.attr(“类别”、“标签”)
.selectAll(“文本”)
.数据(图.节点)
.enter().append(“文本”)
.attr(“dx”,12)
.attr(“dy”,“.35em”)
.style(“填充”(d,i)=>颜色[i%2])
.text(函数(d){return d.group});
d3.选择(“按钮”)。在(“点击”)上,功能(d){
第一次=错误;
node.filter(函数(){
返回d3。选择(此).attr(“填充”)=“红色”
}).每个(d=>d.r=60);
模拟.节点(图.节点);
simulation.alpha(0.8).restart();
})
模拟
.nodes(图.nodes)
。在(勾选)上;
模拟力(“链接”)
.links(图形链接);
函数勾选(){
链接
.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
如果(第一次){
node.attr(“cx”,d=>d.x).attr(“cy”,d=>d.y);
}否则{
节点过滤器(函数(e){
返回d3。选择(此).attr(“填充”)!=“蓝色”
}).attr(“cx”,d=>d.x”).attr(“cy”,d=>d.y);
}
文本
.attr(“x”,函数(d){return d.x;})
.attr(“y”,函数(d){返回d.y;});
}
});
函数dragstarted(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d、 fx=d.x;
d、 fy=d.y;
}
函数(d){
d、 fx=d3.event.x;
d、 fy=d3.event.y;
}
函数d(d){
如果(!d3.event.active)simulation.alphaTarget(0);
d、 fx=null;
d、 fy=null;
}
我为您的上一个问题编写了答案,建议在勾选功能中使用过滤器,因为我不知道您也有链接和文本。现在你有了一个不同的问题,你不能简单地将另一个问题的答案改写成现在这个问题:它们是不同的问题
对于本例,简单的解决方案是设置fx
和fy
属性。根据报告:
要将节点固定在给定位置,可以指定两个附加属性:
- fx-节点的固定x位置
- fy-节点的固定y位置
在每个刻度结束时,在施加任何力后,具有定义的node.fx的节点将node.x重置为该值,node.vx设置为零;同样,定义了node.fy的节点将node.y重置为该值,并将node.vy设置为零。要取消固定以前固定的节点,请将node.fx和node.fy设置为null,或删除这些属性
因此,您可以在“单击”功能中执行以下操作:
d3.select("button").on("click", function(d) {
//this will fix the blue nodes
node.filter(function() {
return d3.select(this).attr("fill") === "blue"
}).each(function(d) {
d.fx = d.x;
d.fy = d.y;
})
node.filter(function() {
return d3.select(this).attr("fill") === "red"
}).each(function(d) {
return d.r = 80
});
simulation.nodes(nodes);
simulation.alpha(0.8).restart();
})
这是一个演示。如果单击该按钮,红色圆圈将推开其他节点/文本,但蓝色圆圈将保留在该位置。文本和链接保持连接。拖动其中任何一个都将释放它
var宽度=400;
var高度=300;
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
变量节点=[{
姓名:"富",,
颜色:“蓝色”
}, {
名称:“酒吧”,
颜色:“绿色”
}, {
名称:“baz”,
颜色:“红色”
}, {
名称:“福福”,
颜色:“黄色”
}, {
名称:“foobar”,
颜色:“蓝色”
}, {
名称:“foobaz”,
颜色:“绿色”
}, {
名称:“巴福”,
颜色:“红色”
}, {
姓名:“芭芭拉”,
颜色:“黄色”
}, {
姓名:“barbaz”,
颜色:“蓝色”
}];
变量链接=[{
“来源”:0,
“目标”:1
}, {
“来源”:0,
“目标”:2
}, {
“来源”:0,
“目标”:3
}, {
“来源”:1,
“目标”:3
}, {
“来源”:1,
“目标”:4
}, {
“来源”:2,
“目标”:5
}, {
“来源”:3,
“目标”:6
}, {
“来源”:1,
“目标”:7
}, {
“来源”:6,
“目标”:8
}, {
“来源”:0,
“目标”:7
}, {
“来源”:2,
“目标”:6
}, {
“来源”:3,
“目标”:8
}];
var模拟=d3.1