D3:在链接中使用节点属性而不是数组中的索引

时间:2013-05-29 21:37:49

标签: d3.js force-layout

我是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()函数。

1 个答案:

答案 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();

如果设置了强制布局,则会覆盖索引,但会保留链接中每个节点的源和目标的引用。