动态添加节点到Cytoscape

时间:2019-10-01 07:19:44

标签: javascript cytoscape.js webcola

我的公司正在为聊天机器人构建图形视图编辑器。我们正在使用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();
    })
}

我想执行以下一项操作:

  1. 了解我在做错什么如果我尝试完成的事情是可能的,但是我的代码无法实现
  2. 了解为什么我无法实现它,即控制它的局限性

1 个答案:

答案 0 :(得分:1)

编辑:这是您要找的东西吗? 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:当布局已为所有   节点(但可能不是最终位置

     

layoutstop:当布局具有   完成完全运行或停止运行

我将尝试删除该回调并检查其是否提供了良好的结果。 另外,您应该尝试在此处复制它:http://jsbin.com/fiqugiq

它使其他人(甚至是作者)更容易使用它,并查看您是否发现了错误。