I’m using Angular with typescript.
This is the layout implementation:
import {
ChangedEvent,
Diagram,
ForceDirectedLayout,
ForceDirectedVertex,
Group,
Part,
Iterable, DraggingTool, Shape
} from 'gojs'
export class ContinuousForceDirectedLayout extends ForceDirectedLayout {
public isObserving: boolean;
public isActive: boolean;
constructor() {
super();
ForceDirectedLayout.call(this);
}
isFixed(v: ForceDirectedVertex): boolean {
return v.node.isSelected;
}
doLayout(coll: Diagram | Group | Iterable<Part>): void {
if (!this.isObserving) {
this.isObserving = true;
// cacheing the network means we need to recreate it if nodes or links have been added or removed or relinked,
// so we need to track structural model changes to discard the saved network.
const lay = this;
this.diagram.addModelChangedListener(function(e) {
// modelChanges include a few cases that we don't actually care about, such as
// "nodeCategory" or "linkToPortId", but we'll go ahead and recreate the network anyway.
// Also clear the network when replacing the model.
if (e.modelChange !== '' ||
(e.change === ChangedEvent.Transaction && e.propertyName === 'StartingFirstTransaction')) {
lay.network = null;
}
});
}
let net = this.network;
if (net === null) { // the first time, just create the network as normal
this.network = net = this.makeNetwork(coll);
} else { // but on reuse we need to update the LayoutVertex.bounds for selected nodes
this.diagram.nodes.each(function(n) {
const v = net.findVertex(n);
if (v !== null) {
v.bounds = n.actualBounds;
}
});
}
// now perform the normal layout
ForceDirectedLayout.prototype.doLayout.call(this, coll);
// doLayout normally discards the LayoutNetwork by setting Layout.network to null;
// here we remember it for next time
this.network = net;
}
}
On the component holding the diagram:
/**
* Overrides diagram property DoMouseMove
* This runs after the diagram is ready
*/
overrideDiagramDoMouseMove() {
const diagram: Diagram = this.graph.diagram;
// dragging a node invalidates the Diagram.layout, causing a layout during the drag
diagram.toolManager.draggingTool.doMouseMove = () => {
DraggingTool.prototype.doMouseMove.call(this);
if (diagram.toolManager.draggingTool.isActive && !this.freezeGraph) {
diagram.layout.invalidateLayout();
}
}
}
/**
* Invalidate the diagram layout on SelectionMoved diagram event
*/
onSelectionMoved() {
if (!this.freezeGraph) {
this.graph.diagram.layout.invalidateLayout();
}
}
As you can see in this video, when dragging a node it doesn’t follow the mouse pointer until it finishes moving.
https://drive.google.com/file/d/1kpJMP8UjQ3MwIDvHOliBbbF6Xcgs92Jq/view?usp=sharing