使用cytoscape.js展开和折叠组时如何保持先前的位置

时间:2019-01-19 10:49:18

标签: javascript layout grouping expand cytoscape.js

很久以来,我一直在寻找一个好的拓扑布局javascript库。我学会了许多图书馆D3WebCola,依此类推,最终我被深深吸引 cytoscape及其惊人的扩展名cytoscape.js-expand-collapse

我想要的是一个javascript布局库,该库可以对很多节点进行合理的布局。父节点包含子节点,换句话说,节点之间存在继承关系。

This Demo几乎正是我所需要的。扩展和折叠功能确实很棒。

然后我在上述演示的基础上创建了演示。但是,当展开一个节点然后折叠该节点时,图上的所有节点都会更改。

初始图

enter image description here

第一次展开和折叠节点后的状态

enter image description here

第二次展开和折叠节点后的状态

enter image description here

显然这不是我的需要。我再次学习了原始的演示程序。我发现demo的elements值在每个数据上都有position

{"data":{"id":"nwtN_50c55b8c-3489-4c4e-8bea-6a1c1162ac9c"},"position":{"x":577.5410894097904,"y":612.5647477282114},"group":"nodes"}

我知道每个数据是否具有合理的坐标,展开和折叠某些节点后,所有节点的位置都不会改变。

关键点是我不知道坐标,也无法为节点设置初始坐标。我认为布局的核心算法是为每个点计算合适的坐标点。

因此,我无法为所有节点设置初始坐标,并且我希望所有节点的位置都是固定的,无论扩展和折叠任何节点。有可能吗?

以下是我的演示。

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

    ready: function() {
      var api = this.expandCollapse({
        layoutBy: {
          name: "cose-bilkent",
          animate: "end",
          randomize: false,
          fit: false
        },
        fisheye: true,
        animate: false,
        undoable: false
      });
      api.collapseAll();
    },

    style: [{
      selector: 'node',
      style: {
        'label': 'data(id)'
      }
    }],

    elements: [{
      "group": "nodes",
      "data": {
        "id": "n_0",
        "name": "External Network"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "n_4",
        "name": "虚拟机网络",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "n_3",
        "name": "VM Network 2",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_128",
        "name": "bfcui-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_105",
        "name": "bychen-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_93",
        "name": "CE-bj",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_100",
        "name": "changliu-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_67",
        "name": "chaoma-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_83",
        "name": "chenwang",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_68",
        "name": "cwang-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_15",
        "name": "gqpei-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_1",
        "name": "gwxu-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_118",
        "name": "gyzhao-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_76",
        "name": "hlli-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_18",
        "name": "hwzhang-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_40",
        "name": "hxqu-pc"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_69",
        "name": "hxwang-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_71",
        "name": "jbshi-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_64",
        "name": "jdai-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_16",
        "name": "jfxiao-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_78",
        "name": "jhhou-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_91",
        "name": "jjsun-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_17",
        "name": "jppan-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_45",
        "name": "jqwang-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_50",
        "name": "jxli-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_42",
        "name": "jyyou-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_28",
        "name": "jyzhou-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_46",
        "name": "jzhao-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_19",
        "name": "lfeng-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_65",
        "name": "lhzhen-pc",
        "parent": "group2"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_1",
        "source": "n_0",
        "target": "v_1"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_100",
        "source": "n_0",
        "target": "v_100"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_46",
        "source": "n_0",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_64",
        "source": "n_0",
        "target": "v_64"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_65",
        "source": "n_0",
        "target": "v_65"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_67",
        "source": "n_0",
        "target": "v_67"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_69",
        "source": "n_0",
        "target": "v_69"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_71",
        "source": "n_0",
        "target": "v_71"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_76",
        "source": "n_0",
        "target": "v_76"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_78",
        "source": "n_0",
        "target": "v_78"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_83",
        "source": "n_0",
        "target": "v_83"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_91",
        "source": "n_0",
        "target": "v_91"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_1n_0",
        "source": "v_1",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_1v_128",
        "source": "v_1",
        "target": "v_128"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_100n_0",
        "source": "v_100",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_16",
        "source": "v_118",
        "target": "v_16"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_18",
        "source": "v_118",
        "target": "v_18"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_46",
        "source": "v_118",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_67",
        "source": "v_118",
        "target": "v_67"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_69",
        "source": "v_118",
        "target": "v_69"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_71",
        "source": "v_118",
        "target": "v_71"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_78",
        "source": "v_118",
        "target": "v_78"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128n_0",
        "source": "v_128",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_1",
        "source": "v_128",
        "target": "v_1"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_105",
        "source": "v_128",
        "target": "v_105"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_46",
        "source": "v_128",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_65",
        "source": "v_128",
        "target": "v_65"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_15n_0",
        "source": "v_15",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_40",
        "source": "v_50",
        "target": "v_40"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_46",
        "source": "v_50",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_64",
        "source": "v_50",
        "target": "v_64"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_65v_19",
        "source": "v_65",
        "target": "v_19"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_65v_91",
        "source": "v_65",
        "target": "v_91"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67n_0",
        "source": "v_67",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_100",
        "source": "v_67",
        "target": "v_100"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_105",
        "source": "v_67",
        "target": "v_105"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_42",
        "source": "v_67",
        "target": "v_42"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_16",
        "source": "v_91",
        "target": "v_16"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_18",
        "source": "v_91",
        "target": "v_18"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_28",
        "source": "v_91",
        "target": "v_28"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_45",
        "source": "v_91",
        "target": "v_45"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group2"
      }
    }]
  });
  var api = cy.expandCollapse('get');
  var beforeExpand = null;
