11import { forEach , map } from 'lodash-es'
2- import LogicFlow , { ElementState , LogicFlowUtil } from '@logicflow/core'
2+ import LogicFlow , {
3+ ElementState ,
4+ OverlapMode ,
5+ ModelType ,
6+ } from '@logicflow/core'
37import '@logicflow/core/es/index.css'
48
5- import { Button , Card , Divider , Flex } from 'antd'
6- import { useEffect , useRef } from 'react'
9+ import { Button , Card , Divider , Flex , Drawer } from 'antd'
10+ import { useEffect , useRef , useState } from 'react'
711import { combine , square , star , uml , user } from './nodes'
812import { animation , connection } from './edges'
913
@@ -12,6 +16,7 @@ import customRect from '@/components/nodes/custom-rect'
1216import customEllipse from '@/components/nodes/custom-ellipse'
1317import customDiamond from '@/components/nodes/custom-diamond'
1418import customPolygon from '@/components/nodes/custom-polygon'
19+ import centerAnchorRect from './nodes/centerAnchorRect'
1520
1621import GraphData = LogicFlow . GraphData
1722import styles from './index.less'
@@ -98,6 +103,7 @@ const data = {
98103 type : 'rect' ,
99104 x : 600 ,
100105 y : 200 ,
106+
101107 properties : {
102108 width : 80 ,
103109 height : 120 ,
@@ -111,9 +117,17 @@ const data = {
111117 x : 90 ,
112118 y : 94 ,
113119 } ,
120+ {
121+ id : 'custom-node-3' ,
122+ text : 'node-3' ,
123+ type : 'centerAnchorRect' ,
124+ x : 360 ,
125+ y : 280 ,
126+ } ,
114127 ] ,
115128 edges : [
116129 {
130+ id : 'bezier-1' ,
117131 type : 'bezier' ,
118132 sourceNodeId : 'custom-node-1' ,
119133 targetNodeId : 'custom-node-2' ,
@@ -123,6 +137,17 @@ const data = {
123137 } ,
124138 } ,
125139 } ,
140+ {
141+ id : 'bezier-2' ,
142+ type : 'bezier' ,
143+ sourceNodeId : 'custom-node-2' ,
144+ targetNodeId : 'custom-node-3' ,
145+ properties : {
146+ style : {
147+ stroke : 'blue' ,
148+ } ,
149+ } ,
150+ } ,
126151 ] ,
127152}
128153
@@ -169,6 +194,11 @@ const data = {
169194export default function BasicNode ( ) {
170195 const lfRef = useRef < LogicFlow > ( )
171196 const containerRef = useRef < HTMLDivElement > ( null )
197+ const [ open , setOpen ] = useState ( false )
198+
199+ const onClose = ( ) => {
200+ setOpen ( false )
201+ }
172202
173203 const registerElements = ( lf : LogicFlow ) => {
174204 const elements : LogicFlow . RegisterConfig [ ] = [
@@ -186,6 +216,7 @@ export default function BasicNode() {
186216 customEllipse ,
187217 customDiamond ,
188218 customPolygon ,
219+ centerAnchorRect ,
189220 ]
190221
191222 map ( elements , ( customElement ) => {
@@ -205,6 +236,10 @@ export default function BasicNode() {
205236 lf . on ( 'edge:click' , ( data ) => {
206237 console . log ( 'edge:click' , data )
207238 } )
239+ lf . on ( 'node:click' , ( data ) => {
240+ console . log ( 'node:click' , data )
241+ setOpen ( true )
242+ } )
208243 }
209244
210245 useEffect ( ( ) => {
@@ -253,9 +288,9 @@ export default function BasicNode() {
253288 } ,
254289 partial : true ,
255290 background : {
256- // color: '#FFFFFF',
257- backgroundImage :
258- "url('https://cdn.jsdelivr.net/gh/Logic-Flow/static@latest/core/rect.png')" ,
291+ color : '#FFFFFF' ,
292+ // backgroundImage:
293+ // "url('https://cdn.jsdelivr.net/gh/Logic-Flow/static@latest/core/rect.png')",
259294 } ,
260295 // grid: true,
261296 grid : {
@@ -363,92 +398,194 @@ export default function BasicNode() {
363398 }
364399 }
365400
366- const handleChangeColor = ( ) => {
401+ // overlapMode 测试逻辑
402+ const setOverlapMode = ( mode : OverlapMode ) => {
367403 const lf = lfRef . current
368- if ( lf ) {
369- const { edges } = lf . graphModel
370- edges . forEach ( ( { id } ) => {
371- lf . setProperties ( id , {
372- style : {
373- stroke : 'blue' ,
374- } ,
375- } )
376- } )
377- }
404+ if ( ! lf ) return
405+ lf . setOverlapMode ( mode )
406+ const order = lf . graphModel . sortElements . map ( ( m ) => m . id )
407+ console . log ( '[overlapMode]' , mode , '排序结果:' , order )
378408 }
409+ const setOverlapModeStatic = ( ) => setOverlapMode ( OverlapMode . STATIC )
410+ const setOverlapModeDefault = ( ) => setOverlapMode ( OverlapMode . DEFAULT )
411+ const setOverlapModeIncrease = ( ) => setOverlapMode ( OverlapMode . INCREASE )
412+ const setOverlapModeEdgeTop = ( ) => setOverlapMode ( OverlapMode . EDGE_TOP )
379413
380- const handleRefreshGraph = ( ) => {
414+ const addOverlapNode = ( ) => {
381415 const lf = lfRef . current
382- if ( lf ) {
383- const data = lf . getGraphRawData ( )
384- console . log ( 'current graph data' , data )
385- const refreshData = LogicFlowUtil . refreshGraphId ( data )
386- console . log ( 'after refresh graphId' , data )
387- lf . render ( refreshData )
388-
389- // 测试 getAreaElement API
390- // const lt: LogicFlow.PointTuple = [550, 130];
391- // const rb: LogicFlow.PointTuple = [650, 270];
392- // const areaElements = lf.getAreaElement(lt, rb);
393- // console.log('areaElements', areaElements);
416+ if ( ! lf ) return
417+ lf . addNode ( {
418+ id : 'overlap-node' ,
419+ text : 'overlap-node' ,
420+ type : 'rect' ,
421+ x : 400 ,
422+ y : 150 ,
423+ properties : { width : 60 , height : 60 } ,
424+ } )
425+ }
426+ const deleteOverlapNode = ( ) => {
427+ lfRef . current ?. deleteNode ( 'overlap-node' )
428+ }
429+ const selectFirstEdge = ( ) => {
430+ const lf = lfRef . current
431+ if ( ! lf ) return
432+ const data = lf . getGraphData ( ) as GraphData
433+ const edgeId = data . edges ?. [ 0 ] ?. id
434+ if ( edgeId ) {
435+ lf . selectElementById ( edgeId )
436+ lf . toFront ( edgeId )
437+ console . log ( '选中并置顶首条边:' , edgeId )
394438 }
395439 }
440+ const selectOverlapNode = ( ) => {
441+ const lf = lfRef . current
442+ if ( ! lf ) return
443+ const id = 'overlap-node'
444+ lf . selectElementById ( id )
445+ lf . toFront ( id )
446+ console . log ( '选中并置顶重叠节点:' , id )
447+ }
448+ const clearSelection = ( ) => {
449+ lfRef . current ?. clearSelectElements ( )
450+ }
396451
452+ // 其他演示用处理函数
397453 const handleActiveElements = ( ) => {
398454 const lf = lfRef . current
399- if ( lf ) {
400- const { nodes, edges } = lf . getSelectElements ( )
401- nodes . forEach ( ( { id } ) => {
402- lf . setProperties ( id , {
403- isHovered : true ,
404- } )
405- } )
406- edges . forEach ( ( { id } ) => {
407- lf . setProperties ( id , {
408- isHovered : true ,
409- } )
410- } )
411- }
455+ if ( ! lf ) return
456+ const { nodes, edges } = lf . getSelectElements ( )
457+ nodes . forEach ( ( { id } ) => {
458+ lf . setProperties ( id , { isHovered : true } )
459+ } )
460+ edges . forEach ( ( { id } ) => {
461+ lf . setProperties ( id , { isHovered : true } )
462+ } )
412463 }
413464
414465 const handleTurnAnimationOn = ( ) => {
415- if ( lfRef . current ) {
416- const { edges } = lfRef . current . getGraphData ( ) as GraphData
417- forEach ( edges , ( edge ) => {
418- lfRef . current ?. openEdgeAnimation ( edge . id )
419- } )
420- }
466+ const lf = lfRef . current
467+ if ( ! lf ) return
468+ const { edges } = lf . getGraphData ( ) as GraphData
469+ forEach ( edges , ( edge ) => {
470+ if ( ( edge as any ) . id ) lf . openEdgeAnimation ( ( edge as any ) . id )
471+ } )
421472 }
473+
422474 const handleTurnAnimationOff = ( ) => {
423- if ( lfRef . current ) {
424- const { edges } = lfRef . current . getGraphData ( ) as GraphData
425- forEach ( edges , ( edge ) => {
426- lfRef . current ?. closeEdgeAnimation ( edge . id )
427- } )
428- }
475+ const lf = lfRef . current
476+ if ( ! lf ) return
477+ const { edges } = lf . getGraphData ( ) as GraphData
478+ forEach ( edges , ( edge ) => {
479+ if ( ( edge as any ) . id ) lf . closeEdgeAnimation ( ( edge as any ) . id )
480+ } )
481+ }
482+
483+ const handleDragItem = ( cfg : OnDragNodeConfig ) => {
484+ const lf = lfRef . current
485+ if ( ! lf ) return
486+ lf . dnd ?. startDrag ( cfg )
429487 }
430488
431- const handleDragItem = ( node : OnDragNodeConfig ) => {
432- lfRef ?. current ?. dnd . startDrag ( node )
489+ const handleRefreshGraph = ( ) => {
490+ const lf = lfRef . current
491+ if ( ! lf ) return
492+ const raw = lf . getGraphRawData ?.( )
493+ console . log ( '当前原始数据:' , raw || lf . getGraphData ( ) )
494+ }
495+
496+ const handleChangeColor = ( ) => {
497+ const lf = lfRef . current
498+ if ( ! lf ) return
499+ const { edges } = lf . getSelectElements ( )
500+ edges . forEach ( ( { id } ) => {
501+ lf . setProperties ( id , { style : { stroke : '#ff4d4f' } } )
502+ } )
433503 }
434504
435505 const changeNodeBorderColor = ( ) => {
436506 const lf = lfRef . current
437- if ( lf ) {
438- const { nodes } = lf . getSelectElements ( )
439- nodes . forEach ( ( { id, properties } ) => {
440- console . log ( 'properties' , properties )
441- lf . setProperties ( id , {
442- style : {
443- stroke : 'pink' ,
444- } ,
445- } )
446- } )
447- }
507+ if ( ! lf ) return
508+ const { nodes } = lf . getSelectElements ( )
509+ nodes . forEach ( ( { id } ) => {
510+ lf . setProperties ( id , { style : { stroke : '#ff4d4f' } } )
511+ } )
448512 }
449513
450514 return (
451515 < Card title = "Graph" >
516+ < Flex wrap = "wrap" gap = "small" >
517+ { /* overlapMode 测试控制 */ }
518+ < Button
519+ key = "overlap-static"
520+ type = "primary"
521+ onClick = { setOverlapModeStatic }
522+ >
523+ 静态堆叠模式
524+ </ Button >
525+ < Button
526+ key = "overlap-default"
527+ type = "primary"
528+ onClick = { setOverlapModeDefault }
529+ >
530+ 默认堆叠模式
531+ </ Button >
532+ < Button
533+ key = "overlap-increase"
534+ type = "primary"
535+ onClick = { setOverlapModeIncrease }
536+ >
537+ 递增堆叠模式
538+ </ Button >
539+ < Button
540+ key = "overlap-edge-top"
541+ type = "primary"
542+ onClick = { setOverlapModeEdgeTop }
543+ >
544+ 边置顶模式
545+ </ Button >
546+ < Button
547+ key = "print-sort"
548+ type = "primary"
549+ onClick = { ( ) => {
550+ const lf = lfRef . current
551+ if ( ! lf ) return
552+ const order = lf . graphModel . sortElements . map ( ( m ) =>
553+ m . modelType === ModelType . EDGE ? 'edge' : 'node' ,
554+ )
555+ console . log ( '当前渲染排序:' , order )
556+ } }
557+ >
558+ 打印渲染排序
559+ </ Button >
560+ < Button key = "add-overlap-node" type = "primary" onClick = { addOverlapNode } >
561+ 添加重叠节点
562+ </ Button >
563+ < Button
564+ key = "delete-overlap-node"
565+ type = "primary"
566+ onClick = { deleteOverlapNode }
567+ >
568+ 删除重叠节点
569+ </ Button >
570+ < Button
571+ key = "select-first-edge"
572+ type = "primary"
573+ onClick = { selectFirstEdge }
574+ >
575+ 选中并置顶首条边
576+ </ Button >
577+ < Button
578+ key = "select-overlap-node"
579+ type = "primary"
580+ onClick = { selectOverlapNode }
581+ >
582+ 选中并置顶重叠节点
583+ </ Button >
584+ < Button key = "clear-selection" type = "primary" onClick = { clearSelection } >
585+ 取消选中
586+ </ Button >
587+ </ Flex >
588+ < Divider orientation = "left" orientationMargin = "5" plain > </ Divider >
452589 < Flex wrap = "wrap" gap = "small" >
453590 < Button key = "arrow1" type = "primary" onClick = { ( ) => setArrow ( 'half' ) } >
454591 箭头 1
@@ -725,6 +862,16 @@ export default function BasicNode() {
725862 </ Flex >
726863 < Divider />
727864 < div ref = { containerRef } id = "graph" className = { styles . viewport } > </ div >
865+ < Drawer
866+ title = "Basic Drawer"
867+ closable = { { 'aria-label' : 'Close Button' } }
868+ onClose = { onClose }
869+ open = { open }
870+ >
871+ < p > Some contents...</ p >
872+ < p > Some contents...</ p >
873+ < p > Some contents...</ p >
874+ </ Drawer >
728875 </ Card >
729876 )
730877}
0 commit comments