@logicflow/core 2.2.0 → 2.2.2
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/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/dist/index.css +3 -2
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/LogicFlow.d.ts +9 -0
- package/es/LogicFlow.js +0 -1
- package/es/constant/index.d.ts +1 -1
- package/es/constant/index.js +1 -1
- package/es/constant/theme.d.ts +136 -0
- package/es/constant/theme.js +680 -0
- package/es/index.css +3 -2
- package/es/model/GraphModel.d.ts +10 -2
- package/es/model/GraphModel.js +48 -14
- package/es/model/TransformModel.js +9 -9
- package/es/model/edge/BaseEdgeModel.js +7 -2
- package/es/model/edge/PolylineEdgeModel.d.ts +7 -0
- package/es/model/edge/PolylineEdgeModel.js +136 -7
- package/es/model/node/BaseNodeModel.d.ts +12 -1
- package/es/model/node/BaseNodeModel.js +9 -2
- package/es/model/node/HtmlNodeModel.d.ts +12 -0
- package/es/model/node/HtmlNodeModel.js +19 -0
- package/es/model/node/PolygonNodeModel.js +3 -3
- package/es/options.d.ts +4 -2
- package/es/style/index.css +3 -2
- package/es/style/index.less +3 -2
- package/es/style/raw.d.ts +1 -1
- package/es/style/raw.js +1 -1
- package/es/tool/MultipleSelectTool.js +10 -5
- package/es/util/drag.js +0 -1
- package/es/util/edge.d.ts +40 -1
- package/es/util/edge.js +43 -9
- package/es/util/geometry.d.ts +8 -0
- package/es/util/geometry.js +79 -0
- package/es/util/theme.d.ts +2 -65
- package/es/util/theme.js +4 -281
- package/es/view/Anchor.d.ts +1 -0
- package/es/view/Anchor.js +24 -21
- package/es/view/Control.d.ts +5 -0
- package/es/view/Control.js +44 -57
- package/es/view/edge/BaseEdge.js +9 -0
- package/es/view/edge/PolylineEdge.js +13 -2
- package/es/view/node/BaseNode.d.ts +1 -0
- package/es/view/node/BaseNode.js +23 -11
- package/es/view/node/HtmlNode.js +2 -4
- package/es/view/overlay/CanvasOverlay.js +5 -2
- package/es/view/overlay/Grid.d.ts +12 -1
- package/es/view/overlay/Grid.js +85 -23
- package/es/view/overlay/OutlineOverlay.d.ts +1 -0
- package/es/view/overlay/OutlineOverlay.js +18 -17
- package/es/view/overlay/gridConfig.d.ts +46 -0
- package/es/view/overlay/gridConfig.js +99 -0
- package/es/view/shape/Polygon.d.ts +0 -7
- package/es/view/shape/Polygon.js +12 -43
- package/lib/LogicFlow.d.ts +9 -0
- package/lib/LogicFlow.js +0 -1
- package/lib/constant/index.d.ts +1 -1
- package/lib/constant/index.js +16 -2
- package/lib/constant/theme.d.ts +136 -0
- package/lib/constant/theme.js +683 -0
- package/lib/index.css +3 -2
- package/lib/model/GraphModel.d.ts +10 -2
- package/lib/model/GraphModel.js +49 -15
- package/lib/model/TransformModel.js +9 -9
- package/lib/model/edge/BaseEdgeModel.js +7 -2
- package/lib/model/edge/PolylineEdgeModel.d.ts +7 -0
- package/lib/model/edge/PolylineEdgeModel.js +136 -7
- package/lib/model/node/BaseNodeModel.d.ts +12 -1
- package/lib/model/node/BaseNodeModel.js +9 -2
- package/lib/model/node/HtmlNodeModel.d.ts +12 -0
- package/lib/model/node/HtmlNodeModel.js +19 -0
- package/lib/model/node/PolygonNodeModel.js +3 -3
- package/lib/options.d.ts +4 -2
- package/lib/style/index.css +3 -2
- package/lib/style/index.less +3 -2
- package/lib/style/raw.d.ts +1 -1
- package/lib/style/raw.js +1 -1
- package/lib/tool/MultipleSelectTool.js +10 -5
- package/lib/util/drag.js +0 -1
- package/lib/util/edge.d.ts +40 -1
- package/lib/util/edge.js +43 -9
- package/lib/util/geometry.d.ts +8 -0
- package/lib/util/geometry.js +81 -1
- package/lib/util/theme.d.ts +2 -65
- package/lib/util/theme.js +15 -292
- package/lib/view/Anchor.d.ts +1 -0
- package/lib/view/Anchor.js +24 -21
- package/lib/view/Control.d.ts +5 -0
- package/lib/view/Control.js +44 -57
- package/lib/view/edge/BaseEdge.js +9 -0
- package/lib/view/edge/PolylineEdge.js +13 -2
- package/lib/view/node/BaseNode.d.ts +1 -0
- package/lib/view/node/BaseNode.js +22 -10
- package/lib/view/node/HtmlNode.js +1 -3
- package/lib/view/overlay/CanvasOverlay.js +5 -2
- package/lib/view/overlay/Grid.d.ts +12 -1
- package/lib/view/overlay/Grid.js +83 -21
- package/lib/view/overlay/OutlineOverlay.d.ts +1 -0
- package/lib/view/overlay/OutlineOverlay.js +18 -17
- package/lib/view/overlay/gridConfig.d.ts +46 -0
- package/lib/view/overlay/gridConfig.js +104 -0
- package/lib/view/shape/Polygon.d.ts +0 -7
- package/lib/view/shape/Polygon.js +13 -45
- package/package.json +9 -2
- package/scripts/postinstall-ai-prompt.js +67 -0
- package/.turbo/turbo-build$colon$dev.log +0 -10
- package/.turbo/turbo-build.log +0 -33
- package/CHANGELOG.md +0 -1849
- package/__tests__/algorithm/egde.test.ts +0 -131
- package/__tests__/algorithm/index.test.ts +0 -74
- package/__tests__/algorithm/outline.test.ts +0 -43
- package/__tests__/bugs/1545-spec.test.ts +0 -42
- package/__tests__/event/event.test.ts +0 -22
- package/__tests__/history/history.test.ts +0 -28
- package/__tests__/logicflow.test.ts +0 -575
- package/__tests__/model/graphmodel.test.ts +0 -87
- package/__tests__/util/compatible.test.ts +0 -48
- package/__tests__/util/edge.test.ts +0 -224
- package/__tests__/util/geometry.test.ts +0 -14
- package/__tests__/util/graph.test.ts +0 -16
- package/__tests__/util/matrix.test.ts +0 -41
- package/__tests__/util/node.test.ts +0 -68
- package/__tests__/util/sampling.test.ts +0 -12
- package/__tests__/util/vector.test.ts +0 -50
- package/__tests__/util/zIndex.test.ts +0 -10
- package/src/LogicFlow.tsx +0 -2008
- package/src/algorithm/edge.ts +0 -67
- package/src/algorithm/index.ts +0 -70
- package/src/algorithm/outline.ts +0 -77
- package/src/algorithm/rotate.ts +0 -55
- package/src/common/drag.ts +0 -219
- package/src/common/history.ts +0 -108
- package/src/common/index.ts +0 -6
- package/src/common/keyboard.ts +0 -108
- package/src/common/matrix.ts +0 -122
- package/src/common/vector.ts +0 -93
- package/src/constant/index.ts +0 -179
- package/src/event/event.md +0 -66
- package/src/event/eventArgs.ts +0 -643
- package/src/event/eventEmitter.ts +0 -156
- package/src/history/index.ts +0 -119
- package/src/index.less +0 -1
- package/src/index.ts +0 -26
- package/src/keyboard/index.ts +0 -112
- package/src/keyboard/shortcut.ts +0 -200
- package/src/model/BaseModel.ts +0 -250
- package/src/model/EditConfigModel.ts +0 -334
- package/src/model/GraphModel.ts +0 -1788
- package/src/model/NestedTransformModel.ts +0 -121
- package/src/model/SnaplineModel.ts +0 -256
- package/src/model/TransformModel.ts +0 -258
- package/src/model/edge/BaseEdgeModel.ts +0 -777
- package/src/model/edge/BezierEdgeModel.ts +0 -197
- package/src/model/edge/LineEdgeModel.ts +0 -36
- package/src/model/edge/PolylineEdgeModel.ts +0 -672
- package/src/model/edge/index.ts +0 -4
- package/src/model/index.ts +0 -9
- package/src/model/node/BaseNodeModel.ts +0 -949
- package/src/model/node/CircleNodeModel.ts +0 -91
- package/src/model/node/DiamondNodeModel.ts +0 -132
- package/src/model/node/EllipseNodeModel.ts +0 -98
- package/src/model/node/HtmlNodeModel.ts +0 -50
- package/src/model/node/PolygonNodeModel.ts +0 -150
- package/src/model/node/RectNodeModel.ts +0 -69
- package/src/model/node/TextNodeModel.ts +0 -54
- package/src/model/node/index.ts +0 -8
- package/src/options.ts +0 -145
- package/src/style/index.less +0 -261
- package/src/style/raw.ts +0 -220
- package/src/tool/MultipleSelectTool.tsx +0 -132
- package/src/tool/TextEditTool.tsx +0 -193
- package/src/tool/index.ts +0 -101
- package/src/typings.d.ts +0 -5
- package/src/util/animation.ts +0 -29
- package/src/util/browser.ts +0 -4
- package/src/util/compatible.ts +0 -15
- package/src/util/drag.ts +0 -220
- package/src/util/edge.ts +0 -1060
- package/src/util/geometry.ts +0 -55
- package/src/util/graph.ts +0 -46
- package/src/util/index.ts +0 -17
- package/src/util/matrix.ts +0 -129
- package/src/util/mobx.ts +0 -23
- package/src/util/node.ts +0 -543
- package/src/util/raf.ts +0 -28
- package/src/util/resize.ts +0 -606
- package/src/util/sampling.ts +0 -85
- package/src/util/theme.ts +0 -375
- package/src/util/uuid.ts +0 -26
- package/src/util/vector.ts +0 -93
- package/src/util/zIndex.ts +0 -6
- package/src/view/Anchor.tsx +0 -445
- package/src/view/Control.tsx +0 -512
- package/src/view/Graph.tsx +0 -141
- package/src/view/Rotate.tsx +0 -113
- package/src/view/behavior/dnd.ts +0 -162
- package/src/view/behavior/index.ts +0 -2
- package/src/view/behavior/snapline.ts +0 -16
- package/src/view/edge/AdjustPoint.tsx +0 -425
- package/src/view/edge/Arrow.tsx +0 -54
- package/src/view/edge/BaseEdge.tsx +0 -650
- package/src/view/edge/BezierEdge.tsx +0 -101
- package/src/view/edge/LineEdge.tsx +0 -81
- package/src/view/edge/PolylineEdge.tsx +0 -299
- package/src/view/edge/index.ts +0 -6
- package/src/view/index.ts +0 -8
- package/src/view/node/BaseNode.tsx +0 -571
- package/src/view/node/CircleNode.tsx +0 -21
- package/src/view/node/DiamondNode.tsx +0 -24
- package/src/view/node/EllipseNode.tsx +0 -22
- package/src/view/node/HtmlNode.tsx +0 -95
- package/src/view/node/PolygonNode.tsx +0 -28
- package/src/view/node/RectNode.tsx +0 -30
- package/src/view/node/TextNode.tsx +0 -39
- package/src/view/node/index.ts +0 -8
- package/src/view/overlay/BackgroundOverlay.tsx +0 -34
- package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
- package/src/view/overlay/CanvasOverlay.tsx +0 -288
- package/src/view/overlay/Grid.tsx +0 -162
- package/src/view/overlay/ModificationOverlay.tsx +0 -31
- package/src/view/overlay/OutlineOverlay.tsx +0 -170
- package/src/view/overlay/SnaplineOverlay.tsx +0 -44
- package/src/view/overlay/ToolOverlay.tsx +0 -65
- package/src/view/overlay/getTransformHoc.tsx +0 -50
- package/src/view/overlay/index.ts +0 -8
- package/src/view/shape/Circle.tsx +0 -41
- package/src/view/shape/Ellipse.tsx +0 -42
- package/src/view/shape/Line.tsx +0 -39
- package/src/view/shape/Path.tsx +0 -22
- package/src/view/shape/Polygon.tsx +0 -91
- package/src/view/shape/Polyline.tsx +0 -31
- package/src/view/shape/Rect.tsx +0 -44
- package/src/view/shape/Text.tsx +0 -169
- package/src/view/shape/index.ts +0 -8
- package/src/view/text/BaseText.tsx +0 -134
- package/src/view/text/LineText.tsx +0 -168
- package/src/view/text/index.ts +0 -2
- package/stats.html +0 -4842
- package/tsconfig.json +0 -18
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: Guide
|
|
3
|
+
group:
|
|
4
|
+
title: Plug-in functionality
|
|
5
|
+
order: 3
|
|
6
|
+
title: Group
|
|
7
|
+
order: 8
|
|
8
|
+
toc: content
|
|
9
|
+
tag: New
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
LogicFlow supports dynamic grouping. Dynamic grouping is an enhanced version of the built-in Group node (since we’ve added Node Resize functionality and the naming of the Group node wasn’t quite appropriate, we introduced the upgraded DynamicGroup node). We will continue to enhance this plugin, and we welcome contributions from the community.
|
|
13
|
+
|
|
14
|
+
## Demonstration
|
|
15
|
+
|
|
16
|
+
<code id="react-portal" src="@/src/tutorial/extension/dynamic-group"></code>
|
|
17
|
+
|
|
18
|
+
## Using the Plugin
|
|
19
|
+
|
|
20
|
+
```tsx | pure
|
|
21
|
+
import LogicFlow from '@logicflow/core';
|
|
22
|
+
import { DynamicGroup } from '@logicflow/extension';
|
|
23
|
+
import '@logicflow/extension/es/style/index.css';
|
|
24
|
+
|
|
25
|
+
const lf = new LogicFlow({
|
|
26
|
+
// ...
|
|
27
|
+
plugins: [DynamicGroup],
|
|
28
|
+
});
|
|
29
|
+
lf.render({
|
|
30
|
+
nodes: [
|
|
31
|
+
{
|
|
32
|
+
type: 'dynamic-group',
|
|
33
|
+
x: 300,
|
|
34
|
+
y: 300,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Data Format for DynamicGroup Nodes
|
|
41
|
+
|
|
42
|
+
`dynamic-group` is a special type of node in LogicFlow, so its data format is similar to that of nodes but with an additional `children` property to store the IDs of its child nodes.
|
|
43
|
+
|
|
44
|
+
```tsx | pure
|
|
45
|
+
lf.render({
|
|
46
|
+
nodes: [
|
|
47
|
+
{
|
|
48
|
+
type: "dynamic-group",
|
|
49
|
+
x: 400,
|
|
50
|
+
y: 400,
|
|
51
|
+
children: ["rect_2"],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "rect_2",
|
|
55
|
+
type: "circle",
|
|
56
|
+
x: 400,
|
|
57
|
+
y: 400,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Customizing Group Nodes
|
|
64
|
+
|
|
65
|
+
In practical applications, we recommend that developers customize groups based on their business needs and assign meaningful names to these groups. For example, in BPMN, a subgroup might be named `subProcess`, and then customize the group's appearance accordingly.
|
|
66
|
+
|
|
67
|
+
```tsx | pure
|
|
68
|
+
import { dynamicGroup } from "@logicflow/extension";
|
|
69
|
+
|
|
70
|
+
class CustomGroup extends dynamicGroup.view {}
|
|
71
|
+
|
|
72
|
+
class CustomGroupModel extends dynamicGroup.model {
|
|
73
|
+
getNodeStyle() {
|
|
74
|
+
const style = super.getNodeStyle();
|
|
75
|
+
style.stroke = "#AEAFAE";
|
|
76
|
+
style.strokeDasharray = "3 3";
|
|
77
|
+
style.strokeWidth = 1;
|
|
78
|
+
return style;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
lf.register({
|
|
83
|
+
type: "my-custom-group",
|
|
84
|
+
view: CustomGroup,
|
|
85
|
+
model: CustomGroupModel,
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Properties and Methods of groupModel
|
|
90
|
+
|
|
91
|
+
In addition to the standard node properties, group nodes have special properties related to grouping. You can control these properties to achieve various grouping effects. For node properties and methods, see [nodeModel](../../api/runtime-model/nodeModel.en.md).
|
|
92
|
+
|
|
93
|
+
### State Properties
|
|
94
|
+
```ts
|
|
95
|
+
export type IRectNodeProperties = {
|
|
96
|
+
width?: number
|
|
97
|
+
height?: number
|
|
98
|
+
radius?: number
|
|
99
|
+
style?: LogicFlow.CommonTheme
|
|
100
|
+
textStyle?: LogicFlow.CommonTheme
|
|
101
|
+
|
|
102
|
+
[key: string]: unknown
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type IGroupNodeProperties = {
|
|
106
|
+
/**
|
|
107
|
+
* IDs of nodes within the group
|
|
108
|
+
*/
|
|
109
|
+
children?: string[]
|
|
110
|
+
/**
|
|
111
|
+
* Whether the group node can be collapsed
|
|
112
|
+
*/
|
|
113
|
+
collapsible?: boolean
|
|
114
|
+
/**
|
|
115
|
+
* Collapsed state of the group node
|
|
116
|
+
*/
|
|
117
|
+
isCollapsed?: boolean
|
|
118
|
+
/**
|
|
119
|
+
* Whether to restrict the movement range of child nodes
|
|
120
|
+
* When enabled, child nodes can only move within the group bounds
|
|
121
|
+
* and cannot be dragged outside the group.
|
|
122
|
+
* Also limits resizing to not exceed children's floor area
|
|
123
|
+
* Defaults to false, allowing nodes to be dragged out of the group
|
|
124
|
+
*/
|
|
125
|
+
isRestrict?: boolean
|
|
126
|
+
/**
|
|
127
|
+
* When isRestrict mode is enabled and autoResize is true,
|
|
128
|
+
* the parent node will automatically resize when child nodes move within it
|
|
129
|
+
*/
|
|
130
|
+
autoResize?: boolean
|
|
131
|
+
|
|
132
|
+
// Default width and height for the expanded state of the group
|
|
133
|
+
/**
|
|
134
|
+
* Width and height of the group node when expanded
|
|
135
|
+
*/
|
|
136
|
+
width?: number
|
|
137
|
+
height?: number
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Width and height of the group node when collapsed
|
|
141
|
+
*/
|
|
142
|
+
collapsedWidth?: number
|
|
143
|
+
collapsedHeight?: number
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* When scaling or rotating a container,
|
|
147
|
+
* whether to scale or rotate the nodes within the group
|
|
148
|
+
* Default to false. When set to true, scaling or rotating the group
|
|
149
|
+
* will also transform the child nodes accordingly
|
|
150
|
+
*/
|
|
151
|
+
transformWithContainer?: boolean
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* zIndex of the group element
|
|
155
|
+
*/
|
|
156
|
+
zIndex?: number
|
|
157
|
+
/**
|
|
158
|
+
* Whether the group node should automatically bring itself to the front
|
|
159
|
+
* When the group is selected, whether to automatically bring the group
|
|
160
|
+
* and its children to the top layer
|
|
161
|
+
*/
|
|
162
|
+
autoToFront?: boolean
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Validation function for whether nodes can be added to the group
|
|
166
|
+
* Allows customizing which nodes can be added to the group
|
|
167
|
+
*/
|
|
168
|
+
isAllowAppendIn?: (nodeData: LogicFlow.NodeData) => boolean
|
|
169
|
+
} & IRectNodeProperties
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Default Configuration
|
|
173
|
+
|
|
174
|
+
Group nodes have the following default configuration:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
// Default size for expanded group
|
|
178
|
+
const DEFAULT_GROUP_EXPAND_WIDTH = 400
|
|
179
|
+
const DEFAULT_GROUP_EXPAND_HEIGHT = 230
|
|
180
|
+
// Default size for collapsed group
|
|
181
|
+
const DEFAULT_GROUP_COLLAPSE_WIDTH = 80
|
|
182
|
+
const DEFAULT_GROUP_COLLAPSE_HEIGHT = 60
|
|
183
|
+
// Default zIndex
|
|
184
|
+
const DEFAULT_BOTTOM_Z_INDEX = -10000
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Group properties can be set similarly to node properties, either in the `groupModel`'s `initNodeData` or `setAttributes` methods. It can also be directly provided in the `properties` during node initialization (recommended).
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
const dynamicGroupNodeConfig = {
|
|
191
|
+
id: 'dynamic-group_1',
|
|
192
|
+
type: 'dynamic-group',
|
|
193
|
+
x: 500,
|
|
194
|
+
y: 140,
|
|
195
|
+
text: 'dynamic-group_1',
|
|
196
|
+
resizable: true,
|
|
197
|
+
rotatable: false,
|
|
198
|
+
properties: {
|
|
199
|
+
children: ["rect_3"],
|
|
200
|
+
collapsible: true, // Enable collapsing
|
|
201
|
+
isCollapsed: false, // Initial state is expanded
|
|
202
|
+
width: 420, // Width when expanded
|
|
203
|
+
height: 250, // Height when expanded
|
|
204
|
+
collapsedWidth: 80, // Width when collapsed
|
|
205
|
+
collapsedHeight: 60, // Height when collapsed
|
|
206
|
+
radius: 5, // Border radius
|
|
207
|
+
isRestrict: false, // Don't restrict child node movement
|
|
208
|
+
autoResize: false, // Don't auto-resize
|
|
209
|
+
transformWithContainer: true, // Transform children with group
|
|
210
|
+
zIndex: -1000, // Layer index
|
|
211
|
+
autoToFront: true, // Auto bring to front when selected
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Complete Configuration Example
|
|
217
|
+
|
|
218
|
+
Here's a complete example showing various property usage:
|
|
219
|
+
|
|
220
|
+
```tsx | pure
|
|
221
|
+
import LogicFlow from '@logicflow/core'
|
|
222
|
+
import { DynamicGroup, dynamicGroup } from '@logicflow/extension'
|
|
223
|
+
|
|
224
|
+
// Custom group
|
|
225
|
+
class CustomGroup extends dynamicGroup.view {}
|
|
226
|
+
|
|
227
|
+
class CustomGroupModel extends dynamicGroup.model {
|
|
228
|
+
initNodeData(data) {
|
|
229
|
+
super.initNodeData(data)
|
|
230
|
+
|
|
231
|
+
// Set default properties
|
|
232
|
+
this.properties = {
|
|
233
|
+
...this.properties,
|
|
234
|
+
collapsible: true,
|
|
235
|
+
autoToFront: true,
|
|
236
|
+
transformWithContainer: false,
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Custom group styling
|
|
241
|
+
getNodeStyle() {
|
|
242
|
+
const style = super.getNodeStyle()
|
|
243
|
+
style.stroke = '#1890ff'
|
|
244
|
+
style.strokeWidth = 2
|
|
245
|
+
style.fill = 'rgba(24, 144, 255, 0.1)'
|
|
246
|
+
return style
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Custom drag-over highlight style
|
|
250
|
+
getAddableOutlineStyle() {
|
|
251
|
+
const style = super.getAddableOutlineStyle()
|
|
252
|
+
style.stroke = '#52c41a'
|
|
253
|
+
style.strokeDasharray = '4 4'
|
|
254
|
+
style.strokeWidth = 2
|
|
255
|
+
return style
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Restrict to only allow specific node types
|
|
259
|
+
isAllowAppendIn(nodeData) {
|
|
260
|
+
return ['rect', 'circle', 'diamond'].includes(nodeData.type)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Register custom group
|
|
265
|
+
lf.register({
|
|
266
|
+
type: 'custom-group',
|
|
267
|
+
view: CustomGroup,
|
|
268
|
+
model: CustomGroupModel,
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// Render data
|
|
272
|
+
lf.render({
|
|
273
|
+
nodes: [
|
|
274
|
+
{
|
|
275
|
+
id: 'group_1',
|
|
276
|
+
type: 'custom-group',
|
|
277
|
+
x: 300,
|
|
278
|
+
y: 200,
|
|
279
|
+
text: 'My Group',
|
|
280
|
+
properties: {
|
|
281
|
+
children: ['node_1', 'node_2'],
|
|
282
|
+
collapsible: true,
|
|
283
|
+
width: 400,
|
|
284
|
+
height: 300,
|
|
285
|
+
isRestrict: true,
|
|
286
|
+
autoResize: true,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
id: 'node_1',
|
|
291
|
+
type: 'rect',
|
|
292
|
+
x: 250,
|
|
293
|
+
y: 150,
|
|
294
|
+
text: 'Node 1',
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'node_2',
|
|
298
|
+
type: 'circle',
|
|
299
|
+
x: 350,
|
|
300
|
+
y: 250,
|
|
301
|
+
text: 'Node 2',
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
})
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## API
|
|
308
|
+
|
|
309
|
+
### Basic Methods
|
|
310
|
+
|
|
311
|
+
#### addChild
|
|
312
|
+
|
|
313
|
+
Adds a node as a child of the group. Note that this method only establishes the relationship and does not automatically move the node into the group.
|
|
314
|
+
|
|
315
|
+
```tsx | pure
|
|
316
|
+
const groupModel = lf.getNodeModelById("group_id");
|
|
317
|
+
const node = lf.addNode({
|
|
318
|
+
type: "rect",
|
|
319
|
+
x: groupModel.x,
|
|
320
|
+
y: groupModel.y,
|
|
321
|
+
});
|
|
322
|
+
groupModel.addChild(node.id);
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### removeChild
|
|
326
|
+
|
|
327
|
+
Removes a child node from the group.
|
|
328
|
+
|
|
329
|
+
```tsx | pure
|
|
330
|
+
const groupModel = lf.getNodeModelById("group_id");
|
|
331
|
+
groupModel.removeChild("node_id_1");
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### toggleCollapse
|
|
335
|
+
|
|
336
|
+
Collapses or expands the group. Pass `true` to collapse, `false` to expand, or no parameter to toggle current state.
|
|
337
|
+
|
|
338
|
+
```tsx | pure
|
|
339
|
+
const groupModel = lf.getNodeModelById('group_id');
|
|
340
|
+
// Collapse the group
|
|
341
|
+
groupModel.toggleCollapse(true);
|
|
342
|
+
// Expand the group
|
|
343
|
+
groupModel.toggleCollapse(false);
|
|
344
|
+
// Toggle current state
|
|
345
|
+
groupModel.toggleCollapse();
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
#### getNodesInGroup
|
|
349
|
+
|
|
350
|
+
Gets all node IDs within the group.
|
|
351
|
+
|
|
352
|
+
```tsx | pure
|
|
353
|
+
const groupModel = lf.getNodeModelById('group_id') as DynamicGroupNodeModel;
|
|
354
|
+
const nodeIds = groupModel.getNodesInGroup(groupModel);
|
|
355
|
+
console.log('Node IDs in group:', nodeIds);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Validation Methods
|
|
359
|
+
|
|
360
|
+
#### isAllowAppendIn(nodeData)
|
|
361
|
+
|
|
362
|
+
Checks whether the specified node can be added to this group. By default, all nodes can be added.
|
|
363
|
+
|
|
364
|
+
```tsx | pure
|
|
365
|
+
class MyGroupModel extends dynamicGroup.model {
|
|
366
|
+
isAllowAppendIn(nodeData) {
|
|
367
|
+
// Only allow nodes of type "custom-rect" to be added to this group
|
|
368
|
+
return nodeData.type === "custom-rect";
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
:::info{title=Tip}
|
|
374
|
+
If a node is not allowed to be added to a group, it will still be displayed at the user's drop location, but it will not be part of the group. If you want to delete the node, you can listen for the `group:not-allowed` event and manually remove the node.
|
|
375
|
+
:::
|
|
376
|
+
|
|
377
|
+
### Styling Methods
|
|
378
|
+
|
|
379
|
+
#### getAddableOutlineStyle
|
|
380
|
+
|
|
381
|
+
Sets the highlight style for the group when dragging a node over it.
|
|
382
|
+
|
|
383
|
+
```tsx | pure
|
|
384
|
+
class MyGroupModel extends dynamicGroup.model {
|
|
385
|
+
getAddableOutlineStyle() {
|
|
386
|
+
const style = super.getAddableOutlineStyle();
|
|
387
|
+
style.stroke = "#AEAFAE";
|
|
388
|
+
style.strokeDasharray = "3 3";
|
|
389
|
+
return style;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### getResizeOutlineStyle
|
|
395
|
+
|
|
396
|
+
Sets the border style when resizing the group.
|
|
397
|
+
|
|
398
|
+
```tsx | pure
|
|
399
|
+
class MyGroupModel extends dynamicGroup.model {
|
|
400
|
+
getResizeOutlineStyle() {
|
|
401
|
+
const style = super.getResizeOutlineStyle();
|
|
402
|
+
style.stroke = "#1890ff";
|
|
403
|
+
style.strokeWidth = 1;
|
|
404
|
+
return style;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
#### getAnchorStyle
|
|
410
|
+
|
|
411
|
+
Sets the anchor point style for the group.
|
|
412
|
+
|
|
413
|
+
```tsx | pure
|
|
414
|
+
class MyGroupModel extends dynamicGroup.model {
|
|
415
|
+
getAnchorStyle() {
|
|
416
|
+
const style = super.getAnchorStyle();
|
|
417
|
+
style.stroke = "#1890ff";
|
|
418
|
+
style.fill = "#ffffff";
|
|
419
|
+
return style;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Utility Methods
|
|
425
|
+
|
|
426
|
+
#### setAllowAppendChild
|
|
427
|
+
|
|
428
|
+
Sets whether the group is in a state that allows adding child nodes.
|
|
429
|
+
|
|
430
|
+
```tsx | pure
|
|
431
|
+
const groupModel = lf.getNodeModelById('group_id') as DynamicGroupNodeModel;
|
|
432
|
+
// Enable adding children
|
|
433
|
+
groupModel.setAllowAppendChild(true);
|
|
434
|
+
// Disable adding children
|
|
435
|
+
groupModel.setAllowAppendChild(false);
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### toBack
|
|
439
|
+
|
|
440
|
+
Sends the group node to the back layer.
|
|
441
|
+
|
|
442
|
+
```tsx | pure
|
|
443
|
+
const groupModel = lf.getNodeModelById('group_id') as DynamicGroupNodeModel;
|
|
444
|
+
groupModel.toBack();
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Plugin Class API
|
|
448
|
+
|
|
449
|
+
The DynamicGroup plugin class provides some utility methods that you can access through `lf.graphModel.dynamicGroup`:
|
|
450
|
+
|
|
451
|
+
### getGroupByNodeId
|
|
452
|
+
|
|
453
|
+
Get the group that a node belongs to by node ID.
|
|
454
|
+
|
|
455
|
+
```tsx | pure
|
|
456
|
+
const nodeGroup = lf.graphModel.dynamicGroup.getGroupByNodeId('node_1');
|
|
457
|
+
if (nodeGroup) {
|
|
458
|
+
console.log('Node belongs to group:', nodeGroup.getData());
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### getGroupByBounds
|
|
463
|
+
|
|
464
|
+
Get the group at the specified position by bounds. When groups overlap, returns the topmost group.
|
|
465
|
+
|
|
466
|
+
```tsx | pure
|
|
467
|
+
const bounds = {
|
|
468
|
+
minX: 100,
|
|
469
|
+
minY: 100,
|
|
470
|
+
maxX: 200,
|
|
471
|
+
maxY: 200
|
|
472
|
+
};
|
|
473
|
+
const nodeData = { id: 'test', type: 'rect' };
|
|
474
|
+
const group = lf.graphModel.dynamicGroup.getGroupByBounds(bounds, nodeData);
|
|
475
|
+
if (group) {
|
|
476
|
+
console.log('Area belongs to group:', group.getData());
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### sendNodeToFront
|
|
481
|
+
|
|
482
|
+
Bring an element to the front. If it's a group, also brings its child elements to the front.
|
|
483
|
+
|
|
484
|
+
```tsx | pure
|
|
485
|
+
const nodeModel = lf.getNodeModelById('group_1');
|
|
486
|
+
lf.graphModel.dynamicGroup.sendNodeToFront(nodeModel);
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Plugin Events
|
|
490
|
+
|
|
491
|
+
The DynamicGroup plugin triggers the following events. You can listen to these events to implement custom business logic:
|
|
492
|
+
|
|
493
|
+
### Group-related Events
|
|
494
|
+
|
|
495
|
+
| Event Name | Description | Event Object |
|
|
496
|
+
| :------------------ | :--------------------------------------------------- | :--------------------------------------------------------------- |
|
|
497
|
+
| `group:add-node` | Triggered when a node is added to a group | `{ data: Group data, childId: ID of newly added node }` |
|
|
498
|
+
| `group:remove-node` | Triggered when a node is removed from a group | `{ data: Group data, childId: ID of removed node }` |
|
|
499
|
+
| `group:not-allowed` | Triggered when a node is not allowed to join a group | `{ group: Group data, node: Information of the forbidden node }` |
|
|
500
|
+
|
|
501
|
+
### Event Listening Examples
|
|
502
|
+
|
|
503
|
+
```tsx | pure
|
|
504
|
+
// Listen for node addition to group
|
|
505
|
+
lf.on('group:add-node', ({ data, childId }) => {
|
|
506
|
+
console.log(`Node ${childId} has been added to group ${data.id}`)
|
|
507
|
+
|
|
508
|
+
// Execute custom logic here, such as updating UI state
|
|
509
|
+
updateGroupInfo(data.id, childId, 'add')
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
// Listen for node removal from group
|
|
513
|
+
lf.on('group:remove-node', ({ data, childId }) => {
|
|
514
|
+
console.log(`Node ${childId} has been removed from group ${data.id}`)
|
|
515
|
+
|
|
516
|
+
updateGroupInfo(data.id, childId, 'remove')
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
// Listen for node rejection from group
|
|
520
|
+
lf.on('group:not-allowed', ({ group, node }) => {
|
|
521
|
+
console.log(`Node ${node.id} is not allowed to join group ${group.id}`)
|
|
522
|
+
|
|
523
|
+
// Show notification
|
|
524
|
+
showNotification(`Node type ${node.type} cannot join this group`)
|
|
525
|
+
|
|
526
|
+
// Delete the rejected node if needed
|
|
527
|
+
// lf.deleteNode(node.id)
|
|
528
|
+
})
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Advanced Usage
|
|
532
|
+
|
|
533
|
+
### Restriction Mode (isRestrict)
|
|
534
|
+
|
|
535
|
+
When restriction mode is enabled, child nodes will be constrained within the group bounds and cannot be dragged outside:
|
|
536
|
+
|
|
537
|
+
```tsx | pure
|
|
538
|
+
const restrictedGroup = {
|
|
539
|
+
type: 'dynamic-group',
|
|
540
|
+
x: 300,
|
|
541
|
+
y: 200,
|
|
542
|
+
properties: {
|
|
543
|
+
isRestrict: true, // Enable restriction mode
|
|
544
|
+
autoResize: true, // Enable auto-resize
|
|
545
|
+
width: 400,
|
|
546
|
+
height: 300,
|
|
547
|
+
},
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// In restriction mode, the group will auto-resize to accommodate all child nodes when they move
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Collapse Feature Details
|
|
554
|
+
|
|
555
|
+
The group's collapse feature automatically handles:
|
|
556
|
+
|
|
557
|
+
1. **Node Hiding**: Hide all child nodes when collapsed, restore visibility when expanded
|
|
558
|
+
2. **Edge Handling**: Automatically create virtual edges to represent connections between group interior and exterior
|
|
559
|
+
3. **Size Changes**: Switch between collapsed and expanded dimensions
|
|
560
|
+
|
|
561
|
+
```tsx | pure
|
|
562
|
+
// Listen for group state changes
|
|
563
|
+
lf.on('node:properties-change', ({ id, properties, preProperties }) => {
|
|
564
|
+
const node = lf.getNodeModelById(id)
|
|
565
|
+
if (node?.isGroup) {
|
|
566
|
+
const wasCollapsed = preProperties.isCollapsed
|
|
567
|
+
const isCollapsed = properties.isCollapsed
|
|
568
|
+
|
|
569
|
+
if (wasCollapsed !== isCollapsed) {
|
|
570
|
+
console.log(`Group ${id} state changed: ${isCollapsed ? 'collapsed' : 'expanded'}`)
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
})
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Transform with Container
|
|
577
|
+
|
|
578
|
+
When `transformWithContainer` is enabled, scaling or rotating the group will also transform child nodes:
|
|
579
|
+
|
|
580
|
+
```tsx | pure
|
|
581
|
+
const transformGroup = {
|
|
582
|
+
type: 'dynamic-group',
|
|
583
|
+
x: 300,
|
|
584
|
+
y: 200,
|
|
585
|
+
properties: {
|
|
586
|
+
transformWithContainer: true, // Enable synchronized transformation
|
|
587
|
+
width: 400,
|
|
588
|
+
height: 300,
|
|
589
|
+
},
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Now when scaling or rotating the group, child nodes will maintain relative positions and transform accordingly
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
:::info{title=How-to-Prevent-Nodes-from-Connecting-to-a-Group?}
|
|
596
|
+
|
|
597
|
+
Groups are a special type of node, so it is still possible to use [custom connection rules](../advanced/node.en.md#connection-rules) to prevent nodes from connecting directly to groups. However, do not set the number of anchors on a group to 0, as connections are used to represent the relationship between internal and external nodes when the group is collapsed.
|
|
598
|
+
|
|
599
|
+
:::
|
|
600
|
+
|
|
601
|
+
## About Swimlanes
|
|
602
|
+
:::info{title=About-Swimlanes}
|
|
603
|
+
|
|
604
|
+
Grouping functionality is not the same as swimlanes; developers need to implement swimlanes based on the grouping functionality. Future LogicFlow support for BPMN will include full BPMN swimlane support. Contributions for implementations are welcome.
|
|
605
|
+
|
|
606
|
+
:::
|