Skip to content

Commit cb181b2

Browse files
DymoneLewisboyongjiong
authored andcommitted
feat: 增加边层级优先堆叠模式和静态堆叠模式 fix #2063
1 parent 80d089b commit cb181b2

File tree

12 files changed

+577
-177
lines changed

12 files changed

+577
-177
lines changed

examples/feature-examples/src/pages/graph/index.tsx

Lines changed: 215 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { 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'
37
import '@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'
711
import { combine, square, star, uml, user } from './nodes'
812
import { animation, connection } from './edges'
913

@@ -12,6 +16,7 @@ import customRect from '@/components/nodes/custom-rect'
1216
import customEllipse from '@/components/nodes/custom-ellipse'
1317
import customDiamond from '@/components/nodes/custom-diamond'
1418
import customPolygon from '@/components/nodes/custom-polygon'
19+
import centerAnchorRect from './nodes/centerAnchorRect'
1520

1621
import GraphData = LogicFlow.GraphData
1722
import 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 = {
169194
export 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

Comments
 (0)