Cytoscape Cola Layout:如何在不改变位置的情况下重新开始布局?
Cytoscape Cola Layout: How to restart the layout without any change of positions?
我正在尝试使用 Cytoscape cola 布局来渲染一个图形,该图形在使用时应应用力导向布局(因此,当四处拖动节点时,它们应该表现得好像有一些重力)。
相关图书馆:
- https://github.com/cytoscape/cytoscape.js
- https://github.com/tgdwyer/WebCola
- https://github.com/cytoscape/cytoscape.js-cola
我的第一个问题是通过 add(node)
将节点添加到图形中并没有将它们包含在可乐布局算法中。我发现的唯一方法是破坏布局,重新初始化并重新启动它。但是在某些情况下这会导致节点跳转。
我认为这是因为我完全破坏了旧布局,但是在设置一个最小示例时,我意识到即使只是调用 layout.stop()
和 layout.run()
也会导致节点被重新定位。
在下面的例子中,只有一个节点。通过拖放移动节点,然后按“停止”按钮,然后按“开始”按钮使节点跳回到其初始位置:
document.addEventListener('DOMContentLoaded', function(){
// Register cola layout
cytoscapeCola(cytoscape);
var nodes = [{ data: { id: 1, name: 1 } }]
var edges = [];
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [
{
selector: 'node[name]',
style: {
'content': 'data(name)'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
},
],
elements: {
nodes: nodes,
edges: edges
}
});
var layout = cy.layout({
name: 'cola',
infinite: true,
fit: false,
});
layout.run();
document.querySelector('#start').addEventListener('click', function() {
layout.run();
});
document.querySelector('#stop').addEventListener('click', function() {
layout.stop();
});
document.querySelector('#add-node').addEventListener('click', function() {
var id = Math.random();
cy.add({ group: 'nodes', data: { id: id, name: id } });
cy.add({ group: 'edges', data: { source: id, target: _.head(nodes).data.id } });
layout.stop();
layout.destroy();
layout = cy.layout({
name: 'cola',
infinite: true,
fit: false,
});
layout.run();
});
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
#buttons {
position: absolute;
right: 0;
bottom: 0;
z-index: 99999;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-edgehandles.js demo for infinite layout</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/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola@2.4.0/cytoscape-cola.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
<script src="cytoscape-edgehandles.js"></script>
</head>
<body>
<h1>cytoscape-edgehandles demo with an infinite layout</h1>
<div id="cy"></div>
<div id="buttons">
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="add-node">Add Node</button>
</div>
</body>
</html>
这是一个错误还是我做错了什么?有谁知道如何在不改变节点位置的情况下停止和重新启动布局?
非常感谢,
杰西
好的,实际上你非常亲密@Stephan。
问题是 WebCola 在默认调用 start
时将节点居中:
https://github.com/tgdwyer/WebCola/blob/78a24fc0dbf0b4eb4a12386db9c09b087633267d/src/layout.ts#L504
WebCola 的 cytoscape 包装器目前不支持这个选项,所以我 fork 了它并自己添加了这个选项:
https://github.com/deje1011/cytoscape.js-cola/commit/f357b97aba900327e12f97b1530c4df624ff9d61
我会在某个时候打开一个拉取请求。
现在你可以像这样顺利重启布局了:
layout.stop();
layout.destroy(); // cleanup event listeners
layout = graph.layout({ name: 'cola', infinite: true, fit: false, centerGraph: false });
layout.run()
这样,节点保持它们的位置
我正在尝试使用 Cytoscape cola 布局来渲染一个图形,该图形在使用时应应用力导向布局(因此,当四处拖动节点时,它们应该表现得好像有一些重力)。 相关图书馆:
- https://github.com/cytoscape/cytoscape.js
- https://github.com/tgdwyer/WebCola
- https://github.com/cytoscape/cytoscape.js-cola
我的第一个问题是通过 add(node)
将节点添加到图形中并没有将它们包含在可乐布局算法中。我发现的唯一方法是破坏布局,重新初始化并重新启动它。但是在某些情况下这会导致节点跳转。
我认为这是因为我完全破坏了旧布局,但是在设置一个最小示例时,我意识到即使只是调用 layout.stop()
和 layout.run()
也会导致节点被重新定位。
在下面的例子中,只有一个节点。通过拖放移动节点,然后按“停止”按钮,然后按“开始”按钮使节点跳回到其初始位置:
document.addEventListener('DOMContentLoaded', function(){
// Register cola layout
cytoscapeCola(cytoscape);
var nodes = [{ data: { id: 1, name: 1 } }]
var edges = [];
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [
{
selector: 'node[name]',
style: {
'content': 'data(name)'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
},
],
elements: {
nodes: nodes,
edges: edges
}
});
var layout = cy.layout({
name: 'cola',
infinite: true,
fit: false,
});
layout.run();
document.querySelector('#start').addEventListener('click', function() {
layout.run();
});
document.querySelector('#stop').addEventListener('click', function() {
layout.stop();
});
document.querySelector('#add-node').addEventListener('click', function() {
var id = Math.random();
cy.add({ group: 'nodes', data: { id: id, name: id } });
cy.add({ group: 'edges', data: { source: id, target: _.head(nodes).data.id } });
layout.stop();
layout.destroy();
layout = cy.layout({
name: 'cola',
infinite: true,
fit: false,
});
layout.run();
});
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
#buttons {
position: absolute;
right: 0;
bottom: 0;
z-index: 99999;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-edgehandles.js demo for infinite layout</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/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola@2.4.0/cytoscape-cola.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
<script src="cytoscape-edgehandles.js"></script>
</head>
<body>
<h1>cytoscape-edgehandles demo with an infinite layout</h1>
<div id="cy"></div>
<div id="buttons">
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="add-node">Add Node</button>
</div>
</body>
</html>
这是一个错误还是我做错了什么?有谁知道如何在不改变节点位置的情况下停止和重新启动布局?
非常感谢, 杰西
好的,实际上你非常亲密@Stephan。
问题是 WebCola 在默认调用 start
时将节点居中:
https://github.com/tgdwyer/WebCola/blob/78a24fc0dbf0b4eb4a12386db9c09b087633267d/src/layout.ts#L504
WebCola 的 cytoscape 包装器目前不支持这个选项,所以我 fork 了它并自己添加了这个选项: https://github.com/deje1011/cytoscape.js-cola/commit/f357b97aba900327e12f97b1530c4df624ff9d61
我会在某个时候打开一个拉取请求。
现在你可以像这样顺利重启布局了:
layout.stop();
layout.destroy(); // cleanup event listeners
layout = graph.layout({ name: 'cola', infinite: true, fit: false, centerGraph: false });
layout.run()
这样,节点保持它们的位置