mirror of
https://github.com/projectstorm/react-diagrams.git
synced 2025-08-16 09:40:44 +08:00
57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
import * as dagre from "dagre";
|
|
import * as _ from "lodash";
|
|
|
|
const size = {
|
|
width: 60,
|
|
height: 60
|
|
};
|
|
|
|
export function distributeElements(model) {
|
|
let clonedModel = _.cloneDeep(model);
|
|
let nodes = distributeGraph(clonedModel);
|
|
nodes.forEach(node => {
|
|
let modelNode = clonedModel.nodes.find(item => item.id === node.id);
|
|
modelNode.x = node.x;
|
|
modelNode.y = node.y;
|
|
});
|
|
return clonedModel;
|
|
}
|
|
|
|
function distributeGraph(model) {
|
|
let nodes = mapElements(model);
|
|
let edges = mapEdges(model);
|
|
let graph = new dagre.graphlib.Graph();
|
|
graph.setGraph({});
|
|
graph.setDefaultEdgeLabel(() => ({}));
|
|
//add elements to dagre graph
|
|
nodes.forEach(node => {
|
|
graph.setNode(node.id, node.metadata);
|
|
});
|
|
edges.forEach(edge => {
|
|
if (edge.from && edge.to) {
|
|
graph.setEdge(edge.from, edge.to);
|
|
}
|
|
});
|
|
//auto-distribute
|
|
dagre.layout(graph);
|
|
return graph.nodes().map(node => graph.node(node));
|
|
}
|
|
|
|
function mapElements(model) {
|
|
// dagre compatible format
|
|
return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } }));
|
|
}
|
|
|
|
function mapEdges(model) {
|
|
// returns links which connects nodes
|
|
// we check are there both from and to nodes in the model. Sometimes links can be detached
|
|
return model.links
|
|
.map(link => ({
|
|
from: link.source,
|
|
to: link.target
|
|
}))
|
|
.filter(
|
|
item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to)
|
|
);
|
|
}
|