@@ -81,21 +81,31 @@ async function layout(
8181 } ) ;
8282 nodes = nodes . filter ( ( n ) => ! isHiddenNode ( showOnlySelected , navHistory , n ) ) ;
8383 edges = edges . filter ( ( e ) => ! isHiddenEdge ( showOnlySelected , navHistory , e ) ) ;
84- const groupNodes = nodes
85- . filter ( ( node ) => node . type === 'group' )
86- . map ( ( node ) => ( { [ node . id ] : node } ) )
87- . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) ;
88- nodes
89- . filter ( ( node ) => node . type !== 'group' )
90- . forEach (
91- ( node ) =>
92- ( groupNodes [ node . parentNode ] = {
93- ...groupNodes [ node . parentNode ] ,
94- children : (
95- groupNodes [ node . parentNode ] ?. children || [ ]
96- ) . concat ( node ) ,
97- } ) ,
98- ) ;
84+
85+ const nodesMap = new Map (
86+ nodes . map ( ( node ) => [
87+ node . id ,
88+ {
89+ node,
90+ elkNode : {
91+ id : node . id ,
92+ width : node . width ?? undefined ,
93+ height : node . height ?? undefined ,
94+ children : [ ] ,
95+ } ,
96+ } ,
97+ ] ) ,
98+ ) ;
99+
100+ for ( const { node, elkNode } of nodesMap . values ( ) ) {
101+ if ( node . type === 'group' ) {
102+ continue ;
103+ }
104+ if ( node . parentNode === undefined ) {
105+ return ;
106+ }
107+ nodesMap . get ( node . parentNode ) . elkNode . children . push ( elkNode ) ;
108+ }
99109
100110 // Primitive edges are deprecated in ELK, so we should use ElkExtendedEdge, that use arrays, essentially hyperedges
101111 const elkEdges = edges . map ( ( edge ) => ( {
@@ -107,36 +117,41 @@ async function layout(
107117 const graph = {
108118 id : 'root' ,
109119 layoutOptions,
110- children : Object . keys ( groupNodes ) . map ( ( key ) => groupNodes [ key ] ) ,
120+ children : [ ...nodesMap . values ( ) ]
121+ . filter ( ( { node } ) => node . type === 'group' )
122+ . map ( ( { elkNode } ) => elkNode ) ,
111123 edges : elkEdges ,
112124 } ;
113125
114- function elk2flow ( node , flattenChildren ) {
115- node . position = { x : node . x , y : node . y } ;
126+ function elk2flow ( elkNode , flatChildren ) {
127+ const node = nodesMap . get ( elkNode . id ) . node ;
128+
129+ node . position = { x : elkNode . x , y : elkNode . y } ;
116130 node . style = {
117131 ...node . style ,
118- width : node . width ,
119- height : node . height ,
132+ width : elkNode . width ,
133+ height : elkNode . height ,
120134 } ;
121- flattenChildren . push ( node ) ;
122- ( node . children ?? [ ] ) . forEach ( ( child ) => {
123- elk2flow ( child , flattenChildren ) ;
135+ node . width = elkNode . width ;
136+ node . height = elkNode . height ;
137+ flatChildren . push ( node ) ;
138+ ( elkNode . children ?? [ ] ) . forEach ( ( child ) => {
139+ elk2flow ( child , flatChildren ) ;
124140 } ) ;
125- delete node . children ;
126141 }
127142
128143 const elk = new ELK ( ) ;
129144 const { children } = await elk . layout ( graph ) ;
130145
131146 // By mutating the children in-place we saves ourselves from creating a
132147 // needless copy of the nodes array.
133- const flattenChildren = [ ] ;
148+ const flatChildren = [ ] ;
134149
135- children . forEach ( ( node ) => {
136- elk2flow ( node , flattenChildren ) ;
150+ children . forEach ( ( elkNode ) => {
151+ elk2flow ( elkNode , flatChildren ) ;
137152 } ) ;
138153
139- setNodes ( flattenChildren ) ;
154+ setNodes ( flatChildren ) ;
140155 setEdges ( edges ) ;
141156 window . requestAnimationFrame ( ( ) => {
142157 if ( navHistory ?. length ) {
@@ -147,7 +162,7 @@ async function layout(
147162 fitView ( ) ;
148163 }
149164 } ) ;
150- return flattenChildren ;
165+ return flatChildren ;
151166}
152167
153168const highlightColor = 'rgba(170,255,170,0.71)' ;
0 commit comments