2013-05-29 3 views
13

Я начинающий D3.js, работающий над сетевой визуализацией, и не могу понять, как правильно указать мои ссылки для компоновки сил. Проблема в том, что по умолчанию d3 интерпретирует «источник» и «цель» ссылок как индексы узлов в массиве «узлы». Однако в моих данных источник и цель ссылаются на номера идентификаторов узлов, которые я сохранил в атрибуте узла. Как мне получить ссылки, чтобы указать на node.id вместо node.index? Вот где я предполагаю, что я должен сделать это:D3: Использование атрибута узла для ссылок вместо индекса в массиве

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().

ответ

21

Я не думаю, что вы можете заставить 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(); 

Компоновка сила перезаписывать индекс, если вы установите он, но сохранит ссылки для источника и цели каждого узла в ссылках.

+0

Это не сработало ... что вы подразумеваете под «Предположим, что ключ в объекте узлов является id»? Разве 'data.nodes []' просто доступ к узлам по индексу массива, когда я должен делать это по id каким-то образом? – FrancesKR

+0

Да, извините, я сделал неправильное предположение о вашей структуре данных. Я обновил код соответствующим образом. –

+0

Хорошо, спасибо, что работает! У меня также был атрибут 'type' для ребер, поэтому мне пришлось добавить это, когда я нажимал каждое ребро, то есть' edge.push ({source: sourceNode, target: targetNode, type: e.type}) ' – FrancesKR