Dagre Tree
import type { Edge, Node } from '@xyflow/vue';
import dagre from '@dagrejs/dagre';
import { Position } from '@xyflow/vue';
const nodeWidth = 172;
const nodeHeight = 36;
export function useDagreLayout() {
const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
return (nodes: Node[], edges: Edge[], direction: 'TB' | 'LR' = 'TB'): { nodes: Node[]; edges: Edge[] } => {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
const layoutedNodes = nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
return {
...node,
targetPosition: isHorizontal ? Position.Left : Position.Top,
sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
// shift the dagre node position (anchor=center) to the top-left so it matches Vue Flow's anchor
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2,
},
};
});
return { nodes: layoutedNodes, edges };
};
}Last updated on