d3初始化前检查重复节点

时间:2015-05-13 15:59:42

标签: javascript arrays dictionary d3.js force-layout

我处于一种独特的困境中。我有一个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。

0 个答案:

没有答案