【问题标题】:cytoscape.js show selected nodes and edges in new graph on right-clickcytoscape.js 在右键单击时在新图中显示选定的节点和边
【发布时间】:2017-09-21 00:05:07
【问题描述】:

我有一个图表 (source credit),我可以在其中选择一个(或多个)节点及其连接的边(当我选择一个节点时边变成蓝色)。现在,如果我想在右键单击已选择的节点之一时显示由选定节点和边组成的新图形,我该怎么做?

这是我到目前为止所做的:

cytoscape.js 来自here

index.html:

<!doctype html>
<!-- source: http://blog.js.cytoscape.org/public/demos/getting-started/index-layout.html -->

<html>

<head>
    <meta charset="utf-8"></meta>
    <title>Tutorial 1: Getting Started</title>
    <script src="cytoscape.js"></script>
</head>

<style>
    #cy {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0px;
        left: 0px;
    }
</style>

<body>
    <div id="cy"></div>
    <script>
        var cy = cytoscape({
          container: document.getElementById('cy'),
          elements: [
            // nodes
            { data: { id: 'a' } },
            { data: { id: 'b' } },
            { data: { id: 'c' } },
            { data: { id: 'd' } },
            { data: { id: 'e' } },
            { data: { id: 'f' } },
            // edges
            {
              data: {
                id: 'ab',
                source: 'a',
                target: 'b'
              }
            },
            {
              data: {
                id: 'cd',
                source: 'c',
                target: 'd'
              }
            },
            {
              data: {
                id: 'ef',
                source: 'e',
                target: 'f'
              }
            },
            {
              data: {
                id: 'ac',
                source: 'a',
                target: 'c'
              }
            },
            {
              data: {
                id: 'be',
                source: 'b',
                target: 'e'
              }
            }
          ],
          style: [
            {
              selector: 'node',
              style: {
                shape: 'vee',
                'background-color': '#A60059',
                label: 'data(id)'
              }
            }],

          layout: {
            name: 'grid'
          }
        });


        cy.on('select', 'node', function(evt){
          evt.cyTarget.connectedEdges().animate({
          style: { lineColor: 'blue' }
          });
        });

       /* cy.on('cxttap', 'node', function(evt) {
        evt.cyTarget.connectedEdges().animate({
        style: {lineColor: 'green'}
        });
        });*/

    </script>
</body>

注释的cy.on('cxttap','node', function()...) 显示了在右键单击节点时将边缘变为绿色的事件处理。但是,我如何将所有先前选择的节点和边获取(即加载)到一个新图形中(并显示它)?我看过this 的帖子,上面说必须使用类似的东西:

cy.$(':selected').jsons()

但老实说,我对如何做到这一点有点迷茫。任何帮助将不胜感激。

编辑:

好的,所以有了 maxkfranz 的提示,我能够将选定的节点(及其边缘)放到另一个图 cy2。因此,当我选择多个节点(`ctrl+drag-selector-over-nodes)然后右键单击其中一个选定节点时,它们会被绘制到另一个 div 中的新图上。这是我更新的代码(数据现在从外部 json 文件加载):

testdata.json

{ "nodes" : [
      {"data": {"id": "a"}},
      {"data": {"id": "b"}},
      {"data": {"id": "c"}},
      {"data": {"id": "d"}},
      {"data": {"id": "e"}},
      {"data": {"id": "f"}}
    ],

  "edges" : [
      {
      "data": {
      "id": "ab",
      "source": "a",
      "target": "b"
      }
      },
      {
      "data": {
      "id": "cd",
      "source": "c",
      "target": "d"
      }
      },
      {
      "data": {
      "id": "ef",
      "source": "e",
      "target": "f"
      }
      },
      {
      "data": {
      "id": "ac",
      "source": "a",
      "target": "c"
      }
      },
      {
      "data": {
      "id": "be",
      "source": "b",
      "target": "e"
      }
      }
    ]

}

index.html

<!doctype html>
<!-- source: http://blog.js.cytoscape.org/public/demos/getting-started/index-layout.html -->

<html>

<head>
    <meta charset="utf-8"></meta>
    <title>Tutorial 1: Getting Started</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="cytoscape.js"></script>
</head>

<style>
    #cy {
        width: 50%;
        height: 50%;
        position: absolute;
        top: 0px;
        left: 0px;
    }

    #cy2 {
        width: 50%;
        height: 50%;
        position: absolute;
        top: 0px;
        right: 0px;
    }
</style>

<body>
    <div id="cy"></div>
    <div id="cy2"></div>
    <script>
        var cy2 = cytoscape({
        container: document.getElementById('cy2'),
          style: [
            {
              selector: 'node',
              style: {
                shape: 'vee',
                'background-color': '#A60059',
                label: 'data(id)'
              }
            }],

          layout: {
            name: 'grid'
          }

       });

        $.getJSON("testdata.json", function (data) {
            //console.log(data);
            var cy = cytoscape({
                container: document.getElementById('cy'),
                elements: data,
                style: [
            {
              selector: 'node',
              style: {
                shape: 'vee',
                'background-color': '#A60059',
                label: 'data(id)'
              }
            }],

          layout: {
            name: 'grid'
          }
            });

        cy.on('select', 'node', function(evt){
          evt.cyTarget.connectedEdges().animate({
          style: { lineColor: 'blue' }
          });
          evt.cyTarget.nodes().animate({
            style: {'background-color': 'yellow'}
        });
        });

        cy.on('cxttap', 'node', function(evt) {
        var newData = cy.$(':selected');
        console.log(newData);
        cy2.add(newData.jsons());
        });

       console.log(cy.$('node:selected'));    
       });

    </script>
</body>

现在的问题是,对于同时选择的节点及其 egdes,这可以按预期工作。但是,如果我例如首先选择节点cd,然后在下一步中选择节点a,当单击节点a 时,新图cy2 将只包含这个单个节点,而没有其他先前选择的节点.现在我想我可以例如选择所有边缘颜色为黄色的节点(这应该主要返回所有曾经选择的节点)。但问题是我不知道该怎么做。像

cy.$('background-color:yellow')

没用。

再次,我们将不胜感激。

【问题讨论】:

    标签: javascript cytoscape.js


    【解决方案1】:
    cy2.add( copy( elementsOfInterest.jsons() ) );
    
    // where copy deep copies json, e.g. obj => _.cloneDeep(obj) or obj => JSON.parse( JSON.stringify(obj) )
    

    查看文档:http://js.cytoscape.org/#notation/object-ownership

    当将对象传递给 Cytoscape.js 以创建元素、动画、布局等时,这些对象被认为归 Cytoscape 所有。像元素这样的对象有几个层次,每次将这些对象传递给 Cytoscape 时都对它们进行深度复制会产生额外的费用。如果需要,开发人员可以在将对象传递给 Cytoscape 之前手动复制它们。但是,大多数开发人员大部分时间都不需要复制。

    一个对象不能有两个所有者。

    【讨论】:

    • 请添加一些关于如何/为什么解决 OP 问题的解释,以便理解和解决问题,而不是简单地解决问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 2017-12-02
    相关资源
    最近更新 更多