Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
283 changes: 215 additions & 68 deletions examples/feature-examples/src/pages/graph/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
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'
import { useEffect, useRef } from 'react'
import { Button, Card, Divider, Flex, Drawer } from 'antd'
import { useEffect, useRef, useState } from 'react'
import { combine, square, star, uml, user } from './nodes'
import { animation, connection } from './edges'

Expand All @@ -12,6 +16,7 @@ import customRect from '@/components/nodes/custom-rect'
import customEllipse from '@/components/nodes/custom-ellipse'
import customDiamond from '@/components/nodes/custom-diamond'
import customPolygon from '@/components/nodes/custom-polygon'
import centerAnchorRect from './nodes/centerAnchorRect'

import GraphData = LogicFlow.GraphData
import styles from './index.less'
Expand Down Expand Up @@ -98,6 +103,7 @@ const data = {
type: 'rect',
x: 600,
y: 200,

properties: {
width: 80,
height: 120,
Expand All @@ -111,9 +117,17 @@ const data = {
x: 90,
y: 94,
},
{
id: 'custom-node-3',
text: 'node-3',
type: 'centerAnchorRect',
x: 360,
y: 280,
},
],
edges: [
{
id: 'bezier-1',
type: 'bezier',
sourceNodeId: 'custom-node-1',
targetNodeId: 'custom-node-2',
Expand All @@ -123,6 +137,17 @@ const data = {
},
},
},
{
id: 'bezier-2',
type: 'bezier',
sourceNodeId: 'custom-node-2',
targetNodeId: 'custom-node-3',
properties: {
style: {
stroke: 'blue',
},
},
},
],
}

Expand Down Expand Up @@ -169,6 +194,11 @@ const data = {
export default function BasicNode() {
const lfRef = useRef<LogicFlow>()
const containerRef = useRef<HTMLDivElement>(null)
const [open, setOpen] = useState(false)

const onClose = () => {
setOpen(false)
}

const registerElements = (lf: LogicFlow) => {
const elements: LogicFlow.RegisterConfig[] = [
Expand All @@ -186,6 +216,7 @@ export default function BasicNode() {
customEllipse,
customDiamond,
customPolygon,
centerAnchorRect,
]

map(elements, (customElement) => {
Expand All @@ -205,6 +236,10 @@ export default function BasicNode() {
lf.on('edge:click', (data) => {
console.log('edge:click', data)
})
lf.on('node:click', (data) => {
console.log('node:click', data)
setOpen(true)
})
}

useEffect(() => {
Expand Down Expand Up @@ -253,9 +288,9 @@ export default function BasicNode() {
},
partial: true,
background: {
// color: '#FFFFFF',
backgroundImage:
"url('https://cdn.jsdelivr.net/gh/Logic-Flow/static@latest/core/rect.png')",
color: '#FFFFFF',
// backgroundImage:
// "url('https://cdn.jsdelivr.net/gh/Logic-Flow/static@latest/core/rect.png')",
},
// grid: true,
grid: {
Expand Down Expand Up @@ -363,92 +398,194 @@ 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.setOverlapMode(mode)
const order = lf.graphModel.sortElements.map((m) => m.id)
console.log('[overlapMode]', mode, '排序结果:', order)
}
const setOverlapModeStatic = () => setOverlapMode(OverlapMode.STATIC)
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)
})
}

const handleDragItem = (cfg: OnDragNodeConfig) => {
const lf = lfRef.current
if (!lf) return
lf.dnd?.startDrag(cfg)
}

const handleDragItem = (node: OnDragNodeConfig) => {
lfRef?.current?.dnd.startDrag(node)
const handleRefreshGraph = () => {
const lf = lfRef.current
if (!lf) return
const raw = lf.getGraphRawData?.()
console.log('当前原始数据:', raw || lf.getGraphData())
}

const handleChangeColor = () => {
const lf = lfRef.current
if (!lf) return
const { edges } = lf.getSelectElements()
edges.forEach(({ id }) => {
lf.setProperties(id, { style: { stroke: '#ff4d4f' } })
})
}

const changeNodeBorderColor = () => {
const lf = lfRef.current
if (lf) {
const { nodes } = lf.getSelectElements()
nodes.forEach(({ id, properties }) => {
console.log('properties', properties)
lf.setProperties(id, {
style: {
stroke: 'pink',
},
})
})
}
if (!lf) return
const { nodes } = lf.getSelectElements()
nodes.forEach(({ id }) => {
lf.setProperties(id, { style: { stroke: '#ff4d4f' } })
})
}

return (
<Card title="Graph">
<Flex wrap="wrap" gap="small">
{/* overlapMode 测试控制 */}
<Button
key="overlap-static"
type="primary"
onClick={setOverlapModeStatic}
>
静态堆叠模式
</Button>
<Button
key="overlap-default"
type="primary"
onClick={setOverlapModeDefault}
>
默认堆叠模式
</Button>
<Button
key="overlap-increase"
type="primary"
onClick={setOverlapModeIncrease}
>
递增堆叠模式
</Button>
<Button
key="overlap-edge-top"
type="primary"
onClick={setOverlapModeEdgeTop}
>
边置顶模式
</Button>
<Button
key="print-sort"
type="primary"
onClick={() => {
const lf = lfRef.current
if (!lf) return
const order = lf.graphModel.sortElements.map((m) =>
m.modelType === ModelType.EDGE ? 'edge' : 'node',
)
console.log('当前渲染排序:', order)
}}
>
打印渲染排序
</Button>
<Button key="add-overlap-node" type="primary" onClick={addOverlapNode}>
添加重叠节点
</Button>
<Button
key="delete-overlap-node"
type="primary"
onClick={deleteOverlapNode}
>
删除重叠节点
</Button>
<Button
key="select-first-edge"
type="primary"
onClick={selectFirstEdge}
>
选中并置顶首条边
</Button>
<Button
key="select-overlap-node"
type="primary"
onClick={selectOverlapNode}
>
选中并置顶重叠节点
</Button>
<Button key="clear-selection" type="primary" onClick={clearSelection}>
取消选中
</Button>
</Flex>
<Divider orientation="left" orientationMargin="5" plain></Divider>
<Flex wrap="wrap" gap="small">
<Button key="arrow1" type="primary" onClick={() => setArrow('half')}>
箭头 1
Expand Down Expand Up @@ -725,6 +862,16 @@ export default function BasicNode() {
</Flex>
<Divider />
<div ref={containerRef} id="graph" className={styles.viewport}></div>
<Drawer
title="Basic Drawer"
closable={{ 'aria-label': 'Close Button' }}
onClose={onClose}
open={open}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</Card>
)
}
Loading
Loading