11import dagre from "@dagrejs/dagre" ;
2- import React , { memo , useEffect , useLayoutEffect , useState } from "react" ;
3-
4- export const PlanViewer = memo ( ( { nested, height, width, nodes, edges, renderNode, renderEdge, onRendered, drawExtra} ) => {
2+ import React , { memo , useEffect , useLayoutEffect , useRef , useState } from "react" ;
3+
4+ export const PlanViewer = memo ( ( {
5+ nested,
6+ height,
7+ width,
8+ nodes,
9+ edges,
10+ renderNode,
11+ renderEdge,
12+ onRendered,
13+ drawExtra
14+ } ) => {
515
616 //dagre.layout(g);
717 const [ internalEdges , setInternalEdges ] = useState ( [ ] )
8-
18+ const isMounted = useRef ( false ) ;
919
1020 const stageWidth = width ;
1121 const stageHeight = height ;
@@ -45,7 +55,12 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
4555 const [ nodesPos , setNodesPos ] = useState ( undefined )
4656
4757 const render = ( nodes , edges ) => {
48- const g = new dagre . graphlib . Graph ( ) . setGraph ( { nodesep : 30 , ranksep : 20 , marginy :nested ? 20 :0 , marginx :nested ?10 :0 } ) ;
58+ const g = new dagre . graphlib . Graph ( ) . setGraph ( {
59+ nodesep : 30 ,
60+ ranksep : 20 ,
61+ marginy : nested ? 20 : 0 ,
62+ marginx : nested ? 10 : 0
63+ } ) ;
4964 nodes . forEach ( ( node ) => {
5065 const element = document . getElementById ( `plan-${ node . ref } ` )
5166 const nodeWidth = element . offsetWidth
@@ -57,10 +72,10 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
5772 } )
5873 dagre . layout ( g ) ;
5974 let newNodesLayout = { }
60- let newNodesPos = { }
75+ let newNodesPos = { }
6176 g . nodes ( ) . forEach ( ( nodeId ) => {
6277 let node = g . node ( nodeId ) ;
63- if ( node === undefined ) {
78+ if ( node === undefined ) {
6479 console . log ( "unknown node" , nodeId , JSON . stringify ( nodeId ) )
6580 }
6681 newNodesLayout [ nodeId ] = {
@@ -69,7 +84,7 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
6984 width : node . width ,
7085 height : node . height
7186 }
72- newNodesPos [ nodeId ] = {
87+ newNodesPos [ nodeId ] = {
7388 computedX : node . x ,
7489 computedY : node . y ,
7590 renderX : node . x - node . width / 2 ,
@@ -100,12 +115,12 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
100115 setInternalEdges ( newEdges )
101116 const requiredWidth = g . nodes ( ) . reduce ( ( maxWidth , nodeId ) => {
102117 let node = g . node ( nodeId ) ;
103- return Math . max ( maxWidth , node . x + node . width / 2 ) ;
104- } , 0 ) + ( nested ? 10 : 0 ) ;
118+ return Math . max ( maxWidth , node . x + node . width / 2 ) ;
119+ } , 0 ) + ( nested ? 10 : 0 ) ;
105120 const requiredHeight = g . nodes ( ) . reduce ( ( maxHeight , nodeId ) => {
106121 let node = g . node ( nodeId ) ;
107- return Math . max ( maxHeight , node . y + node . height / 2 ) ;
108- } , 0 ) + ( nested ? 20 : 0 ) ;
122+ return Math . max ( maxHeight , node . y + node . height / 2 ) ;
123+ } , 0 ) + ( nested ? 20 : 0 ) ;
109124 setRequiredWidth ( requiredWidth )
110125 setRequiredHeight ( requiredHeight )
111126 const newScale = Math . min ( stageWidth / requiredWidth , stageHeight / requiredHeight )
@@ -116,9 +131,19 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
116131
117132 }
118133 useEffect ( ( ) => {
134+ isMounted . current = true
119135 render ( nodes , edges )
120- setTimeout ( ( ) => render ( nodes , edges ) , 500 )
121- setTimeout ( ( ) => render ( nodes , edges ) , 1000 )
136+ let timer1 = setTimeout ( ( ) => {
137+ if ( isMounted . current ) render ( nodes , edges )
138+ } , 500 )
139+ let timer2 = setTimeout ( ( ) => {
140+ if ( isMounted . current ) render ( nodes , edges )
141+ } , 1000 )
142+ return ( ) => {
143+ isMounted . current = false
144+ clearTimeout ( timer1 )
145+ clearTimeout ( timer2 )
146+ }
122147 } , [ nodes , edges ] )
123148
124149
@@ -127,7 +152,7 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
127152 < div >
128153 < div style = { {
129154 backgroundColor : "lightgray" ,
130- position :"relative" ,
155+ position : "relative" ,
131156 } } >
132157 < svg style = { {
133158 backgroundColor : "lightgray" ,
@@ -138,7 +163,7 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
138163 < g >
139164 {
140165
141- internalEdges . map ( ( e ) => renderEdge ( e , nodesPos ) )
166+ internalEdges . map ( ( e ) => renderEdge ( e , nodesPos ) )
142167 }
143168 { drawExtra && drawExtra ( nodesPos , requiredHeight ) }
144169
@@ -152,7 +177,7 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
152177 position : "absolute"
153178 } } >
154179 { nodes . map ( ( node ) => {
155- return renderNode ( node , node . ref in nodesLayout ? nodesLayout [ node . ref ] . x : 0 , node . ref in nodesLayout ? nodesLayout [ node . ref ] . y : 0 , ( ) => render ( nodes , edges ) )
180+ return renderNode ( node , node . ref in nodesLayout ? nodesLayout [ node . ref ] . x : 0 , node . ref in nodesLayout ? nodesLayout [ node . ref ] . y : 0 , ( ) => render ( nodes , edges ) )
156181 } ) }
157182
158183 </ div >
@@ -180,16 +205,16 @@ export const PlanViewer = memo(({nested, height, width, nodes, edges, renderNode
180205 height : requiredHeight ,
181206 backgroundColor : "lightgray" ,
182207 userSelect : "none" ,
183- top :0 ,
184- left :0 ,
185- position :"absolute"
208+ top : 0 ,
209+ left : 0 ,
210+ position : "absolute"
186211 } } >
187212 < g >
188213 {
189214
190- internalEdges . map ( ( e ) => renderEdge ( e , nodesPos ) )
215+ internalEdges . map ( ( e ) => renderEdge ( e , nodesPos ) )
191216 }
192- { drawExtra && drawExtra ( nodesPos , requiredHeight ) }
217+ { drawExtra && drawExtra ( nodesPos , requiredHeight ) }
193218 </ g >
194219 </ svg >
195220 < div style = { {
0 commit comments