背景:项目 vue.js + d3 v4
力导向图可以直观看出各个元素之间的相互作用力
数据:
{
nodes:[{id:xxx, group: xx},{},...] // nodes 是每个节点 group 是聚类后的分组 为了让每个 circle 显示不同分组的颜色
links:[{target:xxx, source:xxx, value:xx },...] // links 为连线 value 可以代表 line 的 stroke-width
}复制代码
具体的代码就不贴了,官网很多 demo 都可以直接拿来用
效果如下:
在这里介绍几个点..
1.有的时候我们需要让他们之间分隔的间隔大一点,需要修改的地方:
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody().strength(-200).distanceMax(100)) // strength 默认 -30
.force("center", d3.forceCenter(width / 2, height / 2));
复制代码
2.当我们鼠标移到某个点的时候,想让与之相连的 circle fill + line stroke 高亮显示:
这里注意一下 鼠标移出的时候 样式恢复到之前的样式
ps:我们的link数据有一些重复的,所以要考虑到 target 和 source 相反的情况
.on("mouseover", function(d, i, o) {
let currentd = d.id
var connectedNodeIds = graph
.links
.filter(x => x.source.id == d.id || x.target.id == d.id)
.map(x => x.source.id == d.id ? x.target.id : x.source.id)
d3.select(".nodes")
.selectAll("circle")
.attr("fill", function(c) {
if (connectedNodeIds.indexOf(c.id) > -1 || c.id == d.id) return "red";
else return '#e49433'
})
d3.select(".links")
.selectAll("line")
.style("stroke", function(d,c) {
if ((d.target.id === currentd && connectedNodeIds.indexOf(d.source.id) > -1) || (d.source.id === currentd && connectedNodeIds.indexOf(d.target.id) > -1)) {
return 'red'
} else {
return '#999'
}
})
})
.on("mouseout", function(d) {
d3.select(".nodes")
.selectAll("circle")
.attr("fill", "#e49433");
d3.select(".links")
.selectAll("line")
.style("stroke", '#999')
})
复制代码