mirror of
https://github.com/projectstorm/react-diagrams.git
synced 2025-08-15 17:25:12 +08:00
156 lines
3.9 KiB
TypeScript
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} />;
|
|
};
|