Я создал макет силы, используя d3, и он работает хорошо. Мои исходные данные загружаются из json файла, и диаграмма рисуется с помощью методов, которые аналогичны этому примеру d3.js:
Теперь, когда диаграмма находится на экране, мне нужно добавлять, обновлять и удалять узлы "на лету" из данных, которые я получаю через веб-сокет. У меня есть методы добавления и удаления, но я не могу найти правильный способ обновления существующих свойств node.
Из прочтения, которое я предпринял, я собираю правильную технику, чтобы изменить источник данных, а затем обновить диаграмму с помощью метода enter().
Чтобы обновить node, я делаю следующее:
function updateNode(id, word, size, trend, parent_id){
var updateNode = nodes.filter(function(d, i) { return d.id == id ? this : null; });
if(updateNode[0]){
updateNode.size = Number(size);
updateNode.trend = trend;
nodes[updateNode.index] = updateNode;
update();
}
}
Затем функция обновления обновляет узлы с помощью:
function update(){
node = vis.selectAll('.node')
.data(nodes, function(d) {
return d.id;
})
createNewNodes(node.enter());
node.exit().remove();
force.start();
}
function createNewNodes(selection){
var slct = selection.append('g')
.attr('class', 'node')
.call(force.drag);
slct.append('circle')
.transition()
.duration(500)
.attr('r', function(d) {
if(d.size){
return Math.sqrt(sizeScale(d.size)*40);
}
})
}
Я правильно подхожу к этому? Когда я пытаюсь использовать этот код, node я получаю в качестве базы данных при попытке установить атрибут radius на круге последний node в массиве узлов. То есть тот, который содержит иерархические node данные, а не один объект node.
Любые указатели будут очень благодарны, я потратил слишком много времени на это:)