cy.unbind('expandcollapse.beforeexpand');
cy.nodes().bind('expandcollapse.beforeexpand', function(event) { 
   if (beforeExpand == null) 
      beforeExpand = cy.elements().clone();  // save the graph before the first expand
}); // Triggered before a node is expanded

cy.unbind('expandcollapse.aftercollapse');
cy.nodes().bind('expandcollapse.aftercollapse', function(event) { 
   if(beforeExpand != null) {
       cy.elements().remove();
       cy.add(beforeExpand);  // set the graph to original values
       beforeExpand = null;
   }
}); 
});
body {
  font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
  font-size: 14px;
}

#cy {
  z-index: 999;
  width: 100%;
  height: 100%;
}

h1 {
  opacity: 0.5;
  font-size: 1em;
  font-weight: bold;
}
<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://unpkg.com/cytoscape@3.1.0/dist/cytoscape.min.js"></script>

<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/cytoscape-cose-bilkent@4.0.0/cytoscape-cose-bilkent.js"></script>
<script src="https://unpkg.com/cytoscape-expand-collapse@3.1.1/cytoscape-expand-collapse.js"></script>
<div id="cy"></div>

最后,总结一下我需要的东西:

  1. 带有某些节点的初始化图,它可以根据类型等属性进行扩展。类型= 1的节点是可扩展的,而类型= 2的节点则不可扩展。

  2. 所有节点都进行合理的布局,例如layoutBy:{name:'cose-bilkent'}

  3. 展开一个节点(例如:A)时,发送ajax请求以获取子节点(例如:A1,A2,A3),然后布局子节点。该图形可能需要适当的调整。我希望它是一个增量布局,而不是完整的重新布局。

  4. 当折叠先前的组合节点(A组为A1,A2,A3)时,图上的所有节点都保持先前的位置。

  5. 在展开最后一个组节点(例如:A)时,子节点也将保持先前的位置。

我认为我的要求非常基本,但是我找不到演示该功能的演示吗?我是否清楚地描述了我的要求?

有人可以帮助我吗?提前致谢。非常感谢。

2 个答案:

答案 0 :(得分:1)

您要尝试执行的操作效率不高。您说自己,您不知道节点的坐标,因此cytoscape也不知道。但是,尽管如此,与众不同的因素仍然将元素定位得尽可能好。位置可能会更改,但结构保持不变。确实没有任何问题可以证明您必须解决的麻烦和工作。

