I want to launch a new springy layout when a node is moved. To do so, I listen to the "position" event on nodes and set a "moving" flag on that node and turn off position change notification. Then when the node is freed, I check if it has moved and if so I start to layout and I set a variable to know a layout is currently running.
Here are the methods I used:
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();
}
});
In the layoutstop event, I was turning back on the position notification but position events were still raised thus starting a whole new layout again resulting in an infinite loop.
I resolved the issue by using a timeout before turning the notification back on.
cy.on("layoutstop", function() {
window.setTimeout( function(){
layouting = false;
cy.on('position', 'node', nodeMoving);
}, 250);
);
Why do I need the timeout?