如何检查节点是否相关?如果有两个邻居,我如何只选择一个邻居?

时间:2015-09-18 16:30:39

标签: javascript jquery d3.js

我在D3中有一个力布局。

我有很多节点都有链接加入它们。我的问题是,如果节点符合某个标准,我想删除链接。

说我有节点A,B,C。

说这个tilda角色 - '〜'意味着连接。

If (A~B && A~C && B~C){

DELETE THE A~C link. //which would leave A~B~C
}

我已尝试浏览每个链接:

link.forEach(function{d){ ....

但我似乎无法理解我将如何做逻辑。

我会经历每个节点3次,检查是否A~B,A~C,B~C,但如果我有100个节点,那将会非常慢。

任何帮助将不胜感激:)

以下是我当前的edge / links数组的外观:

edges = [
{
    "source": "A",
    "target": "B",
    "other information" : "randomstring",
    "other information" : "randomstring"
},
{
    "source": "B",
    "target": "C",
    "other information" : "randomstring",
    "other information" : "randomstring"
} // and so on ....
]

3 个答案:

答案 0 :(得分:2)

这是一个图论问题,我假设你想打破一个循环,这就是我要做的事情

给出尺寸g和订单n

的图表m

1)从links构建哈希表,该哈希表使用链接(O(m),如果哈希是在恒定时间内完成)映射两个节点,例如,

// a reference to the link itself (which can be an object or a dom node)
var hash = {}
links.each(function (d) {
  var u = d.source
  var v = d.target
  hash[u] = hash[u] || {}
  // again replace this with the dom node if you want
  hash[u][v] = d
})

2)运行dfs查找边缘(在an article I wrote或快速谷歌搜索中更多关于它),每当找到后边缘时,您将获得有关源/目标节点和周期长度的信息O(n + m)

3)如果周期长度为3或符合条件,则删除链接,从链接中删除O(km)其中k是找到的周期数

现在使用d3你可以简单地重新绑定新数据(删除一些链接)并重新渲染图形

答案 1 :(得分:1)

假设您的逻辑可以简化为检查当前entry.source是否等于以下entry.target, 你可以使用try

array.reduce

fiddle

这可能不是最高效的解决方案,但是,检查100个对象,你应该没事; 此外,它非常合成,使用reduce

答案 2 :(得分:1)

似乎我们有一个类似的问题,我必须创建一个函数来到达一个特定的节点。您可以在创建和使用的基本功能中看到不同版本:http://bl.ocks.org/CrandellWS/79be3b8c9e8b74549af5

最初的尝试是使用forEach循环,但我发现使用常规for循环更简单。虽然我希望这可以解决你的问题,你应该阅读这个answer为什么在数组迭代中使用“for ... in”这样一个坏主意?

  function getObjByValue(myRoot, myType, myType2, myVal, myVal2){
    var d;
    console.log(typeof myRoot)
    if(typeof myRoot == "object"){
      for(d in myRoot){

        //checking for requirements.
        if(myRoot[d][myType] == myVal && myRoot[d][myType2] == myVal2 ){
          console.log(d);

          //accessing the specific one desired...
          d3.select('#specificOne').text(myRoot[d]["other information"]);

          //deleteing it from the copied array
          delete myRoot[d];

          //do something with the rest
          printRemaining(myRoot);

            //done
            return;
        }
      }
    }
  } 

getObjByValue(edges, 'source', 'target', 'A', 'C');

edges = [
    {
        "source": "A",
        "target": "B",
        "other information" : "randomstringAB",
        "other information2" : "randomstringAB"
    },{
        "source": "A",
        "target": "C",
        "other information" : "randomstringAC",
        "other information2" : "randomstringAC"
    },{
        "source": "B",
        "target": "C",
        "other information" : "randomstringBC",
        "other information2" : "randomstringBC"
    },{
        "source": "D",
        "target": "C",
        "other information" : "randomstringDC",
        "other information2" : "randomstringDC"
    },{
        "source": "C",
        "target": "E",
        "other information2" : "randomstringCE",
        "other information" : "randomstringCE"
    }
]

  function getObjByValue(myRoot, myType, myType2, myVal, myVal2){
    var d;
    console.log(typeof myRoot)
    if(typeof myRoot == "object"){
      for(d in myRoot){
        if(myRoot[d][myType] == myVal && myRoot[d][myType2] == myVal2 ){
          console.log(d);
          //accessing the specific one desired...
          d3.select('#specificOne').text(myRoot[d]["other information"]);
          //deleteing it from the copied array
          delete myRoot[d];
          printRemaining(myRoot);
          console.log(d);
          console.log('done');
            //done
            return;
        }
      }
    }
  } 
  
function printRemaining(myArray){
  for(d in myArray){
    d3.select('#edges').append('p').text(myArray[d]["other information"]+'\r\n');
  }

}


getObjByValue(edges, 'source', 'target', 'A', 'C');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p>First the specific one</p>
<div id="specificOne"></div>
<br /><br /><br /><br /><br />
<p>It's time to eat, Here is the leftovers.</p>
<div id="edges"></div>