ReplicationDiagram.utils.ts45 lines · main
1import dagre from '@dagrejs/dagre'
2import { Edge, Node, Position } from '@xyflow/react'
3
4import { NODE_WIDTH } from './Nodes'
5
6const NODE_SEP = 0
7const NODE_ROW_HEIGHT = 200
8
9export const getDagreGraphLayout = (nodes: Node[], edges: Edge[]) => {
10 const dagreGraph = new dagre.graphlib.Graph()
11 dagreGraph.setDefaultEdgeLabel(() => ({}))
12 dagreGraph.setGraph({
13 rankdir: 'LR',
14 ranksep: 200,
15 nodesep: NODE_SEP,
16 align: nodes.length <= 2 ? 'UL' : undefined,
17 })
18
19 nodes.forEach((node) => {
20 dagreGraph.setNode(node.id, {
21 width: NODE_WIDTH / 2,
22 height: NODE_ROW_HEIGHT / 2,
23 })
24 })
25
26 edges.forEach((edge) => dagreGraph.setEdge(edge.source, edge.target))
27
28 dagre.layout(dagreGraph)
29
30 nodes.forEach((node) => {
31 const nodeWithPosition = dagreGraph.node(node.id)
32 node.sourcePosition = Position.Right
33 node.targetPosition = Position.Left
34 // We are shifting the dagre node position (anchor=center center) to the top left
35 // so it matches the React Flow node anchor point (top left).
36 node.position = {
37 x: nodeWithPosition.x - nodeWithPosition.width / 2,
38 y: nodeWithPosition.y - nodeWithPosition.height / 2,
39 }
40
41 return node
42 })
43
44 return { nodes, edges }
45}