7

我的公司正在为聊天机器人构建一个图形视图编辑器。我们正在使用 Cytoscape 和cytoscape-cola扩展来实现这一点。我们面临的问题之一是动态地向图中添加新节点,而不会使它们与图上的现有节点重叠。

我查看了以前的类似问题(如下所列),但无济于事:

Cytoscape - 处理锁定节点

我在那里尝试了解决方案,即仅在新添加的节点上应用布局,但它们一直堆叠在屏幕的中心。

Cytoscape - 忽略锁定的节点

我尝试了此处提到的解决方案,但无论是一次性锁定节点还是cy.nodes().lock()单独cy.nodes().forEach(node => node.lock())锁定节点,锁定的节点仍会继续移动。这里还需要注意的是,当单独锁定节点时,新添加的节点也会被锁定,无论我是否在上面的调用中锁定。

Cytoscape - 动态添加节点而不移动其他节点

我也尝试了这个解决方案,但锁定的节点仍然移动并且整个布局发生了变化——有时完全改变,有时只是一点点。

代码

这是我目前用来构建图表的方法:

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. 了解为什么我无法完成它,即管理它的限制
4

1 回答 1

2

编辑:这是你要找的吗?https://output.jsbin.com/hokineluwo

编辑:我以前没见过,但你也是unlocking布局调用之后的节点,Cola 是异步的,运行只是启动进程。删除该代码并仅使用该layoutstop方法。

我没记错,但我认为可乐在layoutready. 从他们的代码

// trigger layoutready when each node has had its position set at least once

有一个layoutstop事件可以使用(cytoscape-cola 也可以使用

从文档(重点是我的):

layoutready :当布局为所有节点设置初始位置时(但可能不是最终位置

layoutstop :当布局完全运行或停止运行时

我会尝试删除该回调并检查它是否给出了良好的结果。此外,您应该尝试在此处重现它:http: //jsbin.com/fiqugiq

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

于 2019-10-02T14:18:37.560 回答