32 lines
872 B
TypeScript
32 lines
872 B
TypeScript
import dagre from '@dagrejs/dagre'
|
|
import type { Node, Edge } from '@xyflow/react'
|
|
|
|
/**
|
|
* Compute dagre layout and return nodes with updated x/y.
|
|
* Top-down orientation (TB): root "owner" at top, leaves at bottom.
|
|
*/
|
|
export function computeDagreLayout(
|
|
nodes: Node[],
|
|
edges: Edge[],
|
|
opts: { nodeWidth?: number; nodeHeight?: number } = {},
|
|
): Node[] {
|
|
const g = new dagre.graphlib.Graph()
|
|
g.setDefaultEdgeLabel(() => ({}))
|
|
g.setGraph({
|
|
rankdir: 'TB',
|
|
ranksep: 60,
|
|
nodesep: 36,
|
|
marginx: 24,
|
|
marginy: 24,
|
|
})
|
|
const W = opts.nodeWidth ?? 220
|
|
const H = opts.nodeHeight ?? 80
|
|
nodes.forEach(n => g.setNode(n.id, { width: W, height: H }))
|
|
edges.forEach(e => g.setEdge(e.source, e.target))
|
|
dagre.layout(g)
|
|
return nodes.map(n => {
|
|
const { x, y } = g.node(n.id)
|
|
return { ...n, position: { x: x - W / 2, y: y - H / 2 } }
|
|
})
|
|
}
|