我是D3.js初学者,致力于网络可视化,我无法弄清楚如何正确指定力布局的链接。问题是默认情况下,d3将链接的“源”和“目标”解释为“节点”数组中节点的索引。但是,在我的数据中,源和目标引用节点的id号,我将其存储在节点属性中。如何获取指向node.id
而非node.index
的链接?这是我想我应该这样做的地方:
var nodes = data.nodes;
var edges = data.edges;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(edges)
.size([w, h])
.linkDistance(80)
.charge(-500)
.gravity(0.2)
.on("tick", tick)
.start();
...但我不确定是否应修改.nodes()
部分或.links()
部分。我尝试在它之前添加它:
var nodes = data.nodes;
for (var i = 0; i < nodes.length; i++) {
nodes[i].index = nodes[i].id;
console.log(i + " " + nodes[i].index + " " + nodes[i].id);
}
...但是当我创建力时,index
属性才会被覆盖。
我读了this个问题,但唯一的答案似乎有点像黑客。他们还提到了“数据键”,但我找不到那些,我不知道如何将它们合并,因为我实际上并没有使用enter()
函数。
答案 0 :(得分:22)
我不认为您可以强制D3使用属性node.id
作为索引,但您可以处理链接以获得正确的引用:
var edges = [];
data.edges.forEach(function(e) {
// Get the source and target nodes
var sourceNode = data.nodes.filter(function(n) { return n.id === e.source; })[0],
targetNode = data.nodes.filter(function(n) { return n.id === e.target; })[0];
// Add the edge to the array
edges.push({source: sourceNode, target: targetNode});
});
var force = d3.layout.force()
.nodes(data.nodes)
.links(edges)
// the rest of your code here
.start();
如果设置了强制布局,则会覆盖索引,但会保留链接中每个节点的源和目标的引用。