@logicflow/core 2.2.1 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/dist/docs/api/logicflow-constructor/index.en.md +106 -0
- package/dist/docs/api/logicflow-constructor/index.zh.md +106 -0
- package/dist/docs/api/logicflow-constructor/use.en.md +61 -0
- package/dist/docs/api/logicflow-constructor/use.zh.md +61 -0
- package/dist/docs/api/logicflow-instance/canvas.en.md +197 -0
- package/dist/docs/api/logicflow-instance/canvas.zh.md +199 -0
- package/dist/docs/api/logicflow-instance/edge.en.md +273 -0
- package/dist/docs/api/logicflow-instance/edge.zh.md +273 -0
- package/dist/docs/api/logicflow-instance/edit-config.en.md +59 -0
- package/dist/docs/api/logicflow-instance/edit-config.zh.md +59 -0
- package/dist/docs/api/logicflow-instance/element.en.md +375 -0
- package/dist/docs/api/logicflow-instance/element.zh.md +379 -0
- package/dist/docs/api/logicflow-instance/event.en.md +326 -0
- package/dist/docs/api/logicflow-instance/event.zh.md +406 -0
- package/dist/docs/api/logicflow-instance/history.en.md +38 -0
- package/dist/docs/api/logicflow-instance/history.zh.md +38 -0
- package/dist/docs/api/logicflow-instance/index.en.md +41 -0
- package/dist/docs/api/logicflow-instance/index.zh.md +41 -0
- package/dist/docs/api/logicflow-instance/node.en.md +308 -0
- package/dist/docs/api/logicflow-instance/node.zh.md +308 -0
- package/dist/docs/api/logicflow-instance/register.en.md +76 -0
- package/dist/docs/api/logicflow-instance/register.zh.md +76 -0
- package/dist/docs/api/logicflow-instance/render-and-data.en.md +179 -0
- package/dist/docs/api/logicflow-instance/render-and-data.zh.md +181 -0
- package/dist/docs/api/logicflow-instance/text.en.md +60 -0
- package/dist/docs/api/logicflow-instance/text.zh.md +60 -0
- package/dist/docs/api/logicflow-instance/theme.en.md +179 -0
- package/dist/docs/api/logicflow-instance/theme.zh.md +179 -0
- package/dist/docs/api/runtime-model/edgeModel.en.md +29 -0
- package/dist/docs/api/runtime-model/edgeModel.zh.md +325 -0
- package/dist/docs/api/runtime-model/graphModel.en.md +275 -0
- package/dist/docs/api/runtime-model/graphModel.zh.md +1153 -0
- package/dist/docs/api/runtime-model/nodeModel.en.md +37 -0
- package/dist/docs/api/runtime-model/nodeModel.zh.md +644 -0
- package/dist/docs/api/type/MainTypes.en.md +598 -0
- package/dist/docs/api/type/MainTypes.zh.md +867 -0
- package/dist/docs/api/type/Theme.en.md +187 -0
- package/dist/docs/api/type/Theme.zh.md +187 -0
- package/dist/docs/api/type/canvas-types.en.md +25 -0
- package/dist/docs/api/type/canvas-types.zh.md +25 -0
- package/dist/docs/api/type/index.en.md +96 -0
- package/dist/docs/api/type/index.zh.md +99 -0
- package/dist/docs/api/type/node-types.en.md +21 -0
- package/dist/docs/api/type/node-types.zh.md +21 -0
- package/dist/docs/api/type/plugin-types.en.md +24 -0
- package/dist/docs/api/type/plugin-types.zh.md +24 -0
- package/dist/docs/index.md +11 -0
- package/dist/docs/tutorial/about.en.md +38 -0
- package/dist/docs/tutorial/about.zh.md +65 -0
- package/dist/docs/tutorial/advanced/dnd.en.md +62 -0
- package/dist/docs/tutorial/advanced/dnd.zh.md +52 -0
- package/dist/docs/tutorial/advanced/edge.en.md +64 -0
- package/dist/docs/tutorial/advanced/edge.zh.md +66 -0
- package/dist/docs/tutorial/advanced/keyboard.en.md +70 -0
- package/dist/docs/tutorial/advanced/keyboard.zh.md +67 -0
- package/dist/docs/tutorial/advanced/node.en.md +338 -0
- package/dist/docs/tutorial/advanced/node.zh.md +338 -0
- package/dist/docs/tutorial/advanced/react.en.md +106 -0
- package/dist/docs/tutorial/advanced/react.zh.md +114 -0
- package/dist/docs/tutorial/advanced/silent-mode.en.md +75 -0
- package/dist/docs/tutorial/advanced/silent-mode.zh.md +71 -0
- package/dist/docs/tutorial/advanced/snapline.en.md +54 -0
- package/dist/docs/tutorial/advanced/vue.en.md +249 -0
- package/dist/docs/tutorial/advanced/vue.zh.md +248 -0
- package/dist/docs/tutorial/ai.en.md +64 -0
- package/dist/docs/tutorial/ai.zh.md +64 -0
- package/dist/docs/tutorial/basic/background.en.md +50 -0
- package/dist/docs/tutorial/basic/canvas.en.md +164 -0
- package/dist/docs/tutorial/basic/canvas.zh.md +183 -0
- package/dist/docs/tutorial/basic/class.en.md +106 -0
- package/dist/docs/tutorial/basic/class.zh.md +103 -0
- package/dist/docs/tutorial/basic/edge.en.md +151 -0
- package/dist/docs/tutorial/basic/edge.zh.md +152 -0
- package/dist/docs/tutorial/basic/event.en.md +70 -0
- package/dist/docs/tutorial/basic/event.zh.md +66 -0
- package/dist/docs/tutorial/basic/grid.en.md +77 -0
- package/dist/docs/tutorial/basic/node.en.md +358 -0
- package/dist/docs/tutorial/basic/node.zh.md +318 -0
- package/dist/docs/tutorial/basic/theme.en.md +154 -0
- package/dist/docs/tutorial/basic/theme.zh.md +157 -0
- package/dist/docs/tutorial/extension/adapter.en.md +446 -0
- package/dist/docs/tutorial/extension/adapter.zh.md +429 -0
- package/dist/docs/tutorial/extension/bpmn-element.en.md +1427 -0
- package/dist/docs/tutorial/extension/bpmn-element.zh.md +1472 -0
- package/dist/docs/tutorial/extension/control.en.md +117 -0
- package/dist/docs/tutorial/extension/control.zh.md +118 -0
- package/dist/docs/tutorial/extension/curved-edge.en.md +46 -0
- package/dist/docs/tutorial/extension/curved-edge.zh.md +46 -0
- package/dist/docs/tutorial/extension/custom.en.md +142 -0
- package/dist/docs/tutorial/extension/custom.zh.md +138 -0
- package/dist/docs/tutorial/extension/dnd-panel.en.md +109 -0
- package/dist/docs/tutorial/extension/dnd-panel.zh.md +109 -0
- package/dist/docs/tutorial/extension/dynamic-group.en.md +606 -0
- package/dist/docs/tutorial/extension/dynamic-group.zh.md +606 -0
- package/dist/docs/tutorial/extension/group.en.md +217 -0
- package/dist/docs/tutorial/extension/group.zh.md +209 -0
- package/dist/docs/tutorial/extension/highlight.en.md +50 -0
- package/dist/docs/tutorial/extension/highlight.zh.md +50 -0
- package/dist/docs/tutorial/extension/insert-node-in-polyline.en.md +52 -0
- package/dist/docs/tutorial/extension/insert-node-in-polyline.zh.md +47 -0
- package/dist/docs/tutorial/extension/intro.en.md +72 -0
- package/dist/docs/tutorial/extension/intro.zh.md +95 -0
- package/dist/docs/tutorial/extension/label.en.md +136 -0
- package/dist/docs/tutorial/extension/label.zh.md +135 -0
- package/dist/docs/tutorial/extension/layout.en.md +156 -0
- package/dist/docs/tutorial/extension/layout.zh.md +156 -0
- package/dist/docs/tutorial/extension/menu.en.md +319 -0
- package/dist/docs/tutorial/extension/menu.zh.md +377 -0
- package/dist/docs/tutorial/extension/minimap.en.md +164 -0
- package/dist/docs/tutorial/extension/minimap.zh.md +180 -0
- package/dist/docs/tutorial/extension/node-resize.en.md +199 -0
- package/dist/docs/tutorial/extension/node-resize.zh.md +221 -0
- package/dist/docs/tutorial/extension/pool.en.md +227 -0
- package/dist/docs/tutorial/extension/pool.zh.md +227 -0
- package/dist/docs/tutorial/extension/proximity-connect.en.md +104 -0
- package/dist/docs/tutorial/extension/proximity-connect.zh.md +107 -0
- package/dist/docs/tutorial/extension/selection.en.md +166 -0
- package/dist/docs/tutorial/extension/selection.zh.md +150 -0
- package/dist/docs/tutorial/extension/snapshot.en.md +276 -0
- package/dist/docs/tutorial/extension/snapshot.zh.md +276 -0
- package/dist/docs/tutorial/get-started.en.md +501 -0
- package/dist/docs/tutorial/get-started.zh.md +139 -0
- package/dist/docs/tutorial/update.en.md +213 -0
- package/dist/docs/tutorial/update.zh.md +212 -0
- package/package.json +5 -3
- package/scripts/postinstall-ai-prompt.js +67 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: 指南
|
|
3
|
+
group:
|
|
4
|
+
title: 插件功能
|
|
5
|
+
order: 3
|
|
6
|
+
title: 节点缩放 (NodeResize)
|
|
7
|
+
order: 16
|
|
8
|
+
toc: content
|
|
9
|
+
tag: 已内置
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 使用
|
|
13
|
+
|
|
14
|
+
LogicFlow 在 extension 包中提供了`RectResize`、`EllipseResize`、`DiamondResize`、`HtmlResize`这 4
|
|
15
|
+
种支持缩放的基础节点, 每个节点都有`view`和`model`这两个属性。节点的缩放也是利用 LogicFlow
|
|
16
|
+
的自定义节点机制,使开发者可以继承这 4 种可以缩放的节点,来实现节点的缩放。
|
|
17
|
+
|
|
18
|
+
以我们需要一个可以缩放的矩形为例,在以前我们不支持节点缩放时,我们自定义节点方式为:
|
|
19
|
+
|
|
20
|
+
```tsx | pure
|
|
21
|
+
// 不可以缩放的节点
|
|
22
|
+
import { RectNode, RectNodeModel } from '@logicflow/core'
|
|
23
|
+
|
|
24
|
+
class CustomNode extends RectNode {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class CustomNodeModel extends RectNodeModel {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
type: 'custom-node',
|
|
32
|
+
model: CustomNodeModel,
|
|
33
|
+
view: CustomNode,
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
如果我们期望自定义的节点可以缩放,那么则改成:
|
|
38
|
+
|
|
39
|
+
```tsx | pure
|
|
40
|
+
// 支持缩放的节点
|
|
41
|
+
import { RectResize } from "@logicflow/extension";
|
|
42
|
+
|
|
43
|
+
class CustomNode extends RectResize.view {
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class CustomNodeModel extends RectResize.model {
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default {
|
|
50
|
+
type: "custom-node",
|
|
51
|
+
model: CustomNodeModel,
|
|
52
|
+
view: CustomNode,
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 设置节点的形状属性
|
|
57
|
+
|
|
58
|
+
LogicFlow 把节点的宽高、半径等属性称之为[形状属性](../../api/runtime-model/nodeModel.zh.md#形状属性),我们可以重写
|
|
59
|
+
model 中的[initNodeData](../../api/runtime-model/nodeModel.zh.md#initnodedata)
|
|
60
|
+
或者[setAttributes](../../api/runtime-model/nodeModel.zh.md#setattributes)
|
|
61
|
+
方法来设置节点的形状属性。但是当节点可以缩放后,我们不能在`setAttributes`
|
|
62
|
+
中设置宽高,只能在`initNodeData`中设置。
|
|
63
|
+
|
|
64
|
+
```tsx | pure
|
|
65
|
+
class ResizableRectModel extends RectResize.model {
|
|
66
|
+
initNodeData(data) {
|
|
67
|
+
super.initNodeData(data);
|
|
68
|
+
this.width = 100;
|
|
69
|
+
this.height = 40;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 自定义节点的 view
|
|
75
|
+
|
|
76
|
+
在自定义节点中提到过,对于样式属性比较复杂的节点,我们可以重写`view`中的`getShape`
|
|
77
|
+
方法来实现自定义节点真实渲染的外观。但是由于自定义节点需要在节点外观上填加用于缩放的调整点,所以对于自定义可缩放节点的
|
|
78
|
+
view,我们需要重写`getResizeShape`, 而不是`getShape`。
|
|
79
|
+
|
|
80
|
+
```tsx | pure
|
|
81
|
+
import { RectResize } from "@logicflow/extension";
|
|
82
|
+
|
|
83
|
+
class ResizableRectModel extends RectResize.model {
|
|
84
|
+
initNodeData(data) {
|
|
85
|
+
super.initNodeData(data);
|
|
86
|
+
this.width = 100;
|
|
87
|
+
this.height = 40;
|
|
88
|
+
this.text.draggable = true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
class ResizableRectView extends RectResize.view {
|
|
93
|
+
/**
|
|
94
|
+
* 此方法替代自定义节点的getShape方法。
|
|
95
|
+
*/
|
|
96
|
+
getResizeShape() {
|
|
97
|
+
const { model } = this.props;
|
|
98
|
+
const { x, y, width, height, radius, properties } = model;
|
|
99
|
+
const style = model.getNodeStyle();
|
|
100
|
+
return h("g", {}, [
|
|
101
|
+
h("rect", {
|
|
102
|
+
...style,
|
|
103
|
+
x: x - width / 2,
|
|
104
|
+
y: y - height / 2,
|
|
105
|
+
rx: radius,
|
|
106
|
+
ry: radius,
|
|
107
|
+
width,
|
|
108
|
+
height,
|
|
109
|
+
}),
|
|
110
|
+
]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default {
|
|
115
|
+
type: "resizable-rect",
|
|
116
|
+
view: ResizableRectView,
|
|
117
|
+
model: ResizableRectModel,
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
:::info{title=提示}
|
|
122
|
+
对于继承`HtmlResize`的节点,自定义`view`请继续使用自定义 HTML 节点的`view`的`setHtml`方法。
|
|
123
|
+
:::
|
|
124
|
+
|
|
125
|
+
## 事件
|
|
126
|
+
|
|
127
|
+
节点缩放后抛出事件`node:resize`,抛出数据包括节点缩放前后的节点位置、节点大小信息, 数据为{preData,
|
|
128
|
+
data}, 详细字段如下。
|
|
129
|
+
|
|
130
|
+
| 名称 | 类型 | 描述 |
|
|
131
|
+
| :-------- | :----- | :----------------------- |
|
|
132
|
+
| id | string | 节点 id |
|
|
133
|
+
| type | string | 节点类型 |
|
|
134
|
+
| modelType | string | 节点图形类型,已内部定义 |
|
|
135
|
+
| x | number | 节点中心 x 轴坐标 |
|
|
136
|
+
| y | number | 节点中心 y 轴坐标 |
|
|
137
|
+
| rx | number | x 轴半径(椭圆、菱形) |
|
|
138
|
+
| ry | number | y 轴半径(椭圆、菱形) |
|
|
139
|
+
| width | number | 节点宽度(矩形) |
|
|
140
|
+
| height | number | 节点高度(矩形) |
|
|
141
|
+
|
|
142
|
+
```tsx | pure
|
|
143
|
+
lf.on("node:resize", ({ preData, data }) => {
|
|
144
|
+
console.log(preData, data);
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 设置放大缩小的最大最小值
|
|
149
|
+
|
|
150
|
+
`v1.1.8`后,节点的放大缩小支持设置最大值和最小值。
|
|
151
|
+
|
|
152
|
+
```tsx | pure
|
|
153
|
+
class ResizableRectModel extends RectResize.model {
|
|
154
|
+
initNodeData(data) {
|
|
155
|
+
super.initNodeData(data);
|
|
156
|
+
this.width = 100;
|
|
157
|
+
this.height = 40;
|
|
158
|
+
this.maxWidth = 400;
|
|
159
|
+
this.maxHeight = 400;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 设置放大缩小的调整默认距离
|
|
165
|
+
|
|
166
|
+
`v1.1.8`后,支持设置节点的`girdSize`属性,用来控制鼠标移动多少距离后开始缩放节点。
|
|
167
|
+
|
|
168
|
+
```tsx | pure
|
|
169
|
+
class ResizableRectModel extends RectResize.model {
|
|
170
|
+
initNodeData(data) {
|
|
171
|
+
super.initNodeData(data);
|
|
172
|
+
this.gridSize = 400;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
:::info{title=关于节点缩放的 gridSize}
|
|
178
|
+
大多数情况下,为了保证节点的`整齐`,便于节点之间的上下左右对齐。`logicflow`
|
|
179
|
+
默认在放大缩小时,只有鼠标移动的距离达到初始化画布传入的`gridSize`
|
|
180
|
+
两倍时才改变节点的大小。但是这样会有一个缺点,那就是调整的时候有卡顿的感觉。可以在不改变初始化`gridSize`
|
|
181
|
+
的情况下,单独设置每个节点的`gridSize`来让放大缩小节点更流畅。
|
|
182
|
+
:::
|
|
183
|
+
|
|
184
|
+
## 设置调整边框样式
|
|
185
|
+
|
|
186
|
+
可放大缩小节点在被选中时,会贴着节点显示一个虚线框(矩形没有)。可以通过重写`getResizeOutlineStyle`
|
|
187
|
+
方法实现自定义其样式。
|
|
188
|
+
|
|
189
|
+
```tsx | pure
|
|
190
|
+
class ResizableRectModel extends RectResize.model {
|
|
191
|
+
getResizeOutlineStyle() {
|
|
192
|
+
return {
|
|
193
|
+
stroke: "#000000",
|
|
194
|
+
strokeWidth: 1,
|
|
195
|
+
strokeDasharray: "3,3",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 设置调整点样式
|
|
202
|
+
|
|
203
|
+
可放大缩小节点在被选中时,会在虚线框的四个角生成调整节点大小的操作点,可以通过重写`getControlPointStyle`
|
|
204
|
+
方法实现自定义其样式。
|
|
205
|
+
|
|
206
|
+
```tsx | pure
|
|
207
|
+
class ResizableRectModel extends RectResize.model {
|
|
208
|
+
getControlPointStyle() {
|
|
209
|
+
return {
|
|
210
|
+
width: 7,
|
|
211
|
+
height: 7,
|
|
212
|
+
fill: "#FFFFFF",
|
|
213
|
+
stroke: "#000000",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
地址: [https://codesandbox.io/s/prod-resonance-ztpvtv](https://codesandbox.io/s/prod-resonance-ztpvtv?file=/step_26_nodeResize/index.js)
|
|
220
|
+
|
|
221
|
+
<a href="https://codesandbox.io/embed/prod-resonance-ztpvtv?fontsize=14&hidenavigation=1&theme=dark&view=preview" target="_blank"> 去 CodeSandbox 查看示例</a>
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: Guide
|
|
3
|
+
group:
|
|
4
|
+
title: Plug-in functionality
|
|
5
|
+
order: 3
|
|
6
|
+
title: Swimlane (Pool)
|
|
7
|
+
order: 14
|
|
8
|
+
toc: content
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
LogicFlow provides a swimlane solution built on the DynamicGroup mechanism. A pool (`pool`) contains multiple lanes (`lane`). Lanes hold business nodes, and the plugin can automatically assign nodes to lanes during drag/drop. It also provides built-in interactions to insert and delete lanes.
|
|
12
|
+
|
|
13
|
+
## Demonstration
|
|
14
|
+
|
|
15
|
+
<code id="react-portal" src="@/src/tutorial/extension/pool"></code>
|
|
16
|
+
|
|
17
|
+
## Using the Plugin
|
|
18
|
+
|
|
19
|
+
```tsx | pure
|
|
20
|
+
import LogicFlow from '@logicflow/core'
|
|
21
|
+
import { PoolElements } from '@logicflow/extension'
|
|
22
|
+
import '@logicflow/core/es/index.css'
|
|
23
|
+
import '@logicflow/extension/es/index.css'
|
|
24
|
+
|
|
25
|
+
const lf = new LogicFlow({
|
|
26
|
+
container: document.querySelector('#container') as HTMLElement,
|
|
27
|
+
plugins: [PoolElements],
|
|
28
|
+
allowResize: true,
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
Create a node with `type: 'pool'`. If no lanes exist when the pool is first rendered, a default lane is created automatically.
|
|
35
|
+
|
|
36
|
+
```ts | pure
|
|
37
|
+
lf.render({
|
|
38
|
+
nodes: [
|
|
39
|
+
{
|
|
40
|
+
id: 'pool_1',
|
|
41
|
+
type: 'pool',
|
|
42
|
+
x: 400,
|
|
43
|
+
y: 260,
|
|
44
|
+
text: 'Pool',
|
|
45
|
+
properties: {
|
|
46
|
+
direction: 'horizontal',
|
|
47
|
+
width: 520,
|
|
48
|
+
height: 360,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
edges: [],
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Data Format
|
|
57
|
+
|
|
58
|
+
Pool/Lane nodes are special nodes. You can use `children` to describe hierarchy. During interactions, the plugin also maintains `properties.parent` for child nodes automatically.
|
|
59
|
+
|
|
60
|
+
### Pool (`pool`)
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
type PoolProperties = {
|
|
64
|
+
direction?: 'horizontal' | 'vertical'
|
|
65
|
+
width?: number
|
|
66
|
+
height?: number
|
|
67
|
+
laneConfig?: Record<string, unknown>
|
|
68
|
+
children?: string[]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Lane (`lane`)
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
type LaneProperties = {
|
|
76
|
+
parent?: string
|
|
77
|
+
width?: number
|
|
78
|
+
height?: number
|
|
79
|
+
isRestrict?: boolean
|
|
80
|
+
autoResize?: boolean
|
|
81
|
+
children?: string[]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Full Example
|
|
86
|
+
|
|
87
|
+
```ts | pure
|
|
88
|
+
lf.render({
|
|
89
|
+
nodes: [
|
|
90
|
+
{
|
|
91
|
+
id: 'pool_1',
|
|
92
|
+
type: 'pool',
|
|
93
|
+
x: 500,
|
|
94
|
+
y: 260,
|
|
95
|
+
text: 'Pool (H)',
|
|
96
|
+
properties: {
|
|
97
|
+
direction: 'horizontal',
|
|
98
|
+
width: 520,
|
|
99
|
+
height: 360,
|
|
100
|
+
children: ['lane_1', 'lane_2'],
|
|
101
|
+
},
|
|
102
|
+
children: ['lane_1', 'lane_2'],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'lane_1',
|
|
106
|
+
type: 'lane',
|
|
107
|
+
x: 540,
|
|
108
|
+
y: 340,
|
|
109
|
+
text: 'Lane 1',
|
|
110
|
+
properties: {
|
|
111
|
+
parent: 'pool_1',
|
|
112
|
+
width: 440,
|
|
113
|
+
height: 180,
|
|
114
|
+
isRestrict: true,
|
|
115
|
+
autoResize: false,
|
|
116
|
+
children: ['rect_1'],
|
|
117
|
+
},
|
|
118
|
+
children: ['rect_1'],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: 'lane_2',
|
|
122
|
+
type: 'lane',
|
|
123
|
+
x: 540,
|
|
124
|
+
y: 160,
|
|
125
|
+
text: 'Lane 2',
|
|
126
|
+
properties: {
|
|
127
|
+
parent: 'pool_1',
|
|
128
|
+
width: 440,
|
|
129
|
+
height: 180,
|
|
130
|
+
children: ['circle_1'],
|
|
131
|
+
},
|
|
132
|
+
children: ['circle_1'],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'rect_1',
|
|
136
|
+
type: 'rect',
|
|
137
|
+
x: 470,
|
|
138
|
+
y: 350,
|
|
139
|
+
text: 'Node A',
|
|
140
|
+
properties: {
|
|
141
|
+
parent: 'lane_1',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: 'circle_1',
|
|
146
|
+
type: 'circle',
|
|
147
|
+
x: 620,
|
|
148
|
+
y: 150,
|
|
149
|
+
text: 'Node B',
|
|
150
|
+
properties: {
|
|
151
|
+
parent: 'lane_2',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
edges: [],
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Interactions
|
|
160
|
+
|
|
161
|
+
### Automatic Lane Assignment
|
|
162
|
+
|
|
163
|
+
When you drag/drop a node into a lane area, the plugin assigns the node to that lane. If the node already belongs to another lane, it is removed from the previous lane first.
|
|
164
|
+
|
|
165
|
+
### Insert/Delete Lanes
|
|
166
|
+
|
|
167
|
+
When a lane is selected, operation icons appear on the right:
|
|
168
|
+
|
|
169
|
+
- Insert: insert a new lane before/after the current lane (Up/Down for horizontal pools, Left/Right for vertical pools)
|
|
170
|
+
- Delete: delete the current lane (at least one lane is kept)
|
|
171
|
+
|
|
172
|
+
## API
|
|
173
|
+
|
|
174
|
+
### Plugin API
|
|
175
|
+
|
|
176
|
+
After enabling the plugin, access the plugin instance via `lf.graphModel.dynamicGroup`:
|
|
177
|
+
|
|
178
|
+
#### getLaneByNodeId(nodeId)
|
|
179
|
+
|
|
180
|
+
Get the lane model that a node belongs to.
|
|
181
|
+
|
|
182
|
+
```ts | pure
|
|
183
|
+
const laneModel = lf.graphModel.dynamicGroup.getLaneByNodeId('node_1')
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### getLaneByBounds(bounds, nodeData)
|
|
187
|
+
|
|
188
|
+
Get the lane model for a given bounds. If multiple lanes overlap, the topmost lane is returned.
|
|
189
|
+
|
|
190
|
+
```ts | pure
|
|
191
|
+
const bounds = { minX: 100, minY: 100, maxX: 200, maxY: 200 }
|
|
192
|
+
const nodeData = { id: 'temp', type: 'rect' }
|
|
193
|
+
const laneModel = lf.graphModel.dynamicGroup.getLaneByBounds(bounds, nodeData)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Pool Model Methods
|
|
197
|
+
|
|
198
|
+
#### getLanes
|
|
199
|
+
|
|
200
|
+
Get all lane models in the pool.
|
|
201
|
+
|
|
202
|
+
#### addChildAbove / addChildBelow / addChildLeft / addChildRight
|
|
203
|
+
|
|
204
|
+
Insert a new lane before/after a reference lane (depending on pool direction).
|
|
205
|
+
|
|
206
|
+
#### deleteChild(childId)
|
|
207
|
+
|
|
208
|
+
Delete a lane.
|
|
209
|
+
|
|
210
|
+
### Lane Model Methods
|
|
211
|
+
|
|
212
|
+
#### getPoolId / getPoolModel
|
|
213
|
+
|
|
214
|
+
Get the owning pool of a lane.
|
|
215
|
+
|
|
216
|
+
## Events
|
|
217
|
+
|
|
218
|
+
### lane:not-allowed
|
|
219
|
+
|
|
220
|
+
Triggered when a node is not allowed to be appended into a lane:
|
|
221
|
+
|
|
222
|
+
```ts | pure
|
|
223
|
+
lf.on('lane:not-allowed', ({ lane, node }) => {
|
|
224
|
+
console.log('not allowed', lane.id, node.id)
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: 指南
|
|
3
|
+
group:
|
|
4
|
+
title: 插件功能
|
|
5
|
+
order: 3
|
|
6
|
+
title: 泳池泳道 (Pool)
|
|
7
|
+
order: 14
|
|
8
|
+
toc: content
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
LogicFlow 支持泳池泳道能力。泳池(pool)用于承载多个泳道(lane),泳道用于承载业务节点,并支持在拖拽/放置时自动把节点加入对应泳道,同时提供插入/删除泳道的交互入口。
|
|
12
|
+
|
|
13
|
+
## 演示
|
|
14
|
+
|
|
15
|
+
<code id="react-portal" src="@/src/tutorial/extension/pool"></code>
|
|
16
|
+
|
|
17
|
+
## 使用插件
|
|
18
|
+
|
|
19
|
+
```tsx | pure
|
|
20
|
+
import LogicFlow from '@logicflow/core'
|
|
21
|
+
import { PoolElements } from '@logicflow/extension'
|
|
22
|
+
import '@logicflow/core/es/index.css'
|
|
23
|
+
import '@logicflow/extension/es/index.css'
|
|
24
|
+
|
|
25
|
+
const lf = new LogicFlow({
|
|
26
|
+
container: document.querySelector('#container') as HTMLElement,
|
|
27
|
+
plugins: [PoolElements],
|
|
28
|
+
allowResize: true,
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 快速开始
|
|
33
|
+
|
|
34
|
+
只需要新增一个 `type: 'pool'` 的节点即可。泳池在首次渲染且没有泳道时,会自动创建一条默认泳道。
|
|
35
|
+
|
|
36
|
+
```ts | pure
|
|
37
|
+
lf.render({
|
|
38
|
+
nodes: [
|
|
39
|
+
{
|
|
40
|
+
id: 'pool_1',
|
|
41
|
+
type: 'pool',
|
|
42
|
+
x: 400,
|
|
43
|
+
y: 260,
|
|
44
|
+
text: '泳池',
|
|
45
|
+
properties: {
|
|
46
|
+
direction: 'horizontal',
|
|
47
|
+
width: 520,
|
|
48
|
+
height: 360,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
edges: [],
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 数据格式
|
|
57
|
+
|
|
58
|
+
泳池/泳道基于 DynamicGroup 机制实现,因此它们仍然是“特殊节点”。在数据层面,你可以使用 `children` 来描述层级关系;同时插件也会在交互过程中自动维护子节点的 `properties.parent`。
|
|
59
|
+
|
|
60
|
+
### 泳池(pool)
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
type PoolProperties = {
|
|
64
|
+
direction?: 'horizontal' | 'vertical'
|
|
65
|
+
width?: number
|
|
66
|
+
height?: number
|
|
67
|
+
laneConfig?: Record<string, unknown>
|
|
68
|
+
children?: string[]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 泳道(lane)
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
type LaneProperties = {
|
|
76
|
+
parent?: string
|
|
77
|
+
width?: number
|
|
78
|
+
height?: number
|
|
79
|
+
isRestrict?: boolean
|
|
80
|
+
autoResize?: boolean
|
|
81
|
+
children?: string[]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 完整示例
|
|
86
|
+
|
|
87
|
+
```ts | pure
|
|
88
|
+
lf.render({
|
|
89
|
+
nodes: [
|
|
90
|
+
{
|
|
91
|
+
id: 'pool_1',
|
|
92
|
+
type: 'pool',
|
|
93
|
+
x: 500,
|
|
94
|
+
y: 260,
|
|
95
|
+
text: '横向泳池',
|
|
96
|
+
properties: {
|
|
97
|
+
direction: 'horizontal',
|
|
98
|
+
width: 520,
|
|
99
|
+
height: 360,
|
|
100
|
+
children: ['lane_1', 'lane_2'],
|
|
101
|
+
},
|
|
102
|
+
children: ['lane_1', 'lane_2'],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'lane_1',
|
|
106
|
+
type: 'lane',
|
|
107
|
+
x: 540,
|
|
108
|
+
y: 340,
|
|
109
|
+
text: '泳道1',
|
|
110
|
+
properties: {
|
|
111
|
+
parent: 'pool_1',
|
|
112
|
+
width: 440,
|
|
113
|
+
height: 180,
|
|
114
|
+
isRestrict: true,
|
|
115
|
+
autoResize: false,
|
|
116
|
+
children: ['rect_1'],
|
|
117
|
+
},
|
|
118
|
+
children: ['rect_1'],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: 'lane_2',
|
|
122
|
+
type: 'lane',
|
|
123
|
+
x: 540,
|
|
124
|
+
y: 160,
|
|
125
|
+
text: '泳道2',
|
|
126
|
+
properties: {
|
|
127
|
+
parent: 'pool_1',
|
|
128
|
+
width: 440,
|
|
129
|
+
height: 180,
|
|
130
|
+
children: ['circle_1'],
|
|
131
|
+
},
|
|
132
|
+
children: ['circle_1'],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'rect_1',
|
|
136
|
+
type: 'rect',
|
|
137
|
+
x: 470,
|
|
138
|
+
y: 350,
|
|
139
|
+
text: '节点A',
|
|
140
|
+
properties: {
|
|
141
|
+
parent: 'lane_1',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: 'circle_1',
|
|
146
|
+
type: 'circle',
|
|
147
|
+
x: 620,
|
|
148
|
+
y: 150,
|
|
149
|
+
text: '节点B',
|
|
150
|
+
properties: {
|
|
151
|
+
parent: 'lane_2',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
edges: [],
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 交互说明
|
|
160
|
+
|
|
161
|
+
### 节点自动归属泳道
|
|
162
|
+
|
|
163
|
+
当你把节点拖拽/放置到某条泳道区域内时,插件会自动把节点加入该泳道。若节点原本属于其他泳道,会先从旧泳道移除,再加入新泳道。
|
|
164
|
+
|
|
165
|
+
### 插入/删除泳道
|
|
166
|
+
|
|
167
|
+
选中泳道后,泳道右侧会显示操作按钮:
|
|
168
|
+
|
|
169
|
+
- 插入:在当前泳道的前/后插入一条新泳道(横向泳池为“上/下”,竖向泳池为“左/右”)
|
|
170
|
+
- 删除:删除当前泳道(至少保留 1 条泳道)
|
|
171
|
+
|
|
172
|
+
## API
|
|
173
|
+
|
|
174
|
+
### 插件类 API
|
|
175
|
+
|
|
176
|
+
启用插件后,可通过 `lf.graphModel.dynamicGroup` 访问插件实例方法:
|
|
177
|
+
|
|
178
|
+
#### getLaneByNodeId(nodeId)
|
|
179
|
+
|
|
180
|
+
根据节点 id 获取其所属泳道的模型。
|
|
181
|
+
|
|
182
|
+
```ts | pure
|
|
183
|
+
const laneModel = lf.graphModel.dynamicGroup.getLaneByNodeId('node_1')
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### getLaneByBounds(bounds, nodeData)
|
|
187
|
+
|
|
188
|
+
根据边界框获取该区域所属的泳道。当泳道重合时,优先返回最上层的泳道。
|
|
189
|
+
|
|
190
|
+
```ts | pure
|
|
191
|
+
const bounds = { minX: 100, minY: 100, maxX: 200, maxY: 200 }
|
|
192
|
+
const nodeData = { id: 'temp', type: 'rect' }
|
|
193
|
+
const laneModel = lf.graphModel.dynamicGroup.getLaneByBounds(bounds, nodeData)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 泳池(pool)模型方法
|
|
197
|
+
|
|
198
|
+
#### getLanes
|
|
199
|
+
|
|
200
|
+
获取泳池内所有泳道模型。
|
|
201
|
+
|
|
202
|
+
#### addChildAbove / addChildBelow / addChildLeft / addChildRight
|
|
203
|
+
|
|
204
|
+
在指定泳道的前/后插入新泳道(方向由泳池布局决定)。
|
|
205
|
+
|
|
206
|
+
#### deleteChild(childId)
|
|
207
|
+
|
|
208
|
+
删除泳道。
|
|
209
|
+
|
|
210
|
+
### 泳道(lane)模型方法
|
|
211
|
+
|
|
212
|
+
#### getPoolId / getPoolModel
|
|
213
|
+
|
|
214
|
+
从泳道反查其所属泳池。
|
|
215
|
+
|
|
216
|
+
## 事件
|
|
217
|
+
|
|
218
|
+
### lane:not-allowed
|
|
219
|
+
|
|
220
|
+
当节点不被允许加入目标泳道时触发:
|
|
221
|
+
|
|
222
|
+
```ts | pure
|
|
223
|
+
lf.on('lane:not-allowed', ({ lane, node }) => {
|
|
224
|
+
console.log('not allowed', lane.id, node.id)
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|