简体   繁体   English

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

[英]How to check if nodes are related? How do I chose only one neighbour if it has two?

I have a force layout in D3. 我在D3中有一个部队布局。

I have many nodes with links joining them up. 我有很多带有链接的节点。 My problem is, I want to delete links if nodes meet a certain criteria. 我的问题是,如果节点满足特定条件,我想删除链接。

Say I have nodes A,B,C. 假设我有节点A,B,C。

Say this tilda character - '~' means connected. 说这个tilda字符-“〜”表示已连接。

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

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

I've tried going through each link : 我试图通过每个链接:

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

but I can't seem to get my head around how I would do the logic. 但我似乎无法理解如何执行逻辑。

I would go through each node 3 times, check if A~B, A~C, B~C, but if i have 100 nodes that's going to be really slow. 我将遍历每个节点3次,检查A〜B,A〜C,B〜C,但是如果我有100个节点,那将会非常慢。

Any help would be appreciated :) 任何帮助,将不胜感激 :)

Here is how my current edges/links array looks : 这是我当前的edges / 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 ....
]

This is a graph theory problem where I assume you want to break a cycle, here's what I'd do 这是一个图论问题,我假设您想打破一个循环,这就是我要做的

Given a graph g of size n and order m 给定大小为n且阶为m的图g

1) build a hash table out of links which maps two nodes with a link ( O(m) if the hash is done in constant time), eg 1)从links构建一个哈希表,该哈希表将两个带有链接的节点映射O(m)如果哈希是在恒定时间内完成的,则为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) run dfs finding back edges (more about it in an article I wrote or with a quick google search), whenever you find a back edge you will have info about the source/target node and the length of the cycle O(n + m) 2)运行dfs查找后边缘(在我写的文章中或通过谷歌快速搜索找到更多关于后边缘的信息),每当找到后边缘时,您将获得有关源/目标节点和周期长度O(n + m)

3) erase the link if the length of the cycle is 3 or whatever your criteria is, erasing from links would take O(km) where k is the number of cycles found 3)如果周期的长度是3或您的标准是什么,则删除链接,从链接中擦除将花费O(km) ,其中k是找到的周期数

Now using d3 you can simply rebind the new data (with some links removed) and rerender the graph 现在使用d3,您可以简单地重新绑定新数据(删除一些链接)并重新呈现图形

Assuming your logic could be simplified to checking if the current entry.source is equal to the following entry.target, you could use array.reduce : 假设你的逻辑可以简化为检查当前entry.source等于以下entry.target,你可以使用array.reduce

    edges = [
    {
        "source": "A",
        "target": "B",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "A",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "B",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "D",
        "target": "C",
        "other information" : "randomstring",
        "other information" : "randomstring"
    },{
        "source": "C",
        "target": "E",
        "other information" : "randomstring",
        "other information" : "randomstring"
    }
]




var res = edges.reduce(function (acc, cur, i, array) {

    if (array[i - 1] == undefined || acc[acc.length - 1].target == cur.source) {
        acc.push(cur)
    }

    return acc

}, [])
console.log(res)

fiddle 小提琴

This is probably not the most performant solution but, checking 100 objects, you should be fine; 这可能不是最有效的解决方案,但是检查100个对象应该没问题; furthermore it's quite synthetic and an elegant use of reduce . 此外,它是完全合成的,并且还很好地使用了reduce

It seems that we had a similar issue that where I had to create a function to get to a specific node. 似乎我们遇到了类似的问题,即我必须创建一个函数才能到达特定节点。 You can see a different version of the same basic function where it was created and used: http://bl.ocks.org/CrandellWS/79be3b8c9e8b74549af5 您可以在创建和使用的地方看到相同基本功能的不同版本: http : //bl.ocks.org/CrandellWS/79be3b8c9e8b74549af5

The original attempts was to use forEach looping but I found it simpler to use a regular for loop. 最初的尝试是使用forEach循环,但我发现使用常规的for循环更简单。 Though I hope this solves your problem, you should read this answer of Why is using “for…in” with array iteration such a bad idea? 尽管我希望这可以解决您的问题,但是您应该阅读以下答案 :为什么在数组迭代中使用“ 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何检查 object 是否只有一个属性或只有两个属性而 javascript 中没有其他属性 - How do I check if an object has only one property or only two properties and no other property in javascript 使用JQuery如何检查仅需要填写的两个字段 - Using JQuery how do I check two fields that I need one filled only 提交表单后,如何禁用并检查我在单选按钮中选择的选项? - How do I disable and check which option that I chose in the radio buttons after form submission? 我如何运行 animation 两个,只有在 animation 一个完成之后? - How do i run animation two, only after animation one has completed? 如何只触发一个复选框检查操作 - How do I get only one checkbox check action to trigger 如何检查数组是否仅包含一个不同的元素? - How do I check if an array contains only one distinct element? 在JavaScript中,如何检查输入中是否只有一个“ @”? - In JavaScript, how do I check that only one “@” is present in an input? Firebase如何检查除一个以外的所有子节点的更改? - Firebase how can I check for changes for all child nodes but one? 在该人选择隐藏div之后,如何使div重新出现? (与javascript相关) - How can I make the div reappear again, after the person chose to hide the div? (javascript-related) 如何检查窗口是否有焦点? - How do I check if the window has focus?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM