【问题标题】:Filtering graph by connectivity to a specific node in cytoscape.js通过与 cytoscape.js 中特定节点的连接来过滤图形
【发布时间】:2020-01-28 19:09:57
【问题描述】:

Cytoscape 新手。我有一个图表,其中包含主要的主网络和一些未连接到我要删除的主要网络的较小网络。浏览文档,我看不到明显的解决方案。我猜可能需要一种自定义方法来循环遍历所有节点,检查它们与主集群中最中心节点的图形距离,如果该距离未定义,则删除该节点及其连接的所有其他节点。但渴望从其他有更多图书馆经验的人那里获得指导。非常感谢任何建议。我注意到this 未回答但相关的问题。

这是一个示例图表。虽然我无法在jsfiddle 上工作,但这里是working version

<!DOCTYPE>
<html>
  <head>
    <title>cytoscape-dagre.js demo</title>

    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">

    <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
    <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
    <script src="cytoscape-dagre.js"></script>

    <style>
      #cy {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        z-index: 999;
      }
    </style>

    <script>
      window.addEventListener('DOMContentLoaded', function(){

        var cy = window.cy = cytoscape({
          container: document.getElementById('cy'),

          boxSelectionEnabled: false,
          autounselectify: true,

          layout: {
            name: 'dagre'
          },

          style: [
            {
              selector: 'node',
              style: {
                'background-color': '#11479e'
              }
            },

            {
              selector: 'edge',
              style: {
                'width': 4,
                'target-arrow-shape': 'triangle',
                'line-color': '#9dbaea',
                'target-arrow-color': '#9dbaea',
                'curve-style': 'bezier'
              }
            }
          ],

          elements: {
            nodes: [
              { data: { id: 'n0' } },
              { data: { id: 'n1' } },
              { data: { id: 'n2' } },
              { data: { id: 'n3' } },
              { data: { id: 'n4' } },
              { data: { id: 'n5' } },
              { data: { id: 'n6' } },
              { data: { id: 'n7' } },
              { data: { id: 'n8' } },
              { data: { id: 'n9' } },
              { data: { id: 'n10' } },
              { data: { id: 'n11' } },
              { data: { id: 'n12' } },
              { data: { id: 'n13' } },
              { data: { id: 'n14' } },
              { data: { id: 'n15' } },
              { data: { id: 'n16' } }
            ],
            edges: [
              { data: { source: 'n0', target: 'n1' } },
              { data: { source: 'n1', target: 'n2' } },
              { data: { source: 'n1', target: 'n3' } },
              { data: { source: 'n4', target: 'n5' } },
              { data: { source: 'n4', target: 'n6' } },
              { data: { source: 'n6', target: 'n7' } },
              { data: { source: 'n6', target: 'n8' } },
              { data: { source: 'n8', target: 'n9' } },
              { data: { source: 'n8', target: 'n10' } },
              { data: { source: 'n11', target: 'n12' } },
              { data: { source: 'n12', target: 'n13' } },
              { data: { source: 'n13', target: 'n14' } },
              { data: { source: 'n13', target: 'n15' } },
            ]
          }
        });

      });
    </script>
  </head>

  <body>
    <h1>cytoscape-dagre demo</h1>

    <div id="cy"></div>

  </body>
</html>

