1
- import { memo , useCallback , useEffect , useState } from 'react' ;
1
+ import { memo , useCallback , useEffect , useState , useTransition } from 'react' ;
2
2
import {
3
3
ReactFlow ,
4
4
Node ,
5
5
Edge ,
6
6
useNodesState ,
7
7
useEdgesState ,
8
8
Position ,
9
- useReactFlow ,
10
9
ConnectionMode ,
11
10
Background ,
12
11
BackgroundVariant ,
@@ -88,7 +87,6 @@ const getNodeStyle = ({
88
87
} ;
89
88
} ;
90
89
91
- // 边的样式
92
90
const edgeStyle = {
93
91
stroke : '#4a90e2' ,
94
92
strokeWidth : 2
@@ -148,37 +146,34 @@ const TreeVisualizerContent = ({ parseTree }: TreeVisualizerPanelProps) => {
148
146
const [ nodes , setNodes , onNodesChange ] = useNodesState < Node < NodeData > > ( [ ] ) ;
149
147
const [ edges , setEdges , onEdgesChange ] = useEdgesState < Edge > ( [ ] ) ;
150
148
const [ selectedNodeId , setSelectedNodeId ] = useState < string | null > ( null ) ;
151
- const { fitView } = useReactFlow ( ) ;
149
+ const [ _ , startTransition ] = useTransition ( ) ;
152
150
153
151
// 获取节点的所有子节点ID
154
- const getChildNodeIds = useCallback (
155
- ( nodeId : string | null ) : string [ ] => {
156
- if ( ! nodeId ) return [ ] ;
157
- const childIds : string [ ] = [ ] ;
158
- const queue = [ nodeId ] ;
159
-
160
- while ( queue . length > 0 ) {
161
- const currentId = queue . shift ( ) ! ;
162
- edges . forEach ( ( edge ) => {
163
- if ( edge . source === currentId ) {
164
- childIds . push ( edge . target ) ;
165
- queue . push ( edge . target ) ;
166
- }
167
- } ) ;
168
- }
152
+ const getChildNodeIds = ( nodeId : string | null ) : string [ ] => {
153
+ if ( ! nodeId ) return [ ] ;
154
+ const childIds : string [ ] = [ ] ;
155
+ const queue = [ nodeId ] ;
156
+
157
+ while ( queue . length > 0 ) {
158
+ const currentId = queue . shift ( ) ! ;
159
+ edges . forEach ( ( edge ) => {
160
+ if ( edge . source === currentId ) {
161
+ childIds . push ( edge . target ) ;
162
+ queue . push ( edge . target ) ;
163
+ }
164
+ } ) ;
165
+ }
169
166
170
- return childIds ;
171
- } ,
172
- [ edges ]
173
- ) ;
167
+ return childIds ;
168
+ } ;
174
169
175
- const handleNodeClick = useCallback ( ( event : React . MouseEvent , node : Node ) => {
170
+ const handleNodeClick = ( _event : React . MouseEvent , node : Node ) => {
176
171
setSelectedNodeId ( node . id ) ;
177
- } , [ ] ) ;
172
+ } ;
178
173
179
- const handlePaneClick = useCallback ( ( ) => {
174
+ const handlePaneClick = ( ) => {
180
175
setSelectedNodeId ( null ) ;
181
- } , [ ] ) ;
176
+ } ;
182
177
183
178
const convertTreeToElements = useCallback ( ( tree : SerializedTreeNode ) => {
184
179
const newNodes : Node < NodeData > [ ] = [ ] ;
@@ -245,19 +240,20 @@ const TreeVisualizerContent = ({ parseTree }: TreeVisualizerPanelProps) => {
245
240
} , [ ] ) ;
246
241
247
242
useEffect ( ( ) => {
248
- if ( ! parseTree ) return ;
243
+ if ( ! parseTree ) {
244
+ setEdges ( [ ] ) ;
245
+ setNodes ( [ ] ) ;
246
+ return ;
247
+ }
249
248
250
249
const elements = convertTreeToElements ( parseTree ) ;
251
250
const layoutedElements = getLayoutedElements ( elements . nodes , elements . edges ) ;
252
251
253
- setNodes ( layoutedElements . nodes ) ;
254
- setEdges ( layoutedElements . edges ) ;
255
- setSelectedNodeId ( elements . rootNodeId ) ;
256
-
257
- // 等待节点渲染完成后自动适应视图
258
- setTimeout ( ( ) => {
259
- fitView ( { padding : 0.2 , includeHiddenNodes : false } ) ;
260
- } , 100 ) ;
252
+ startTransition ( ( ) => {
253
+ setNodes ( layoutedElements . nodes ) ;
254
+ setEdges ( layoutedElements . edges ) ;
255
+ setSelectedNodeId ( null ) ;
256
+ } ) ;
261
257
} , [ parseTree ] ) ;
262
258
263
259
useEffect ( ( ) => {
@@ -275,7 +271,7 @@ const TreeVisualizerContent = ({ parseTree }: TreeVisualizerPanelProps) => {
275
271
} )
276
272
} ) )
277
273
) ;
278
- } , [ selectedNodeId , getChildNodeIds ] ) ;
274
+ } , [ selectedNodeId ] ) ;
279
275
280
276
return (
281
277
< div style = { { height : '100%' , width : '100%' } } >
@@ -288,6 +284,7 @@ const TreeVisualizerContent = ({ parseTree }: TreeVisualizerPanelProps) => {
288
284
fitViewOptions = { { padding : 0.2 } }
289
285
minZoom = { 0.1 }
290
286
maxZoom = { 2 }
287
+ onlyRenderVisibleElements
291
288
onNodeClick = { handleNodeClick }
292
289
onPaneClick = { handlePaneClick }
293
290
defaultEdgeOptions = { {
0 commit comments