import ELK from 'elkjs/lib/elk.bundled.js'; | |
import { Edge, Node } from 'reactflow'; | |
const elk = new ELK(); | |
export const getLayoutedElements = ( | |
nodes: Node[], | |
edges: Edge[], | |
options = {}, | |
) => { | |
const isHorizontal = options?.['elk.direction'] === 'RIGHT'; | |
const graph = { | |
id: 'root', | |
layoutOptions: options, | |
children: nodes.map((node) => ({ | |
...node, | |
// Adjust the target and source handle positions based on the layout | |
// direction. | |
targetPosition: isHorizontal ? 'left' : 'top', | |
sourcePosition: isHorizontal ? 'right' : 'bottom', | |
// Hardcode a width and height for elk to use when layouting. | |
width: 150, | |
height: 50, | |
})), | |
edges: edges, | |
}; | |
return elk | |
.layout(graph) | |
.then((layoutedGraph) => ({ | |
nodes: layoutedGraph.children.map((node) => ({ | |
...node, | |
// React Flow expects a position property on the node instead of `x` | |
// and `y` fields. | |
position: { x: node.x, y: node.y }, | |
})), | |
edges: layoutedGraph.edges, | |
})) | |
.catch(console.error); | |
}; | |