2017-01-03 106 views
2

美好的一天!JS/d3.js - 删除/合并d3.js节点图中的重复链接

我在JS/d3.js一个初学者,我目前工作的一个小项目。这里是我以前的问题:

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

//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] 
     });  
    } 
}); 

这种用于循环将理解导致重复的路线作为朋友是相互包容EAC的h其他。 (即S001A是S002A,S003A和S004A的朋友,S002A在他的'朋友'阵列中也有S001A)。

虽然我还以为只使用源/目标对其中source === this.id的,但我怕我会再省略一些对,这将影响到数据的完整性..

有没有一种方法可以迭代并从数组中删除配对?无论是通过修改当前的for-loop,还是对数据进行后期处理。

非常感谢您的帮助!

+1

前段时间我回答了一个类似的问题,检查解决方案是否适用于您的情况:http://stackoverflow.com/a/40167473/5768908 –

+1

非常感谢您的帮助!虽然排序功能在我的情况下不起作用,因为我正在比较字母数字值,但我确实设法以迂回的方式进行,尽管我知道这种方法会导致性能问题。我将在下面发布我的解决方案:) –

回答

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的帮助!干杯:)

+0

很高兴知道它的工作原理。 –

+0

再次感谢您的帮助! :) –