ReplicationDiagram.utils.ts 1.2 KB

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