Skip to content

Commit 4802f1e

Browse files
committed
fix: 修复 GroupNode 中 getNodeStyle 解构后调用,BaseNodeModel 中 getNodeStyle 方法 this 为空的问题
- 确认解构后赋值和直接 this.props.model.getNodeStyle() 方法调用的区别 -> this 指向的问题 - LogicFlow Examples 中新增 Group 插件
1 parent 2fd2e0d commit 4802f1e

File tree

17 files changed

+342
-21
lines changed

17 files changed

+342
-21
lines changed

examples/feature-examples/.umirc.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ export default defineConfig({
8282
name: 'BPMN 插件',
8383
component: './extensions/bpmn',
8484
},
85+
{
86+
path: '/extension/group',
87+
name: 'Group 插件',
88+
component: './extensions/group',
89+
},
8590
],
8691
},
8792
],
Loading
Loading
314 Bytes
Loading
Loading
Loading
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.viewport {
2+
position: relative;
3+
height: 70vh;
4+
overflow: hidden;
5+
}
6+
7+
:global {
8+
.lf-dnd-shape {
9+
background-size: contain;
10+
}
11+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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 styles from './index.less'
18+
19+
const config: Partial<LogicFlow.Options> = {
20+
grid: true,
21+
multipleSelectKey: 'alt',
22+
autoExpand: false,
23+
keyboard: {
24+
enabled: true,
25+
},
26+
plugins: [Group, Control, DndPanel, SelectionSelect],
27+
}
28+
29+
const customDndConfig: ShapeItem[] = [
30+
{
31+
type: 'custom-group',
32+
label: '自定义分组',
33+
text: 'CustomGroup',
34+
icon: require('@/assets/group/group.png'),
35+
},
36+
{
37+
type: 'circle',
38+
label: '圆形',
39+
text: 'Circle',
40+
icon: require('@/assets/group/circle.png'),
41+
},
42+
{
43+
type: 'rect',
44+
label: '矩形',
45+
text: 'Rect',
46+
icon: require('@/assets/group/rect.png'),
47+
},
48+
{
49+
type: 'sub-process',
50+
label: '子流程-展开',
51+
text: 'SubProcess',
52+
icon: require('@/assets/group/subprocess-expanded.png'),
53+
},
54+
{
55+
type: 'sub-process',
56+
label: '子流程-收起',
57+
text: 'SubProcess',
58+
icon: require('@/assets/group/subprocess-collapsed.png'),
59+
},
60+
]
61+
62+
const getDndPanelConfig = (lf: LogicFlow): ShapeItem[] => [
63+
{
64+
label: '选区',
65+
icon: require('@/assets/bpmn/select.png'),
66+
callback: () => {
67+
lf.openSelectionSelect()
68+
lf.once('selection:selected', () => {
69+
lf.closeSelectionSelect()
70+
})
71+
},
72+
},
73+
...customDndConfig,
74+
]
75+
76+
export default function BPMNExtension() {
77+
const lfRef = useRef<LogicFlow>()
78+
const containerRef = useRef<HTMLDivElement>(null)
79+
80+
useEffect(() => {
81+
if (!lfRef.current) {
82+
const lf = new LogicFlow({
83+
...config,
84+
container: containerRef.current as HTMLElement,
85+
})
86+
87+
const dndPanelConfig = getDndPanelConfig(lf)
88+
lf.setPatternItems(dndPanelConfig)
89+
90+
lf.register(customGroup)
91+
lf.register(subProcess)
92+
93+
// 获取渲染数据
94+
const graphData: GraphConfigData = {
95+
nodes: [
96+
// {
97+
// type: "custom-group",
98+
// x: 400,
99+
// y: 400,
100+
// text: 'custom-group1',
101+
// children: ["circle_1"]
102+
// },
103+
// {
104+
// id: "circle_1",
105+
// type: "circle",
106+
// x: 400,
107+
// y: 400
108+
// },
109+
// {
110+
// id: "rect_1",
111+
// type: "rect",
112+
// x: 200,
113+
// y: 100
114+
// },
115+
// {
116+
// id: "circle_2",
117+
// type: "circle",
118+
// x: 800,
119+
// y: 140
120+
// },
121+
{
122+
id: 'group_1',
123+
type: 'sub-process',
124+
x: 300,
125+
y: 120,
126+
// children: ["rect_3"],
127+
text: 'sub-process-1',
128+
properties: {
129+
isFolded: true,
130+
},
131+
},
132+
// {
133+
// id: "group_2",
134+
// type: "sub-process",
135+
// x: 800,
136+
// y: 120,
137+
// children: ["circle_4"],
138+
// text: 'sub-process-2',
139+
// properties: {
140+
// isFolded: true
141+
// }
142+
// }
143+
],
144+
edges: [],
145+
}
146+
lf.render(graphData)
147+
148+
lfRef.current = lf
149+
}
150+
}, [])
151+
152+
const getGraphData = () => {}
153+
154+
const rerender = () => {}
155+
156+
return (
157+
<Card title="LogicFlow Extension - DndPanel" className="control-container">
158+
<Flex wrap="wrap" gap="small">
159+
<Button type="primary" key="getData" onClick={getGraphData}>
160+
获取数据
161+
</Button>
162+
<Button type="primary" key="rerender" onClick={rerender}>
163+
重新渲染
164+
</Button>
165+
</Flex>
166+
<Divider />
167+
<div ref={containerRef} id="graph" className={styles.viewport}></div>
168+
</Card>
169+
)
170+
}
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/feature-examples/src/pages/graph/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { map } from 'lodash-es'
1+
import { forEach, map } from 'lodash-es'
22
import LogicFlow, { ElementState, LogicFlowUtil } from '@logicflow/core'
33
import '@logicflow/core/es/index.css'
44

@@ -274,15 +274,15 @@ export default function BasicNode() {
274274
const handleTurnAnimationOn = () => {
275275
if (lfRef.current) {
276276
const { edges } = lfRef.current.getGraphData() as GraphConfigData
277-
edges.forEach((edge) => {
277+
forEach(edges, (edge) => {
278278
lfRef.current?.openEdgeAnimation(edge.id)
279279
})
280280
}
281281
}
282282
const handleTurnAnimationOff = () => {
283283
if (lfRef.current) {
284284
const { edges } = lfRef.current.getGraphData() as GraphConfigData
285-
edges.forEach((edge) => {
285+
forEach(edges, (edge) => {
286286
lfRef.current?.closeEdgeAnimation(edge.id)
287287
})
288288
}

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "LogicFlow, help you quickly create flowcharts",
55
"main": "dist/index.js",
66
"module": "es/index.js",
7-
"types": "lib/index.d.ts",
7+
"types": "es/index.d.ts",
88
"scripts": {
99
"clean:turbo": "rss",
1010
"clean:build": "rss",

packages/core/src/model/node/BaseNodeModel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020

2121
import AnchorConfig = Model.AnchorConfig
2222
import GraphElements = LogicFlow.GraphElements
23+
import TextConfig = LogicFlow.TextConfig
2324

2425
export interface IBaseNodeModel extends Model.BaseModel {
2526
/**
@@ -44,7 +45,7 @@ export class BaseNodeModel implements IBaseNodeModel {
4445
@observable readonly type = ''
4546
@observable x = 0
4647
@observable y = 0
47-
@observable text = {
48+
@observable text: TextConfig = {
4849
value: '',
4950
x: 0,
5051
y: 0,

packages/core/src/view/node/BaseNode.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ export abstract class BaseNode extends Component<IProps, IState> {
141141
}
142142
return (
143143
<BaseText
144-
editable={editConfigModel.nodeTextEdit && model.text.editable}
144+
editable={
145+
editConfigModel.nodeTextEdit && (model.text.editable ?? true)
146+
}
145147
model={model}
146148
graphModel={graphModel}
147149
draggable={draggable}

0 commit comments

Comments
 (0)