import dagre from 'dagre' ; import type { SizedPlanNode } from './flow' ; interface GraphNode < T = any > { nodeData : T ; id : string ; width : number ; height : number ; x : number ; y : number ; } interface GraphEdge { nodes : { from : string ; to : string ; } ; points : { x : number ; y : number ; } [ ] ; } export interface Graph < T > { nodes : GraphNode < T > [ ] ; edges : GraphEdge [ ] ; } export interface SizedNode { id : string ; width : number ; height : number ; children ? : SizedPlanNode [ ] ; } /**
 * Calculates layout from array of SizedNodes.
 * returns nodes, edges and graph information
 */ const createLayout = < T > ( nodes ) : Graph < T > => { const g = new dagre . graphlib . Graph ( ) ; g . setGraph ( { rankdir : 'TB' , ranksep : 100 , nodesep : 100 , edgesep : 100 } ) ; g . setDefaultEdgeLabel ( ( ) => ( { } ) ) ; nodes . forEach ( ( node ) => { g . setNode ( node . id , { nodeData : node , id : node . id , width : node . width , height : node . height , } ) ; node . children ?. forEach ( ( child ) => { g . setEdge ( node . id , child . id ) ; } ) ; } ) ; dagre . layout ( g ) ; return { nodes : g . nodes ( ) . map ( ( node ) => g . node ( node ) ) , edges : g . edges ( ) . map ( ( edge ) => ( { ... g . edge ( edge ) , nodes : { from : edge . v , to : edge . w } , } ) ) , } ; } ; export default createLayout ;