JS / d3.js - 删除/合并d3.js节点图中的重复链接

时间:2017-01-03 07:08:32

标签: javascript arrays json d3.js

美好的一天!

我是js / d3.js的初学者,我目前正在开展一个小项目..这是我以前的问题:

我的项目旨在根据用户输入动态创建源和目标对。但是,在这样做的过程中,我有几个带有重复链接的节点。经过进一步检查,我意识到这可能是由于创建的数组中的Source / Target元素重复。以下是'links'数组中发生的事情的摘录:

//Source and target are unique identifiers of each datastruct
source: S001A, target: S002A
source: S001A, target: S003A
source: S001A, target: S004A       
source: S002A, target: S001A //Duplicate
source: S002A, target: S005A
source: S003A, target: S001A //Duplicate
source: S003A, target: S006A
source: S004A, target: S001A //Duplicate
                  ...

这是因为我的原始数据有一个“朋友”的嵌套数组,这里是数据集中的一个示例条目:

{
   "NRIC": "S001A",
   "name": "Benjamin",
   "blk": 123,
   "estate": "Woodlands",
   "street": "Woodlands Street 12",
   "unitNo": "01-23",
   "postal": 123123,
   "school": "Nanyang Technological University",
   "Friends": //Nested array..
   [
      "S002A",
      "S003A",
      "S004A",
   ]
}

这是我用来为嵌套数据创建源目标数组的for循环:

graphData.forEach(function(gdata,index)
{
    for (i = 0; i < gdata.Friends.length; i++)
    {
        links.push({
            source: gdata.NRIC,
            target: gdata.Friends[i]
        });     
    }
});

这个for循环可以理解地导致重复,因为朋友互相包容。 (即S001A是S002A,S003A和S004A的朋友.S002A也会在他的'Friends'阵列中有S001A。)

虽然我只考虑使用source === this.id的源/目标对,但我担心我可能会省略一些对,这会影响数据的完整性。

有没有办法可以迭代并从数组中删除配对?通过修改当前的for循环,或者进行数据的后处理..

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

感谢@Gerardo Furtado的帮助!

我稍微调整了解决方案,因为我需要对字母数字值进行排序,但这是我的工作答案:

graphData.forEach(function(gdata,index)
{
    for (i = 0; i < gdata.Friends.length; i++)
    {
        links.push({
            source: gdata.NRIC,
            target: gdata.Friends[i]
        });     
    }
});

links.forEach(function(d) {
    var sourceTemp = d.source, targetTemp = d.target;
    if (d.source > d.target)
    {
        d.source = targetTemp;
        d.target = sourceTemp;
    }
});

//links.sort(); doesn't work as item to be sorted may be alphanmueric :(
var linkslength = links.length;

links.forEach(function(d,i)
{
    var curSrc = d.source, curTgt = d.target;
    for(var j = i+1; j < linkslength; j++)
    {
        if (links[j].source === curSrc && links[j].target === curTgt)
        {
            links.splice(j,1);
            linkslength -= 1;
        }
    }
}); 

我知道这是一个非常优化的版本,有没有办法优化我必须循环的次数?另外,我担心在每次拼接后,links.length不会自动更新,因此我将其存储到变量中,并在每次拼接后手动减少它。

谢谢Gerardo Furtado和SO的帮助!干杯:)