-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat(core): 新增边在上的堆叠模式 #2307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(core): 新增边在上的堆叠模式 #2307
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,5 +1,9 @@ | ||||||
| import { forEach, map } from 'lodash-es' | ||||||
| import LogicFlow, { ElementState, LogicFlowUtil } from '@logicflow/core' | ||||||
| import LogicFlow, { | ||||||
| ElementState, | ||||||
| OverlapMode, | ||||||
| ModelType, | ||||||
| } from '@logicflow/core' | ||||||
| import '@logicflow/core/es/index.css' | ||||||
|
|
||||||
| import { Button, Card, Divider, Flex } from 'antd' | ||||||
|
|
@@ -98,6 +102,7 @@ const data = { | |||||
| type: 'rect', | ||||||
| x: 600, | ||||||
| y: 200, | ||||||
|
|
||||||
| properties: { | ||||||
| width: 80, | ||||||
| height: 120, | ||||||
|
|
@@ -363,92 +368,186 @@ export default function BasicNode() { | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| const handleChangeColor = () => { | ||||||
| // overlapMode 测试逻辑 | ||||||
| const setOverlapMode = (mode: OverlapMode) => { | ||||||
| const lf = lfRef.current | ||||||
| if (lf) { | ||||||
| const { edges } = lf.graphModel | ||||||
| edges.forEach(({ id }) => { | ||||||
| lf.setProperties(id, { | ||||||
| style: { | ||||||
| stroke: 'blue', | ||||||
| }, | ||||||
| }) | ||||||
| }) | ||||||
| } | ||||||
| if (!lf) return | ||||||
| lf.graphModel.overlapMode = mode | ||||||
| const order = lf.graphModel.sortElements.map((m) => m.modelType) | ||||||
| console.log('[overlapMode]', mode, '排序结果:', order) | ||||||
| } | ||||||
| const setOverlapModeDefault = () => setOverlapMode(OverlapMode.DEFAULT) | ||||||
| const setOverlapModeIncrease = () => setOverlapMode(OverlapMode.INCREASE) | ||||||
| const setOverlapModeEdgeTop = () => setOverlapMode(OverlapMode.EDGE_TOP) | ||||||
|
|
||||||
| const handleRefreshGraph = () => { | ||||||
| const addOverlapNode = () => { | ||||||
| const lf = lfRef.current | ||||||
| if (lf) { | ||||||
| const data = lf.getGraphRawData() | ||||||
| console.log('current graph data', data) | ||||||
| const refreshData = LogicFlowUtil.refreshGraphId(data) | ||||||
| console.log('after refresh graphId', data) | ||||||
| lf.render(refreshData) | ||||||
|
|
||||||
| // 测试 getAreaElement API | ||||||
| // const lt: LogicFlow.PointTuple = [550, 130]; | ||||||
| // const rb: LogicFlow.PointTuple = [650, 270]; | ||||||
| // const areaElements = lf.getAreaElement(lt, rb); | ||||||
| // console.log('areaElements', areaElements); | ||||||
| if (!lf) return | ||||||
| lf.addNode({ | ||||||
| id: 'overlap-node', | ||||||
| text: 'overlap-node', | ||||||
| type: 'rect', | ||||||
| x: 400, | ||||||
| y: 150, | ||||||
| properties: { width: 60, height: 60 }, | ||||||
| }) | ||||||
| } | ||||||
| const deleteOverlapNode = () => { | ||||||
| lfRef.current?.deleteNode('overlap-node') | ||||||
| } | ||||||
| const selectFirstEdge = () => { | ||||||
| const lf = lfRef.current | ||||||
| if (!lf) return | ||||||
| const data = lf.getGraphData() as GraphData | ||||||
| const edgeId = data.edges?.[0]?.id | ||||||
| if (edgeId) { | ||||||
| lf.selectElementById(edgeId) | ||||||
| lf.toFront(edgeId) | ||||||
| console.log('选中并置顶首条边:', edgeId) | ||||||
| } | ||||||
| } | ||||||
| const selectOverlapNode = () => { | ||||||
| const lf = lfRef.current | ||||||
| if (!lf) return | ||||||
| const id = 'overlap-node' | ||||||
| lf.selectElementById(id) | ||||||
| lf.toFront(id) | ||||||
| console.log('选中并置顶重叠节点:', id) | ||||||
| } | ||||||
| const clearSelection = () => { | ||||||
| lfRef.current?.clearSelectElements() | ||||||
| } | ||||||
|
|
||||||
| // 其他演示用处理函数 | ||||||
| const handleActiveElements = () => { | ||||||
| const lf = lfRef.current | ||||||
| if (lf) { | ||||||
| const { nodes, edges } = lf.getSelectElements() | ||||||
| nodes.forEach(({ id }) => { | ||||||
| lf.setProperties(id, { | ||||||
| isHovered: true, | ||||||
| }) | ||||||
| }) | ||||||
| edges.forEach(({ id }) => { | ||||||
| lf.setProperties(id, { | ||||||
| isHovered: true, | ||||||
| }) | ||||||
| }) | ||||||
| } | ||||||
| if (!lf) return | ||||||
| const { nodes, edges } = lf.getSelectElements() | ||||||
| nodes.forEach(({ id }) => { | ||||||
| lf.setProperties(id, { isHovered: true }) | ||||||
| }) | ||||||
| edges.forEach(({ id }) => { | ||||||
| lf.setProperties(id, { isHovered: true }) | ||||||
| }) | ||||||
| } | ||||||
|
|
||||||
| const handleTurnAnimationOn = () => { | ||||||
| if (lfRef.current) { | ||||||
| const { edges } = lfRef.current.getGraphData() as GraphData | ||||||
| forEach(edges, (edge) => { | ||||||
| lfRef.current?.openEdgeAnimation(edge.id) | ||||||
| }) | ||||||
| } | ||||||
| const lf = lfRef.current | ||||||
| if (!lf) return | ||||||
| const { edges } = lf.getGraphData() as GraphData | ||||||
| forEach(edges, (edge) => { | ||||||
| if ((edge as any).id) lf.openEdgeAnimation((edge as any).id) | ||||||
| }) | ||||||
| } | ||||||
|
|
||||||
| const handleTurnAnimationOff = () => { | ||||||
| if (lfRef.current) { | ||||||
| const { edges } = lfRef.current.getGraphData() as GraphData | ||||||
| forEach(edges, (edge) => { | ||||||
| lfRef.current?.closeEdgeAnimation(edge.id) | ||||||
| }) | ||||||
| } | ||||||
| const lf = lfRef.current | ||||||
| if (!lf) return | ||||||
| const { edges } = lf.getGraphData() as GraphData | ||||||
| forEach(edges, (edge) => { | ||||||
| if ((edge as any).id) lf.closeEdgeAnimation((edge as any).id) | ||||||
|
||||||
| if ((edge as any).id) lf.closeEdgeAnimation((edge as any).id) | |
| lf.closeEdgeAnimation(edge.id) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -249,6 +249,48 @@ export class GraphModel { | |
| * todo: 性能优化 | ||
| */ | ||
| @computed get sortElements() { | ||
| // 在 EDGE_TOP 模式下,先渲染节点,再渲染边,保证边始终在顶部。 | ||
| if (this.overlapMode === OverlapMode.EDGE_TOP) { | ||
| const nodesSorted = [...this.nodes].sort((a, b) => a.zIndex - b.zIndex) | ||
| const edgesSorted = [...this.edges].sort((a, b) => a.zIndex - b.zIndex) | ||
|
|
||
| const visibleNodes: (BaseNodeModel | BaseEdgeModel)[] = [] | ||
| const visibleEdges: (BaseNodeModel | BaseEdgeModel)[] = [] | ||
| const visibleLt: PointTuple = [ | ||
| -DEFAULT_VISIBLE_SPACE, | ||
| -DEFAULT_VISIBLE_SPACE, | ||
| ] | ||
| const visibleRb: PointTuple = [ | ||
| this.width + DEFAULT_VISIBLE_SPACE, | ||
| this.height + DEFAULT_VISIBLE_SPACE, | ||
| ] | ||
|
|
||
| for (let i = 0; i < nodesSorted.length; i++) { | ||
| const item = nodesSorted[i] | ||
| if ( | ||
| item.visible && | ||
| (!this.partial || | ||
| item.isSelected || | ||
| this.isElementInArea(item, visibleLt, visibleRb, false, false)) | ||
| ) { | ||
| visibleNodes.push(item) | ||
| } | ||
| } | ||
| for (let i = 0; i < edgesSorted.length; i++) { | ||
| const item = edgesSorted[i] | ||
| if ( | ||
| item.visible && | ||
| (!this.partial || | ||
| item.isSelected || | ||
| this.isElementInArea(item, visibleLt, visibleRb, false, false)) | ||
| ) { | ||
| visibleEdges.push(item) | ||
| } | ||
| } | ||
|
|
||
| return [...visibleNodes, ...visibleEdges] | ||
|
Comment on lines
+254
to
+291
|
||
| } | ||
|
|
||
| const elements = [...this.nodes, ...this.edges].sort( | ||
| (a, b) => a.zIndex - b.zIndex, | ||
| ) | ||
|
|
@@ -772,7 +814,10 @@ export class GraphModel { | |
| element.setZIndex(ELEMENT_MAX_Z_INDEX) | ||
| this.topElement = element | ||
| } | ||
| if (this.overlapMode === OverlapMode.INCREASE) { | ||
| if ( | ||
| this.overlapMode === OverlapMode.INCREASE || | ||
| this.overlapMode === OverlapMode.EDGE_TOP | ||
| ) { | ||
| this.setElementZIndex(id, 'top') | ||
| } | ||
| } | ||
|
|
@@ -1584,7 +1629,7 @@ export class GraphModel { | |
| } | ||
|
|
||
| /** | ||
| * 获取图形区域虚拟矩型的尺寸和中心坐标 | ||
| * 获取图形区域虚拟矩形的尺寸和中心坐标 | ||
| * @returns | ||
| */ | ||
| getVirtualRectSize(): GraphModel.VirtualRectProps { | ||
|
|
@@ -1611,7 +1656,7 @@ export class GraphModel { | |
| const virtualRectWidth = maxX - minX || 0 | ||
| const virtualRectHeight = maxY - minY || 0 | ||
|
|
||
| // 获取虚拟矩型的中心坐标 | ||
| // 获取虚拟矩形的中心坐标 | ||
| const virtualRectCenterPositionX = minX + virtualRectWidth / 2 | ||
| const virtualRectCenterPositionY = minY + virtualRectHeight / 2 | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary type casting and null check. The
edgesarray fromgetGraphData()returnsEdgeData[]which always has anidproperty. Remove the type cast and condition:lf.openEdgeAnimation(edge.id)