为什么节点在引发 "layoutstop" 事件后移动?

Why are nodes moving after the "layoutstop" event has been raised?

我想在移动节点时启动一个新的弹性布局。为此,我在节点上监听 "position" 事件并在该节点上设置 "moving" 标志并关闭位置更改通知。然后当节点被释放时,我检查它是否已经移动,如果是的话我开始布局并设置一个变量来知道布局当前是 运行.

以下是我使用的方法:

var layouting = false;    

var relayout = function() {
    if (layouting === false) {
        layouting = true;           
        cy.layout(forceFieldLayout);
    }
}

var nodeMoving = function(e) {
    cy.off('position', 'node', nodeMoving);
    e.cyTarget.data("moving", true);
}

cy.on("free", 'node', function(e) {
        if (e.cyTarget.data("moving") === true) {
            e.cyTarget.data("moving", false)
            relayout();
         }
 });

在 layoutstop 事件中,我正在关闭位置通知,但位置事件仍然被引发,因此再次开始一个全新的布局,导致无限循环。

我通过在重新打开通知之前使用超时解决了这个问题。

cy.on("layoutstop", function() {    
    window.setTimeout( function(){
                    layouting = false;
                    cy.on('position', 'node', nodeMoving);
                }, 250);
);

为什么我需要超时?

我只能在 Springy 上重现它,就运行时和视觉结果而言,它的布局不如所有其他包含的物理模拟布局。

(1)我建议你不要使用Springy。包含它只是为了完整性(有些人喜欢它,但我无法想象为什么)。

(2) https://github.com/cytoscape/cytoscape.js/issues/865