【问题标题】:d3js - Force-Directed Graph: Delete node that only link to itselfd3js - 强制有向图:删除仅链接到自身的节点
【发布时间】:2017-10-21 03:32:32
【问题描述】:

我正在尝试从this example 做力导向图,但我的数据非常大(5000 个节点),所以我想删除一些不链接到任何其他节点的节点。

但是,在我的 JSON 中,每个节点至少有 1 个链接(链接到自身)。这是我的数据示例:

{"directed": false, "graph": {}, 
"nodes": [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, 
         {"id": 6}, {"id": 7}, {"id": 8}, {"id": 9}, {"id": 10}, {"id": 11}, {"id": 12}], 

"links": [{"source": 0, "target": 0}, {"source": 1, "target": 1}, 
    {"source": 2, "target": 2}, {"source": 3, "target": 3}, 
    {"source": 4, "target": 4}, {"source": 5, "target": 5}, 
    {"source": 6, "target": 6}, {"source": 7, "target": 8}, 
    {"source": 7, "target": 9}, {"source": 7, "target": 10}, 
    {"source": 7, "target": 11}, {"source": 7, "target": 7}, 
    {"source": 8, "target": 8}, {"source": 9, "target": 9}, 
    {"source": 10, "target": 10}, {"source": 11, "target": 11}, 
    {"source": 12, "target": 12}], "multigraph": false}

即,节点id:0 仅具有链接{"source": 0, "target": 0},因此应将其删除,但节点id:7 具有链接{"source": 7, "target": 8}, {"source": 7, "target": 7}。它已链接到另一个节点,因此不应被删除。

我的问题是如何删除只链接到自身的节点?

【问题讨论】:

    标签: javascript d3.js graph force-layout


    【解决方案1】:

    这样做的一种方法是首先将链接归结为不指向同一节点的链接,即source !== target。我选择使用Array.prototype.reduce(),尽管其他迭代方式也一样。为了稍后加快节点的消除,我还使用了Set 来存储 unique id 值,不过从技术上讲,这并不是必需的。

    let uniqueNonSelfReferringLinks = data.links.reduce((set, {source:s, target:t}) =>
      s !== t ? set.add(s).add(t) : set,
      new Set()
    );
    

    过滤节点然后归结为迭代 nodes 数组以查找节点 ID 值的集合:

    let filteredNodes = data.nodes.filter(n => uniqueNonSelfReferringLinks.has(n.id));
    

    将这两个步骤合并为一个,这样可以更简洁地编写:

    let filteredNodes = data.nodes.filter(
      function(n) { return this.has(n.id); },  
      data.links.reduce((set, {source:s, target:t}) =>
        s !== t ? set.add(s).add(t) : set,
        new Set()
      )
    );
    

    看看下面的工作演示:

    var data = {
      "directed": false,
      "graph": {}, 
      "nodes": [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, 
             {"id": 6}, {"id": 7}, {"id": 8}, {"id": 9}, {"id": 10}, {"id": 11}, {"id": 12}], 
    
      "links": [{"source": 0, "target": 0}, {"source": 1, "target": 1}, 
        {"source": 2, "target": 2}, {"source": 3, "target": 3}, 
        {"source": 4, "target": 4}, {"source": 5, "target": 5}, 
        {"source": 6, "target": 6}, {"source": 7, "target": 8}, 
        {"source": 7, "target": 9}, {"source": 7, "target": 10}, 
        {"source": 7, "target": 11}, {"source": 7, "target": 7}, 
        {"source": 8, "target": 8}, {"source": 9, "target": 9}, 
        {"source": 10, "target": 10}, {"source": 11, "target": 11}, 
        {"source": 12, "target": 12}],
      "multigraph": false
    };
    
    let filteredNodes = data.nodes.filter(
      function(n) { return this.has(n.id); },  
      data.links.reduce((set, {source:s, target:t}) =>
        s !== t ? set.add(s).add(t) : set,
        new Set()
      )
    );
    
    console.log(filteredNodes);

    【讨论】:

    • 非常感谢!它的工作非常好。我还有一个问题。当我在浏览器中打开我的图表时,它仍然非常滞后。有没有办法提高性能?我的代码就像示例 (bl.ocks.org/mbostock/4062045)
    • 引用您的评论:“我还有一个问题。” 请照此发布;该问题非常值得提出自己的问题,该问题应与显示问题的工作演示一起出现!但是,在为此付出太多努力之前,我建议您先看一下"d3js force large number of nodes",并连续五次大声朗读已接受答案的第一句;-) 如果您仍然觉得需要描述您的数据,阅读帖子的其余部分,然后,也许,写下你的新问题。
    • 明白。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2017-08-16
    • 2019-05-01
    • 2013-10-07
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 2020-09-01
    • 2013-10-09
    相关资源
    最近更新 更多