如果您真的想实现这一目标,我想您可以在发生的特定事件中做到这一点:

代码:

var nodes = cy.nodes();
var positions = [];
for (node in nodes) {
    positions[node] = nodes[node].position(); // save the i'th nodes positions
}

然后折叠父级并再次对其展开后,可以设置之前存储的所有节点位置:

var nodes = cy.nodes();
for (node in nodes) {
    nodes[node].position(positions[node]); // set x and y of node
}

事件:

cy.nodes().on("expandcollapse.beforecollapse", function(event) { var node = this; ... }) // Triggered before a node is collapsed

cy.nodes().on("expandcollapse.aftercollapse", function(event) { var node = this; ... }) // Triggered after a node is collapsed

cy.nodes().on("expandcollapse.beforeexpand", function(event) { var node = this; ... }) // Triggered before a node is expanded

cy.nodes().on("expandcollapse.afterexpand", function(event) { var node = this; ... }) // Triggered after a node is expanded

编辑:

var beforeExpand = null;
cy.unbind('expandcollapse.beforeexpand');
cy.nodes().bind('expandcollapse.beforeexpand', function(event) { 
   if (beforeExpand == null) 
      beforeExpand = cy.elements().clone();  // save the graph before the first expand
}); // Triggered before a node is expanded

cy.unbind('expandcollapse.aftercollapse');
cy.nodes().bind('expandcollapse.aftercollapse', function(event) { 
   if(beforeExpand != null) {
       cy.elements().remove();
       cy.add(beforeExpand);  // set the graph to original values
       beforeExpand = null;
   }
}); // Triggered before a node is expanded

编辑:

