Skip to content

Commit e12a8dc

Browse files
committed
feat: 暂存「开发 动态组节点功能 代码」
1 parent 36e2c9a commit e12a8dc

File tree

25 files changed

+853
-24
lines changed

25 files changed

+853
-24
lines changed
Loading
Loading
Loading
Loading
Loading

examples/engine-browser-examples/src/main.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import ReactDOM from 'react-dom/client'
33
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
44

55
import Root from './routes/root'
6+
import Home from './pages/Home'
67
import ErrorPage from './pages/ErrorPage'
78

89
// 页面组件
910
import Graph from './pages/graph'
1011
import Bpmn from './pages/extension/bpmn'
12+
import DynamicGroup from './pages/extension/dynamic-group'
1113

1214
import GetStarted from './pages/engine/GetStarted'
1315
import Recorder from './pages/engine/Recorder'
@@ -20,6 +22,10 @@ const router = createBrowserRouter([
2022
element: <Root />,
2123
errorElement: <ErrorPage />,
2224
children: [
25+
{
26+
path: '/',
27+
element: <Home />,
28+
},
2329
{
2430
path: '/graph',
2531
children: [
@@ -36,6 +42,10 @@ const router = createBrowserRouter([
3642
path: '/extension/bpmn',
3743
element: <Bpmn />,
3844
},
45+
{
46+
path: '/extension/dynamic-group',
47+
element: <DynamicGroup />,
48+
},
3949
],
4050
},
4151
{
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useRouteError } from 'react-router-dom'
2+
3+
export interface IErrorProps {
4+
statusText?: string | number
5+
message?: string
6+
}
7+
8+
export default function ErrorPage() {
9+
const error = useRouteError()
10+
console.log('page error ===>>>', error)
11+
12+
return (
13+
<div id="error-page">
14+
<h1>Wire Your Ideas with LogicFlow!</h1>
15+
<p>低成本实现,让逻辑管理更简单、更高效</p>
16+
</div>
17+
)
18+
}

examples/engine-browser-examples/src/pages/extension/bpmn/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export default function BPMNExtension() {
181181
const { control, miniMap } = lf.extension
182182

183183
;(control as Control).addItem({
184+
key: 'mini-map',
184185
iconClass: 'custom-minimap',
185186
title: '',
186187
text: '导航',
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.viewport {
2+
position: relative;
3+
height: 70vh;
4+
overflow: hidden;
5+
}
6+
7+
.lf-dnd-shape {
8+
background-size: contain;
9+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import LogicFlow from '@logicflow/core'
2+
import {
3+
Control,
4+
DndPanel,
5+
ShapeItem,
6+
Group,
7+
SelectionSelect,
8+
} from '@logicflow/extension'
9+
10+
import { Button, Card, Divider, Flex } from 'antd'
11+
import { useEffect, useRef } from 'react'
12+
import { customGroup, subProcess } from './nodes'
13+
import GraphConfigData = LogicFlow.GraphConfigData
14+
15+
import '@logicflow/core/es/index.css'
16+
import '@logicflow/extension/es/index.css'
17+
import './index.less'
18+
import { getImageUrl } from '@/utls.ts'
19+
20+
const config: Partial<LogicFlow.Options> = {
21+
grid: true,
22+
multipleSelectKey: 'alt',
23+
autoExpand: false,
24+
keyboard: {
25+
enabled: true,
26+
},
27+
plugins: [Group, Control, DndPanel, SelectionSelect],
28+
}
29+
30+
const customDndConfig: ShapeItem[] = [
31+
{
32+
type: 'custom-group',
33+
label: '自定义分组',
34+
text: 'CustomGroup',
35+
icon: getImageUrl('/group/group.png'),
36+
},
37+
{
38+
type: 'circle',
39+
label: '圆形',
40+
text: 'Circle',
41+
icon: getImageUrl('/group/circle.png'),
42+
},
43+
{
44+
type: 'rect',
45+
label: '矩形',
46+
text: 'Rect',
47+
icon: getImageUrl('/group/rect.png'),
48+
},
49+
{
50+
type: 'sub-process',
51+
label: '子流程-展开',
52+
text: 'SubProcess',
53+
icon: getImageUrl('/group/subprocess-expanded.png'),
54+
},
55+
{
56+
type: 'sub-process',
57+
label: '子流程-收起',
58+
text: 'SubProcess',
59+
icon: getImageUrl('/group/subprocess-collapsed.png'),
60+
},
61+
]
62+
63+
const getDndPanelConfig = (lf: LogicFlow): ShapeItem[] => [
64+
{
65+
label: '选区',
66+
icon: getImageUrl('/bpmn/select.png'),
67+
callback: () => {
68+
lf.openSelectionSelect()
69+
lf.once('selection:selected', () => {
70+
lf.closeSelectionSelect()
71+
})
72+
},
73+
},
74+
...customDndConfig,
75+
]
76+
77+
export default function BPMNExtension() {
78+
const lfRef = useRef<LogicFlow>()
79+
const containerRef = useRef<HTMLDivElement>(null)
80+
81+
useEffect(() => {
82+
if (!lfRef.current) {
83+
const lf = new LogicFlow({
84+
...config,
85+
container: containerRef.current as HTMLElement,
86+
})
87+
88+
const dndPanelConfig = getDndPanelConfig(lf)
89+
lf.setPatternItems(dndPanelConfig)
90+
91+
lf.register(customGroup)
92+
lf.register(subProcess)
93+
94+
// 获取渲染数据
95+
const graphData: GraphConfigData = {
96+
nodes: [
97+
// {
98+
// type: "custom-group",
99+
// x: 400,
100+
// y: 400,
101+
// text: 'custom-group1',
102+
// children: ["circle_1"]
103+
// },
104+
// {
105+
// id: "circle_1",
106+
// type: "circle",
107+
// x: 400,
108+
// y: 400
109+
// },
110+
// {
111+
// id: "rect_1",
112+
// type: "rect",
113+
// x: 200,
114+
// y: 100
115+
// },
116+
// {
117+
// id: "circle_2",
118+
// type: "circle",
119+
// x: 800,
120+
// y: 140
121+
// },
122+
{
123+
id: 'group_1',
124+
type: 'sub-process',
125+
x: 300,
126+
y: 120,
127+
// children: ["rect_3"],
128+
text: 'sub-process-1',
129+
properties: {
130+
isFolded: true,
131+
},
132+
},
133+
// {
134+
// id: "group_2",
135+
// type: "sub-process",
136+
// x: 800,
137+
// y: 120,
138+
// children: ["circle_4"],
139+
// text: 'sub-process-2',
140+
// properties: {
141+
// isFolded: true
142+
// }
143+
// }
144+
],
145+
edges: [],
146+
}
147+
lf.render(graphData)
148+
149+
lfRef.current = lf
150+
}
151+
}, [])
152+
153+
const getGraphData = () => {}
154+
155+
const rerender = () => {}
156+
157+
return (
158+
<Card title="LogicFlow Extension - DndPanel" className="control-container">
159+
<Flex wrap="wrap" gap="small">
160+
<Button type="primary" key="getData" onClick={getGraphData}>
161+
获取数据
162+
</Button>
163+
<Button type="primary" key="rerender" onClick={rerender}>
164+
重新渲染
165+
</Button>
166+
</Flex>
167+
<Divider />
168+
<div ref={containerRef} id="graph" className="viewport"></div>
169+
</Card>
170+
)
171+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import LogicFlow from '@logicflow/core'
2+
import { GroupNode, GroupNodeModel } from '@logicflow/extension'
3+
4+
import NodeConfig = LogicFlow.NodeConfig
5+
import TextConfig = LogicFlow.TextConfig
6+
7+
export class CustomGroup extends GroupNode {}
8+
9+
export class CustomGroupModel extends GroupNodeModel {
10+
foldedText?: TextConfig
11+
12+
initNodeData(data: NodeConfig) {
13+
super.initNodeData(data)
14+
this.isRestrict = true
15+
this.resizable = true
16+
this.width = 480
17+
this.height = 280
18+
}
19+
20+
getNodeStyle() {
21+
const style = super.getNodeStyle()
22+
style.stroke = '#AEAFAE'
23+
style.strokeWidth = 1
24+
return style
25+
}
26+
27+
foldGroup(folded: boolean) {
28+
super.foldGroup(folded)
29+
// this.isFolded = folded
30+
31+
if (folded) {
32+
if (this.foldedText) {
33+
this.text = { ...this.foldedText }
34+
}
35+
if (!this.text.value) {
36+
this.text.value = '已折叠分组'
37+
}
38+
this.text.x = this.x + 10
39+
this.text.y = this.y
40+
} else {
41+
this.foldedText = { ...this.text }
42+
this.text.value = ''
43+
}
44+
}
45+
46+
// isAllowAppendIn(nodeData) {
47+
// if (nodeData.type === 'rect') {
48+
// return false
49+
// }
50+
// return true
51+
// }
52+
}
53+
54+
export const customGroup = {
55+
type: 'custom-group',
56+
view: CustomGroup,
57+
model: CustomGroupModel,
58+
}
59+
60+
export default customGroup
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './custom-group'
2+
export * from './sub-process'
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import LogicFlow from '@logicflow/core'
2+
import { GroupNode, GroupNodeModel } from '@logicflow/extension'
3+
4+
import TextConfig = LogicFlow.TextConfig
5+
import NodeData = LogicFlow.NodeData
6+
7+
export class SubProcess extends GroupNode {}
8+
9+
export class SubProcessModel extends GroupNodeModel {
10+
foldedText?: TextConfig
11+
setAttributes() {
12+
// const size = 80
13+
const circleOnlyAsTarget = {
14+
message: '正方形节点下一个节点只能是圆形节点',
15+
validate: () => {
16+
return false
17+
},
18+
}
19+
this.targetRules.push(circleOnlyAsTarget)
20+
}
21+
22+
initNodeData(data: NodeData) {
23+
super.initNodeData(data)
24+
this.foldable = true
25+
this.resizable = true
26+
this.width = 400
27+
this.height = 200
28+
}
29+
30+
getNodeStyle() {
31+
const style = super.getNodeStyle()
32+
style.stroke = '#989891'
33+
style.strokeWidth = 1
34+
style.strokeDasharray = '3 3'
35+
if (this.isSelected) {
36+
style.stroke = 'rgb(124, 15, 255)'
37+
}
38+
if (this.isFolded) {
39+
style.fill = '#47C769'
40+
}
41+
return style
42+
}
43+
44+
foldGroup(folded: boolean) {
45+
super.foldGroup(folded)
46+
if (folded) {
47+
if (this.foldedText) {
48+
this.text = { ...this.foldedText }
49+
}
50+
if (!this.text.value) {
51+
this.text.value = '已折叠分组已折叠分组已折叠分组'
52+
}
53+
this.text.x = this.x + 10
54+
this.text.y = this.y
55+
} else {
56+
this.foldedText = { ...this.text }
57+
this.text.value = ''
58+
}
59+
}
60+
61+
// isAllowAppendIn(nodeData) {
62+
// return false
63+
// }
64+
}
65+
66+
export const subProcess = {
67+
type: 'sub-process',
68+
view: SubProcess,
69+
model: SubProcessModel,
70+
}
71+
72+
export default subProcess

examples/engine-browser-examples/src/routes/root.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ export default function Root() {
2323
<ul>
2424
<div className="nav-title">LogicFlow</div>
2525
<li>
26-
<a href={`/graph/get-started`}>Graph</a>
26+
<a href={`/graph/get-started`}>Overview</a>
2727
</li>
2828
<div className="nav-title">Extension</div>
2929
<li>
3030
<a href={`/extension/bpmn`}>BPMN</a>
31+
<a href={`/extension/dynamic-group`}>Dynamic Group</a>
3132
</li>
3233
<div className="nav-title">Engine</div>
3334
<li>

0 commit comments

Comments
 (0)