我处于一种独特的困境中。我有一个d3强制图,其功能是随着时间的推移读入JSON s 。我有一个方法可以读入数据并将链接/节点推送到一个用于“更新”图形的数组中。它看起来像这样:
var edges = [];
var nodes = [];
// pushes the NODE attributes in the JSON to the nodes array.
json.nodes.forEach(function(n) {
nodes.push({
data: n.data,
selected: n.selected,
removed: n.removed
});
})
// sets the source and target to use id instead of index
json.edges.forEach(function(e) {
var sourceNode = nodes.filter(function(n) {
return n.data.id === e.data.source;
})[0],
targetNode = nodes.filter(function(n) {
return n.data.id === e.data.target;
})[0];
// push the EDGE attributes in the JSON to the edges array.
edges.push({
source: sourceNode,
target: targetNode,
data: e.data
});
});
force
.nodes(nodes)
.links(edges)
因此源/目标基于节点的ID。
现在的问题是当JSON数据被读取时有时它会带有已经存在于图中的节点,因为这些节点连接到一些新的节点。新数据完全与新图形链接并起作用。但是,重复的节点只是悬空。我不能使用只检查节点是否有weight
的函数,因为我有一个删除功能可以让一些节点浮动。
另外,如果我只是检查数组中的重复项,然后才能读入force.nodes(nodes).links(edges)
它会开始变慢,因为你总是检查所有节点(对于ID)。我想知道在推到图表之前是否有办法检查它?
我想到的解决方案是使用地图而不是数组,但我不知道如何根据d.data ['id']检查它的唯一性,我不知道如何{{1使用我拥有的属性进入地图。我尝试过这样做......
put
但错误了。对我的方法有任何帮助或正确的方法如何做到这一点?
更新了代码段:
var nodes = {};
// pushes the NODE attributes in the JSON to the nodes MAP.
json.nodes.forEach(function(n) {
nodes[n.data['id']] = {
data: n.data,
selected: n.selected,
removed: n.removed
}
})
这仍然会生成重复的节点,但var edges = [];
var nodes = [];
var nodesHash = {};
// pushes the NODE attributes in the JSON to the nodes array.
json.nodes.forEach(function(n) {
nodesHash[n.data['id']] = n;
if (n.data['id'] in nodesHash) {
console.log("test break")
console.log(nodesHash);
nodes.push({
data: n.data,
selected: n.selected,
removed: n.removed
});
}
})
// sets the source and target to use id instead of index
json.edges.forEach(function(e) {
var sourceNode = nodes.filter(function(n) {
return n.data.id === e.data.source;
})[0],
targetNode = nodes.filter(function(n) {
return n.data.id === e.data.target;
})[0];
// push the EDGE attributes in the JSON to the edges array.
edges.push({
source: sourceNode,
target: targetNode,
data: e.data
});
});
force
.nodes(nodes)
.links(edges)
显示的内容类似于。
console.logs
如果展开其中的第一个test break
Object {idfoo: Object}
test break
Object {idfoo: Object, idbar: Object}
test break
Object {idfoo: Object, idbar: Object, idbash: Object}
test break
,它已经包含了所有节点ID(idfoo,idbar,idbash)的列表。
但是让我们说下一个JSON会经历这个过程。它会附加,例如2个节点进来......
Object {idfoo: Object}
请注意,idfoo有两次。但是如果你扩展最后一个Object {idfoo: Object, idbar: Object, idbash: Object, idnext: Object}
test break
Object {idfoo: Object, idbar: Object, idbash: Object, idfoo: Object, idnext: Object}
test break
然后在该列表中它将不包含2个idfoo。