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

Fra*_*sKR 14 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();
Run Code Online (Sandbox Code Playgroud)

......但我不确定我是否应该修改.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);
}
Run Code Online (Sandbox Code Playgroud)

...但是index当我创建力时,属性才会被覆盖.

我读了这个问题,但唯一的答案似乎有点像黑客.他们还提到了"数据键",但我找不到那些,我不知道如何合并它们,因为我实际上并没有使用这个enter()功能.

Pab*_*rro 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();
Run Code Online (Sandbox Code Playgroud)

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