【问题标题】:JS / d3.js - Removing/merging duplicate links in d3.js node graphJS / d3.js - 删除/合并 d3.js 节点图中的重复链接
【发布时间】:2017-05-17 05:31:56
【问题描述】:

美好的一天!

我是 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 循环,或对数据进行后处理..

非常感谢您的帮助!

【问题讨论】:

  • 我前段时间回答了一个类似的问题,请检查该解决方案是否适用于您的情况:stackoverflow.com/a/40167473/5768908
  • 非常感谢您的帮助!尽管在我比较字母数字值时排序功能在我的情况下不起作用,但我确实设法以一种迂回的方式做到了,尽管我知道这种方法会导致性能问题。我将在下面发布我的解决方案:)

标签: javascript arrays json d3.js


【解决方案1】:

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

【讨论】:

  • 再次感谢您的帮助! :)
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 2013-07-13
相关资源
最近更新 更多