D3: использование атрибута node для ссылок вместо индекса в массиве
Я начинаю D3.js, работая над сетевой визуализацией, и я не могу понять, как правильно указать мои ссылки для компоновки силовых установок. Проблема в том, что по умолчанию d3 интерпретирует "источник" и "цель" ссылок как индексы узлов в массиве "узлы". Однако в моих данных источник и цель ссылаются на номера идентификаторов узлов, которые я сохранил в атрибуте node. Как получить ссылки, чтобы указать 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
просто перезаписывается, когда я создаю силу.
Я читаю этот вопрос, но единственный ответ там кажется немного взломанным. Они также упоминают "ключи данных", но я не могу их найти, и я не знаю, как их включить, поскольку на самом деле я не использую функцию enter()
.
Ответы
Ответ 1
Я не думаю, что вы можете заставить 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();
Схема синтаксиса переписывает индекс, если вы его установили, но сохранит ссылки для источника и цели каждого node в ссылках.