动态添加节点到 Cytoscape
Dynamically adding nodes to Cytoscape
我的公司正在为聊天机器人构建图形视图编辑器。我们正在使用 Cytoscape 和 cytoscape-cola
扩展来实现这一点。我们面临的问题之一是动态地向图中添加新节点而不与图上的现有节点重叠。
我查看了以前的类似问题(如下所列),但无济于事:
Cytoscape - handle locked nodes
我尝试了那里的解决方案,即仅在新添加的节点上应用布局,但它们一直堆叠在屏幕中央。
Cytoscape - ignore locked nodes
我尝试了这里提到的解决方案,但无论是一次性锁定节点,即 cy.nodes().lock()
还是单独锁定节点,即 cy.nodes().forEach(node => node.lock())
,锁定的节点仍然会继续移动。这里还需要注意的一点是,当单独锁定节点时,无论我是否在上面的调用中锁定,新添加的节点也会被锁定。
Cytoscape - dynamically add nodes without moving others
我也尝试过这个解决方案,但锁定的节点仍然移动并且整个布局发生了变化 - 有时完全改变,有时只是一点点。
代码
这是我目前用来构建图表的内容:
const layoutConfig = {
name: "cola",
handleDisconnected: true,
animate: true,
avoidOverlap: true,
infinite: false,
unconstrIter: 1,
userConstIter: 0,
allConstIter: 1,
ready: e => {
e.cy.fit()
e.cy.center()
}
}
this.graph = Cytoscape({ ... })
this.layout = this.grapg.makeLayout(layoutConfig)
this.layout.run();
这是我用来向图中添加新节点的方法:
const addElements = (elements: ElementSingular | ElementMultiple) => {
this.graph.nodes().forEach(node => {
node.lock();
})
this.graph.add(elements)
this.layout = this.graph.makeLayout(layoutConfig)
this.layout.on("layoutready", () => {
this.nodes().forEach(node => {
node.unlock();
})
})
this.layout.run()
this.graph.nodes().forEach(node => {
node.unlock();
})
}
我想执行以下操作之一:
- 了解我做错了什么如果我试图完成的事情是可能的,但我的代码没有实现它
- 了解为什么我无法完成它,即控制它的限制
编辑:这就是您要找的东西吗? https://output.jsbin.com/hokineluwo
编辑:我之前没看到,但你也是 unlocking
布局调用之后的节点,Cola 是异步的,运行 只是启动进程。删除该代码并仅使用 layoutstop
方法。
我记错了,但我认为 可乐一直在 layoutready
之后移动元素。来自 their code:
// trigger layoutready when each node has had its position set at least once
有一个 layoutstop
事件可以使用(还有 cytoscape-cola uses)。
来自文档(重点是我的):
layoutready : when a layout has set initial positions for all the
nodes (but perhaps not final positions)
layoutstop : when a layout has
finished running completely or otherwise stopped running
我会尝试删除该回调并检查它是否会产生良好的结果。
此外,您应该尝试在此处复制它:http://jsbin.com/fiqugiq
其他人(甚至作者)可以更轻松地使用它并查看您是否发现了错误。
我的公司正在为聊天机器人构建图形视图编辑器。我们正在使用 Cytoscape 和 cytoscape-cola
扩展来实现这一点。我们面临的问题之一是动态地向图中添加新节点而不与图上的现有节点重叠。
我查看了以前的类似问题(如下所列),但无济于事:
Cytoscape - handle locked nodes我尝试了那里的解决方案,即仅在新添加的节点上应用布局,但它们一直堆叠在屏幕中央。
Cytoscape - ignore locked nodes我尝试了这里提到的解决方案,但无论是一次性锁定节点,即 cy.nodes().lock()
还是单独锁定节点,即 cy.nodes().forEach(node => node.lock())
,锁定的节点仍然会继续移动。这里还需要注意的一点是,当单独锁定节点时,无论我是否在上面的调用中锁定,新添加的节点也会被锁定。
我也尝试过这个解决方案,但锁定的节点仍然移动并且整个布局发生了变化 - 有时完全改变,有时只是一点点。
代码
这是我目前用来构建图表的内容:
const layoutConfig = {
name: "cola",
handleDisconnected: true,
animate: true,
avoidOverlap: true,
infinite: false,
unconstrIter: 1,
userConstIter: 0,
allConstIter: 1,
ready: e => {
e.cy.fit()
e.cy.center()
}
}
this.graph = Cytoscape({ ... })
this.layout = this.grapg.makeLayout(layoutConfig)
this.layout.run();
这是我用来向图中添加新节点的方法:
const addElements = (elements: ElementSingular | ElementMultiple) => {
this.graph.nodes().forEach(node => {
node.lock();
})
this.graph.add(elements)
this.layout = this.graph.makeLayout(layoutConfig)
this.layout.on("layoutready", () => {
this.nodes().forEach(node => {
node.unlock();
})
})
this.layout.run()
this.graph.nodes().forEach(node => {
node.unlock();
})
}
我想执行以下操作之一:
- 了解我做错了什么如果我试图完成的事情是可能的,但我的代码没有实现它
- 了解为什么我无法完成它,即控制它的限制
编辑:这就是您要找的东西吗? https://output.jsbin.com/hokineluwo
编辑:我之前没看到,但你也是 unlocking
布局调用之后的节点,Cola 是异步的,运行 只是启动进程。删除该代码并仅使用 layoutstop
方法。
我记错了,但我认为 可乐一直在 layoutready
之后移动元素。来自 their code:
// trigger layoutready when each node has had its position set at least once
有一个 layoutstop
事件可以使用(还有 cytoscape-cola uses)。
来自文档(重点是我的):
layoutready : when a layout has set initial positions for all the nodes (but perhaps not final positions)
layoutstop : when a layout has finished running completely or otherwise stopped running
我会尝试删除该回调并检查它是否会产生良好的结果。 此外,您应该尝试在此处复制它:http://jsbin.com/fiqugiq
其他人(甚至作者)可以更轻松地使用它并查看您是否发现了错误。