Files
Dylan Vorster 1e84a03aa5 fix the demos
2024-02-19 15:07:14 -07:00

156 lines
3.9 KiB
TypeScript

import createEngine, {
DiagramModel,
DefaultNodeModel,
DefaultPortModel,
NodeModel,
DagreEngine,
DiagramEngine,
PathFindingLinkFactory
} from '@projectstorm/react-diagrams';
import { useLayoutEffect, useRef } from 'react';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
function createNode(name): any {
return new DefaultNodeModel(name, 'rgb(0,192,255)');
}
let count = 0;
function connectNodes(nodeFrom, nodeTo, engine: DiagramEngine) {
//just to get id-like structure
count++;
const portOut = nodeFrom.addPort(new DefaultPortModel(true, `${nodeFrom.name}-out-${count}`, 'Out'));
const portTo = nodeTo.addPort(new DefaultPortModel(false, `${nodeFrom.name}-to-${count}`, 'IN'));
return portOut.link(portTo);
// ################# UNCOMMENT THIS LINE FOR PATH FINDING #############################
// return portOut.link(portTo, engine.getLinkFactories().getFactory(PathFindingLinkFactory.NAME));
// #####################################################################################
}
/**
* Tests auto distribution
*/
function genDagreEngine() {
return new DagreEngine({
graph: {
rankdir: 'RL',
ranker: 'longest-path',
marginx: 25,
marginy: 25
},
includeLinks: true,
nodeMargin: 25
});
}
function autoDistribute(engine: DiagramEngine) {
const model = engine.getModel();
const dagreEngine = genDagreEngine();
dagreEngine.redistribute(model);
reroute(engine);
engine.repaintCanvas();
}
function autoRefreshLinks(engine: DiagramEngine) {
const model = engine.getModel();
const dagreEngine = genDagreEngine();
dagreEngine.refreshLinks(model);
// only happens if pathfing is enabled (check line 29)
reroute(engine);
engine.repaintCanvas();
}
function reroute(engine: DiagramEngine) {
engine.getLinkFactories().getFactory<PathFindingLinkFactory>(PathFindingLinkFactory.NAME).calculateRoutingMatrix();
}
function DemoWidget(props) {
const engine = props.engine;
useLayoutEffect(() => {
autoDistribute(engine);
}, []);
const redistribute = () => {
autoDistribute(engine);
};
const refreshLinks = () => {
autoRefreshLinks(engine);
};
return (
<DemoWorkspaceWidget
buttons={
<div>
<DemoButton onClick={redistribute}>Re-distribute</DemoButton>
<DemoButton onClick={refreshLinks}>Refresh Links</DemoButton>
</div>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
}
export default () => {
//1) setup the diagram engine
const engineRef = useRef(createEngine());
let engine = engineRef.current;
//2) setup the diagram model
let model = new DiagramModel();
//3) create a default nodes
let nodesFrom: NodeModel[] = [];
let nodesTo: NodeModel[] = [];
nodesFrom.push(createNode('from-1'));
nodesFrom.push(createNode('from-2'));
nodesFrom.push(createNode('from-3'));
nodesTo.push(createNode('to-1'));
nodesTo.push(createNode('to-2'));
nodesTo.push(createNode('to-3'));
//4) link nodes together
let links = nodesFrom.map((node, index) => {
return connectNodes(node, nodesTo[index], engine);
});
// more links for more complicated diagram
links.push(connectNodes(nodesTo[0], nodesTo[1], engine));
links.push(connectNodes(nodesTo[1], nodesTo[2], engine));
links.push(connectNodes(nodesTo[0], nodesTo[2], engine));
links.push(connectNodes(nodesFrom[0], nodesFrom[2], engine));
links.push(connectNodes(nodesFrom[0], nodesTo[2], engine));
// initial random position
nodesFrom.forEach((node, index) => {
node.setPosition(index * 70, index * 70);
model.addNode(node);
});
nodesTo.forEach((node, index) => {
node.setPosition(index * 70, 100);
model.addNode(node);
});
links.forEach((link) => {
model.addLink(link);
});
engine.setModel(model);
return <DemoWidget model={model} engine={engine} />;
};