53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import dagre from "dagre";
|
|
import { ref } from "vue";
|
|
import { Position, useVueFlow } from "@vue-flow/core";
|
|
|
|
export function useLayout() {
|
|
const { findNode } = useVueFlow();
|
|
|
|
const graph = ref(new dagre.graphlib.Graph());
|
|
|
|
const previousDirection = ref("LR");
|
|
|
|
function layout(nodes, edges, direction) {
|
|
const dagreGraph = new dagre.graphlib.Graph();
|
|
|
|
graph.value = dagreGraph;
|
|
|
|
dagreGraph.setDefaultEdgeLabel(() => ({}));
|
|
|
|
const isHorizontal = direction === "LR";
|
|
dagreGraph.setGraph({ rankdir: direction });
|
|
|
|
previousDirection.value = direction;
|
|
|
|
for (const node of nodes) {
|
|
const graphNode = findNode(node.id);
|
|
|
|
dagreGraph.setNode(node.id, {
|
|
width: graphNode.dimensions.width || 150,
|
|
height: graphNode.dimensions.height || 50
|
|
});
|
|
}
|
|
|
|
for (const edge of edges) {
|
|
dagreGraph.setEdge(edge.source, edge.target);
|
|
}
|
|
|
|
dagre.layout(dagreGraph);
|
|
|
|
return nodes.map(node => {
|
|
const nodeWithPosition = dagreGraph.node(node.id);
|
|
|
|
return {
|
|
...node,
|
|
targetPosition: isHorizontal ? Position.Left : Position.Top,
|
|
sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
|
|
position: { x: nodeWithPosition.x, y: nodeWithPosition.y }
|
|
};
|
|
});
|
|
}
|
|
|
|
return { graph, layout, previousDirection };
|
|
}
|