这是您修复演示的方法:

  • 更改fit:false更改为true
  • 像下面的代码片段一样,将您的css更改为细胞景

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

    ready: function() {
      var api = this.expandCollapse({
        layoutBy: {
          name: "cose-bilkent",
          animate: "end",
          randomize: false,
          fit: true               // set this to true
        },
        fisheye: true,
        animate: false,
        undoable: false
      });
      api.collapseAll();
    },

    style: [{
      selector: 'node',
      style: {
        'label': 'data(id)'
      }
    }],

    elements: [{
      "group": "nodes",
      "data": {
        "id": "n_0",
        "name": "External Network"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "n_4",
        "name": "虚拟机网络",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "n_3",
        "name": "VM Network 2",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_128",
        "name": "bfcui-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_105",
        "name": "bychen-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_93",
        "name": "CE-bj",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_100",
        "name": "changliu-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_67",
        "name": "chaoma-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_83",
        "name": "chenwang",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_68",
        "name": "cwang-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_15",
        "name": "gqpei-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_1",
        "name": "gwxu-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_118",
        "name": "gyzhao-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_76",
        "name": "hlli-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_18",
        "name": "hwzhang-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_40",
        "name": "hxqu-pc"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_69",
        "name": "hxwang-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_71",
        "name": "jbshi-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_64",
        "name": "jdai-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_16",
        "name": "jfxiao-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_78",
        "name": "jhhou-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_91",
        "name": "jjsun-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_17",
        "name": "jppan-bj",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_45",
        "name": "jqwang-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_50",
        "name": "jxli-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_42",
        "name": "jyyou-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_28",
        "name": "jyzhou-pc",
        "parent": "group2"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_46",
        "name": "jzhao-pc",
        "parent": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_19",
        "name": "lfeng-pc",
        "parent": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "v_65",
        "name": "lhzhen-pc",
        "parent": "group2"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_1",
        "source": "n_0",
        "target": "v_1"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_100",
        "source": "n_0",
        "target": "v_100"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_46",
        "source": "n_0",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_64",
        "source": "n_0",
        "target": "v_64"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_65",
        "source": "n_0",
        "target": "v_65"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_67",
        "source": "n_0",
        "target": "v_67"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_69",
        "source": "n_0",
        "target": "v_69"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_71",
        "source": "n_0",
        "target": "v_71"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_76",
        "source": "n_0",
        "target": "v_76"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_78",
        "source": "n_0",
        "target": "v_78"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_83",
        "source": "n_0",
        "target": "v_83"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "n_0v_91",
        "source": "n_0",
        "target": "v_91"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_1n_0",
        "source": "v_1",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_1v_128",
        "source": "v_1",
        "target": "v_128"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_100n_0",
        "source": "v_100",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_16",
        "source": "v_118",
        "target": "v_16"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_18",
        "source": "v_118",
        "target": "v_18"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_46",
        "source": "v_118",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_67",
        "source": "v_118",
        "target": "v_67"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_69",
        "source": "v_118",
        "target": "v_69"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_71",
        "source": "v_118",
        "target": "v_71"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_118v_78",
        "source": "v_118",
        "target": "v_78"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128n_0",
        "source": "v_128",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_1",
        "source": "v_128",
        "target": "v_1"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_105",
        "source": "v_128",
        "target": "v_105"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_46",
        "source": "v_128",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_128v_65",
        "source": "v_128",
        "target": "v_65"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_15n_0",
        "source": "v_15",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_40",
        "source": "v_50",
        "target": "v_40"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_46",
        "source": "v_50",
        "target": "v_46"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_50v_64",
        "source": "v_50",
        "target": "v_64"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_65v_19",
        "source": "v_65",
        "target": "v_19"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_65v_91",
        "source": "v_65",
        "target": "v_91"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67n_0",
        "source": "v_67",
        "target": "n_0"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_100",
        "source": "v_67",
        "target": "v_100"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_105",
        "source": "v_67",
        "target": "v_105"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_67v_42",
        "source": "v_67",
        "target": "v_42"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_16",
        "source": "v_91",
        "target": "v_16"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_18",
        "source": "v_91",
        "target": "v_18"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_28",
        "source": "v_91",
        "target": "v_28"
      }
    }, {
      "data": {
        "group": "edges",
        "id": "v_91v_45",
        "source": "v_91",
        "target": "v_45"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group0"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group1"
      }
    }, {
      "group": "nodes",
      "data": {
        "id": "group2"
      }
    }]
  });
  var api = cy.expandCollapse('get');
  var beforeExpand = null;
cy.unbind('expandcollapse.beforeexpand');
cy.nodes().bind('expandcollapse.beforeexpand', function(event) { 
   if (beforeExpand == null) 
      beforeExpand = cy.elements().clone();  // save the graph before the first expand
}); // Triggered before a node is expanded

cy.unbind('expandcollapse.aftercollapse');
cy.nodes().bind('expandcollapse.aftercollapse', function(event) { 
   if(beforeExpand != null) {
       cy.elements().remove();
       cy.add(beforeExpand);  // set the graph to original values
       beforeExpand = null;
   }
}); 
});
body {
  font-family: helvetica;
  font-size: 14px;
}
#cy { /*change your css*/
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 999;
}
h1 {
  opacity: 0.5;
  font-size: 1em;
}
<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://unpkg.com/cytoscape@3.1.0/dist/cytoscape.min.js"></script>

<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/cytoscape-cose-bilkent@4.0.0/cytoscape-cose-bilkent.js"></script>
<script src="https://unpkg.com/cytoscape-expand-collapse@3.1.1/cytoscape-expand-collapse.js"></script>
<div id="cy"></div>

答案 1 :(得分:1)

示例中的节点之所以具有位置,仅仅是因为它是从其他工具中导出的。

每次执行展开或折叠操作时,如果设置了layoutBy选项,则该布局将应用于图形。在示例中,layoutBy选项设置为cose-bilkent,这就是位置更改的原因。

我相信您可以通过将layoutBy设置为null,并将fisheye设置为false来实现您想要的。您可以查看其他选项及其说明here

P.S:对于初始坐标,您可以考虑在initializing时设置Cytoscape的layout选项。