@@ -34,8 +34,13 @@ interface EdgeProxyNodeLabel extends Omit<NodeLabel, 'e'> {
3434 e : Edge ;
3535}
3636
37- let _oldGraph : Graph < GraphLabel , NodeLabel , EdgeLabel > | null = null ;
38- let _rawOldNodes : NodeCollection = null ;
37+ interface PreviousLayout {
38+ graph : Graph < GraphLabel , NodeLabel , EdgeLabel > ;
39+ rawNodes : NodeCollection ;
40+ }
41+
42+ // Remember layout state per input graph so unrelated callers cannot affect each other.
43+ const previousLayouts = new WeakMap < Graph < GraphLabel , NodeLabel , EdgeLabel > , PreviousLayout > ( ) ;
3944
4045export function layout ( g : Graph < GraphLabel , NodeLabel , EdgeLabel > , opts : LayoutOptions = { } ) : Graph < GraphLabel , NodeLabel , EdgeLabel > {
4146 recursiveClusterLayout ( g , util . notime , opts ) ;
@@ -97,7 +102,7 @@ function recursiveClusterLayout(g: Graph<GraphLabel, NodeLabel, EdgeLabel>, time
97102 recursiveClusterLayout ( subgraph , time , opts ) ;
98103 // Run the layout pipeline on the subgraph via a proper layout graph
99104 const subLayoutG = buildLayoutGraph ( subgraph ) ;
100- runLayout ( subLayoutG , time , opts ) ;
105+ runLayout ( subLayoutG , time , opts , null ) ;
101106 updateInputGraph ( subgraph , subLayoutG ) ;
102107 // Compute bounding box for the cluster
103108 let minX = Infinity , minY = Infinity , maxX = - Infinity , maxY = - Infinity ;
@@ -235,7 +240,8 @@ function recursiveClusterLayout(g: Graph<GraphLabel, NodeLabel, EdgeLabel>, time
235240
236241 // --- Step 5: run the main layout for the top-level graph ---
237242 const layoutG = buildLayoutGraph ( g ) ;
238- runLayout ( layoutG , time , opts ) ;
243+ const result = runLayout ( layoutG , time , opts , previousLayouts . get ( g ) ?? null ) ;
244+ previousLayouts . set ( g , result ) ;
239245 updateInputGraph ( g , layoutG ) ;
240246
241247 // --- Step 6: remove proxy edges, restore cluster internals, position children ---
@@ -317,15 +323,15 @@ function recursiveClusterLayout(g: Graph<GraphLabel, NodeLabel, EdgeLabel>, time
317323function runLayout (
318324 g : Graph < GraphLabel , NodeLabel , EdgeLabel > ,
319325 time : < T > ( name : string , fn : ( ) => T ) => T ,
320- opts : LayoutOptions
321- ) : void {
322- if ( opts ?. useDynamic === false ) {
323- _oldGraph = null ;
324- _rawOldNodes = null ;
325- }
326+ opts : LayoutOptions ,
327+ previous : PreviousLayout | null = null
328+ ) : PreviousLayout {
329+ const dynamic = opts ?. useDynamic !== false ;
330+ const oldGraph = dynamic ? previous ?. graph ?? null : null ;
331+ const rawOldNodes = dynamic ? previous ?. rawNodes ?? null : null ;
326332 time ( " makeSpaceForEdgeLabels" , ( ) => makeSpaceForEdgeLabels ( g ) ) ;
327333 time ( " removeSelfEdges" , ( ) => removeSelfEdges ( g ) ) ;
328- time ( " acyclic" , ( ) => acyclic . run ( g , _oldGraph ) ) ;
334+ time ( " acyclic" , ( ) => acyclic . run ( g , oldGraph ) ) ;
329335 time ( " nestingGraph.run" , ( ) => nestingGraph . run ( g ) ) ;
330336 time ( " rank" , ( ) => rank ( util . asNonCompoundGraph ( g ) ) ) ;
331337 time ( " injectEdgeLabelProxies" , ( ) => injectEdgeLabelProxies ( g ) ) ;
@@ -337,12 +343,12 @@ function runLayout(
337343 time ( " normalize.run" , ( ) => normalize . run ( g ) ) ;
338344 time ( " parentDummyChains" , ( ) => parentDummyChains ( g ) ) ;
339345 time ( " addBorderSegments" , ( ) => addBorderSegments ( g ) ) ;
340- time ( " order" , ( ) => order ( g , opts , _rawOldNodes ) ) ;
346+ time ( " order" , ( ) => order ( g , opts , rawOldNodes ) ) ;
341347 time ( " insertSelfEdges" , ( ) => insertSelfEdges ( g ) ) ;
342348 time ( " adjustCoordinateSystem" , ( ) => coordinateSystem . adjust ( g ) ) ;
343349 time ( " position" , ( ) => position ( g , opts . corePath ) ) ;
344350 time ( " positionSelfEdges" , ( ) => positionSelfEdges ( g ) ) ;
345- _rawOldNodes = JSON . parse ( JSON . stringify ( ( g as unknown as { _nodes : NodeCollection } ) . _nodes ) ) ;
351+ const rawNodes : NodeCollection = JSON . parse ( JSON . stringify ( ( g as unknown as { _nodes : NodeCollection } ) . _nodes ) ) ;
346352 time ( " removeBorderNodes" , ( ) => removeBorderNodes ( g ) ) ;
347353 time ( " normalize.undo" , ( ) => normalize . undo ( g ) ) ;
348354 time ( " fixupEdgeLabelCoords" , ( ) => fixupEdgeLabelCoords ( g ) ) ;
@@ -351,7 +357,8 @@ function runLayout(
351357 time ( " assignNodeIntersects" , ( ) => assignNodeIntersects ( g ) ) ;
352358 time ( " reversePoints" , ( ) => reversePointsForReversedEdges ( g ) ) ;
353359 time ( " acyclic.undo" , ( ) => acyclic . undo ( g ) ) ;
354- _oldGraph = g ;
360+
361+ return { graph : g , rawNodes} ;
355362}
356363
357364/*
0 commit comments