【问题讨论】:

    标签: cytoscape.js


    【解决方案1】:

    您可以使用docs 中提供的过滤方法来完成此操作,如果您找到更适合此问题的方法,只需摆弄它们,直到获得正确的结果。这里重要的部分是.union().not() 方法。您可以将它们用于:

    • 以可控方式遍历图,途中保存重要节点
    • 然后过滤集合以满足您的需求

    您提到无法让 jsfiddle 工作,您可以在here 中测试以下代码

    var cy = (window.cy = cytoscape({
      container: document.getElementById("cy"),
    
      style: [{
          selector: "node",
          css: {
            content: "data(id)",
            "text-valign": "center",
            "text-halign": "center",
            height: "60px",
            width: "60px",
            "border-color": "black",
            "border-opacity": "1",
            "border-width": "10px"
          }
        },
        {
          selector: "edge",
          css: {
            "target-arrow-shape": "triangle"
          }
        }
      ],
    
      elements: {
        nodes: [{
            data: {
              id: "n0"
            }
          },
          {
            data: {
              id: "n1"
            }
          },
          {
            data: {
              id: "n2"
            }
          },
          {
            data: {
              id: "n3"
            }
          },
          {
            data: {
              id: "n4"
            }
          },
          {
            data: {
              id: "n5"
            }
          },
          {
            data: {
              id: "n6"
            }
          },
          {
            data: {
              id: "n7"
            }
          },
          {
            data: {
              id: "n8"
            }
          },
          {
            data: {
              id: "n9"
            }
          },
          {
            data: {
              id: "n10"
            }
          },
          {
            data: {
              id: "n11"
            }
          },
          {
            data: {
              id: "n12"
            }
          },
          {
            data: {
              id: "n13"
            }
          },
          {
            data: {
              id: "n14"
            }
          },
          {
            data: {
              id: "n15"
            }
          },
          {
            data: {
              id: "n16"
            }
          }
        ],
        edges: [{
            data: {
              source: "n0",
              target: "n1"
            }
          },
          {
            data: {
              source: "n1",
              target: "n2"
            }
          },
          {
            data: {
              source: "n1",
              target: "n3"
            }
          },
          {
            data: {
              source: "n4",
              target: "n5"
            }
          },
          {
            data: {
              source: "n4",
              target: "n6"
            }
          },
          {
            data: {
              source: "n6",
              target: "n7"
            }
          },
          {
            data: {
              source: "n6",
              target: "n8"
            }
          },
          {
            data: {
              source: "n8",
              target: "n9"
            }
          },
          {
            data: {
              source: "n8",
              target: "n10"
            }
          },
          {
            data: {
              source: "n11",
              target: "n12"
            }
          },
          {
            data: {
              source: "n12",
              target: "n13"
            }
          },
          {
            data: {
              source: "n13",
              target: "n14"
            }
          },
          {
            data: {
              source: "n13",
              target: "n15"
            }
          }
        ]
      },
    
      layout: {
        name: "dagre",
        padding: 5
      }
    }));
    
    
    cy.unbind('click')
    cy.bind('click', 'node', function(event) {
      // .union() takes two collections and adds both together without duplicates
      var connected = event.target
      connected = connected.union(event.target.predecessors())
      connected = connected.union(connected.successors())
      // in one line: 
      // event.target.union(event.target.predecessors().union(event.target.successors()))
    
      // .not() filters out whatever is not specified in connected, e.g. every other node/edge not present in connected
      var notConnected = cy.elements().not(connected)
    
      // if you want, you can later add the saved elements again
      var saved = cy.remove(notConnected)
    });
    body {
      font: 14px helvetica neue, helvetica, arial, sans-serif;
    }
    
    #cy {
      height: 100%;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
      float: left;
    }
    <html>
    
    <head>
      <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
      <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.1.0/cytoscape-dagre.min.js"></script>
    </head>
    
    <body>
      <div id="cy"></div>
    </body>
    
    </html>

    【讨论】:

    • 啊完美!出人意料的优雅解决方案。谢谢斯蒂芬。另外,您是否知道 Cytoscape / Cytoscape.js 的任何社区空间?我找不到任何看起来像聊天、论坛 Slack 频道或 IRC 的东西。
    • 嗯,好像就是这样:Questions about cytoscape.js should go to stackoverflow.groups.google.com/forum/#!forum/cytoscape-app-dev
    • 除了stackoverflow,我个人并没有真正参与过其他社区,但正如您所见here,对于不同的范围都有专门的地方。自己看看,哪一个最适合您的需求 :) 此外,cytoscape.js 的首席开发人员 @maxkfranz 经常在 stackoverflow 上回答有关 cytoscape.js 的问题,所以我建议将官方文档和这个平台作为您的主要知识来源。
    • 啊 gitter 看起来像这个地方 :) 再次感谢
    • 除了无向图是否可以这样做?由于在这种情况下源/目标是随机设置的,因此后继/前任将不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多