@logicflow/extension 2.2.0-alpha.5 → 2.2.0-alpha.7
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +15 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/bpmn-elements-adapter/json2xml.d.ts +2 -1
- package/es/bpmn-elements-adapter/json2xml.js +18 -4
- package/es/bpmn-elements-adapter/xml2json.js +2 -7
- package/es/components/control/index.js +3 -3
- package/es/index.d.ts +1 -0
- package/es/index.js +2 -0
- package/es/materials/curved-edge/index.js +41 -25
- package/es/pool/LaneModel.d.ts +90 -0
- package/es/pool/LaneModel.js +252 -0
- package/es/pool/LaneView.d.ts +40 -0
- package/es/pool/LaneView.js +202 -0
- package/es/pool/PoolModel.d.ts +120 -0
- package/es/pool/PoolModel.js +586 -0
- package/es/pool/PoolView.d.ts +17 -0
- package/es/pool/PoolView.js +76 -0
- package/es/pool/constant.d.ts +15 -0
- package/es/pool/constant.js +17 -0
- package/es/pool/index.d.ts +89 -0
- package/es/pool/index.js +524 -0
- package/es/pool/utils.d.ts +19 -0
- package/es/pool/utils.js +33 -0
- package/lib/bpmn-elements-adapter/json2xml.d.ts +2 -1
- package/lib/bpmn-elements-adapter/json2xml.js +19 -4
- package/lib/bpmn-elements-adapter/xml2json.js +2 -7
- package/lib/components/control/index.js +3 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/materials/curved-edge/index.js +41 -25
- package/lib/pool/LaneModel.d.ts +90 -0
- package/lib/pool/LaneModel.js +255 -0
- package/lib/pool/LaneView.d.ts +40 -0
- package/lib/pool/LaneView.js +205 -0
- package/lib/pool/PoolModel.d.ts +120 -0
- package/lib/pool/PoolModel.js +589 -0
- package/lib/pool/PoolView.d.ts +17 -0
- package/lib/pool/PoolView.js +79 -0
- package/lib/pool/constant.d.ts +15 -0
- package/lib/pool/constant.js +20 -0
- package/lib/pool/index.d.ts +89 -0
- package/lib/pool/index.js +527 -0
- package/lib/pool/utils.d.ts +19 -0
- package/lib/pool/utils.js +38 -0
- package/package.json +5 -5
- package/src/bpmn-elements-adapter/json2xml.ts +18 -4
- package/src/bpmn-elements-adapter/xml2json.ts +2 -8
- package/src/components/control/index.ts +3 -3
- package/src/dynamic-group/index.ts +0 -1
- package/src/index.ts +2 -0
- package/src/materials/curved-edge/index.ts +47 -30
- package/src/pool/LaneModel.ts +226 -0
- package/src/pool/LaneView.ts +220 -0
- package/src/pool/PoolModel.ts +631 -0
- package/src/pool/PoolView.ts +75 -0
- package/src/pool/constant.ts +19 -0
- package/src/pool/index.ts +621 -0
- package/src/pool/utils.ts +46 -0
- package/stats.html +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const poolConfig: {
|
|
2
|
+
defaultWidth: number;
|
|
3
|
+
defaultHeight: number;
|
|
4
|
+
titleSize: number;
|
|
5
|
+
poolMinSize: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const laneConfig: {
|
|
8
|
+
defaultWidth: number;
|
|
9
|
+
defaultHeight: number;
|
|
10
|
+
titleSize: number;
|
|
11
|
+
iconSize: number;
|
|
12
|
+
iconSpacing: number;
|
|
13
|
+
};
|
|
14
|
+
declare const _default: null;
|
|
15
|
+
export default _default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// 泳池配置常量
|
|
2
|
+
export var poolConfig = {
|
|
3
|
+
// 默认尺寸
|
|
4
|
+
defaultWidth: 120,
|
|
5
|
+
defaultHeight: 120,
|
|
6
|
+
// 标题区域
|
|
7
|
+
titleSize: 60,
|
|
8
|
+
poolMinSize: 20,
|
|
9
|
+
};
|
|
10
|
+
export var laneConfig = {
|
|
11
|
+
defaultWidth: 120,
|
|
12
|
+
defaultHeight: 120,
|
|
13
|
+
titleSize: 20,
|
|
14
|
+
iconSize: 20,
|
|
15
|
+
iconSpacing: 15,
|
|
16
|
+
};
|
|
17
|
+
export default null;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import LogicFlow, { CallbackArgs, Model, BaseNodeModel, BaseEdgeModel } from '@logicflow/core';
|
|
2
|
+
import { PoolModel } from './PoolModel';
|
|
3
|
+
import { PoolView } from './PoolView';
|
|
4
|
+
import { LaneModel } from './LaneModel';
|
|
5
|
+
import { LaneView } from './LaneView';
|
|
6
|
+
import EdgeConfig = LogicFlow.EdgeConfig;
|
|
7
|
+
import EdgeData = LogicFlow.EdgeData;
|
|
8
|
+
import NodeData = LogicFlow.NodeData;
|
|
9
|
+
import BoxBoundsPoint = Model.BoxBoundsPoint;
|
|
10
|
+
type ElementsInfoInGroup = {
|
|
11
|
+
childNodes: BaseNodeModel[];
|
|
12
|
+
edgesData: EdgeData[];
|
|
13
|
+
};
|
|
14
|
+
export declare const PoolNode: {
|
|
15
|
+
type: string;
|
|
16
|
+
view: typeof PoolView;
|
|
17
|
+
model: typeof PoolModel;
|
|
18
|
+
};
|
|
19
|
+
export declare const LaneNode: {
|
|
20
|
+
type: string;
|
|
21
|
+
view: typeof LaneView;
|
|
22
|
+
model: typeof LaneModel;
|
|
23
|
+
};
|
|
24
|
+
export declare class PoolElements {
|
|
25
|
+
static pluginName: string;
|
|
26
|
+
private lf;
|
|
27
|
+
activeGroup?: LaneModel;
|
|
28
|
+
nodeLaneMap: Map<string, string>;
|
|
29
|
+
constructor({ lf, options }: LogicFlow.IExtensionProps);
|
|
30
|
+
/**
|
|
31
|
+
* 获取节点所属的泳道
|
|
32
|
+
* @param nodeId
|
|
33
|
+
*/
|
|
34
|
+
getLaneByNodeId(nodeId: string): BaseNodeModel<LogicFlow.PropertiesType> | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* 获取指定范围内的泳道
|
|
37
|
+
* 当泳道重合时,优先返回最上层的泳道
|
|
38
|
+
* @param bounds
|
|
39
|
+
* @param nodeData
|
|
40
|
+
*/
|
|
41
|
+
getLaneByBounds(bounds: BoxBoundsPoint, nodeData: NodeData): any | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* 提高元素的层级,如果是 group,同时提高其子元素的层级
|
|
44
|
+
* @param model
|
|
45
|
+
*/
|
|
46
|
+
onSelectionDrop: () => void;
|
|
47
|
+
onNodeAddOrDrop: ({ data: node }: CallbackArgs<'node:add'>) => void;
|
|
48
|
+
addNodeToGroup: (node: LogicFlow.NodeData) => void;
|
|
49
|
+
onGroupAddNode: ({ data: groupData, childId, }: CallbackArgs<'group:add-node'>) => void;
|
|
50
|
+
removeNodeFromGroup: ({ data: node, model, }: CallbackArgs<'node:delete'>) => void;
|
|
51
|
+
onSelectionDrag: () => void;
|
|
52
|
+
onNodeDrag: ({ data: node }: CallbackArgs<'node:drag'>) => void;
|
|
53
|
+
setActiveGroup: (node: LogicFlow.NodeData) => void;
|
|
54
|
+
/**
|
|
55
|
+
* @param node
|
|
56
|
+
* @param isMultiple
|
|
57
|
+
* @param isSelected
|
|
58
|
+
*/
|
|
59
|
+
onNodeSelect: ({ data: node, isMultiple, isSelected, }: Omit<CallbackArgs<'node:click'>, 'e' | 'position'>) => void;
|
|
60
|
+
onNodeMove: ({ deltaX, deltaY, data, }: Omit<CallbackArgs<'node:mousemove'>, 'e' | 'position'>) => void;
|
|
61
|
+
onGraphRendered: ({ data }: CallbackArgs<'graph:rendered'>) => void;
|
|
62
|
+
removeChildrenInGroupNodeData<T extends LogicFlow.NodeData | LogicFlow.NodeConfig>(nodeData: T): T;
|
|
63
|
+
/**
|
|
64
|
+
* 创建一个 Group 类型节点内部所有子节点的副本
|
|
65
|
+
* 并且在遍历所有 nodes 的过程中,顺便拿到所有 edges (只在 Group 范围的 edges)
|
|
66
|
+
*/
|
|
67
|
+
initGroupChildNodes(nodeIdMap: Record<string, string>, children: Set<string>, curGroup: LaneModel, distance: number): ElementsInfoInGroup;
|
|
68
|
+
/**
|
|
69
|
+
* 根据参数 edge 选择是新建边还是基于已有边,复制一条边出来
|
|
70
|
+
* @param edge
|
|
71
|
+
* @param nodeIdMap
|
|
72
|
+
* @param distance
|
|
73
|
+
*/
|
|
74
|
+
createEdge(edge: EdgeConfig | EdgeData, nodeIdMap: Record<string, string>, distance: number): BaseEdgeModel<LogicFlow.PropertiesType>;
|
|
75
|
+
/**
|
|
76
|
+
* 检测group:resize后的bounds是否会小于children的bounds
|
|
77
|
+
* 限制group进行resize时不能小于内部的占地面积
|
|
78
|
+
* @param groupModel
|
|
79
|
+
* @param deltaX
|
|
80
|
+
* @param deltaY
|
|
81
|
+
* @param newWidth
|
|
82
|
+
* @param newHeight
|
|
83
|
+
*/
|
|
84
|
+
checkGroupBoundsWithChildren(groupModel: LaneModel, deltaX: number, deltaY: number, newWidth: number, newHeight: number): boolean;
|
|
85
|
+
init(): void;
|
|
86
|
+
render(): void;
|
|
87
|
+
destroy(): void;
|
|
88
|
+
}
|
|
89
|
+
export default PoolElements;
|
package/es/pool/index.js
ADDED
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
13
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
14
|
+
if (!m) return o;
|
|
15
|
+
var i = m.call(o), r, ar = [], e;
|
|
16
|
+
try {
|
|
17
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
18
|
+
}
|
|
19
|
+
catch (error) { e = { error: error }; }
|
|
20
|
+
finally {
|
|
21
|
+
try {
|
|
22
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
23
|
+
}
|
|
24
|
+
finally { if (e) throw e.error; }
|
|
25
|
+
}
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
29
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
30
|
+
if (ar || !(i in from)) {
|
|
31
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
32
|
+
ar[i] = from[i];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
36
|
+
};
|
|
37
|
+
import { EventType, transformNodeData, transformEdgeData, } from '@logicflow/core';
|
|
38
|
+
import { assign, filter, forEach, cloneDeep, has, map } from 'lodash-es';
|
|
39
|
+
import { PoolModel } from './PoolModel';
|
|
40
|
+
import { PoolView } from './PoolView';
|
|
41
|
+
import { LaneModel } from './LaneModel';
|
|
42
|
+
import { LaneView } from './LaneView';
|
|
43
|
+
import { isAllowMoveTo, isBoundsInLane } from './utils';
|
|
44
|
+
export var PoolNode = {
|
|
45
|
+
type: 'pool',
|
|
46
|
+
view: PoolView,
|
|
47
|
+
model: PoolModel,
|
|
48
|
+
};
|
|
49
|
+
export var LaneNode = {
|
|
50
|
+
type: 'lane',
|
|
51
|
+
view: LaneView,
|
|
52
|
+
model: LaneModel,
|
|
53
|
+
};
|
|
54
|
+
var PoolElements = /** @class */ (function () {
|
|
55
|
+
function PoolElements(_a) {
|
|
56
|
+
var lf = _a.lf, options = _a.options;
|
|
57
|
+
var _this = this;
|
|
58
|
+
// 存储节点与 group 的映射关系
|
|
59
|
+
this.nodeLaneMap = new Map();
|
|
60
|
+
/**
|
|
61
|
+
* 提高元素的层级,如果是 group,同时提高其子元素的层级
|
|
62
|
+
* @param model
|
|
63
|
+
*/
|
|
64
|
+
this.onSelectionDrop = function () {
|
|
65
|
+
var selectedNodes = _this.lf.graphModel.getSelectElements().nodes;
|
|
66
|
+
selectedNodes.forEach(function (node) {
|
|
67
|
+
_this.addNodeToGroup(node);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
this.onNodeAddOrDrop = function (_a) {
|
|
71
|
+
var node = _a.data;
|
|
72
|
+
_this.addNodeToGroup(node);
|
|
73
|
+
};
|
|
74
|
+
this.addNodeToGroup = function (node) {
|
|
75
|
+
// 1. 如果该节点之前已经有泳道了,则将其从之前的泳道移除
|
|
76
|
+
var preLaneId = _this.nodeLaneMap.get(node.id);
|
|
77
|
+
if (preLaneId) {
|
|
78
|
+
var lane = _this.lf.getNodeModelById(preLaneId);
|
|
79
|
+
lane.removeChild(node.id);
|
|
80
|
+
_this.nodeLaneMap.delete(node.id);
|
|
81
|
+
lane.setAllowAppendChild(false);
|
|
82
|
+
}
|
|
83
|
+
// 2. 然后再判断这个节点是否在某个泳道范围内,如果是,则将其添加到对应的泳道中
|
|
84
|
+
var nodeModel = _this.lf.getNodeModelById(node.id);
|
|
85
|
+
var bounds = nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.getBounds();
|
|
86
|
+
if (nodeModel && bounds) {
|
|
87
|
+
// TODO: 确认下面的注释内容
|
|
88
|
+
// https://github.com/didi/LogicFlow/issues/1261
|
|
89
|
+
// 当使用 SelectionSelect 框选后触发 lf.addNode(Group)
|
|
90
|
+
// 会触发 appendNodeToGroup() 的执行
|
|
91
|
+
// 由于 this.getGroup() 会判断 node.id !== nodeData.id
|
|
92
|
+
// 因此当 addNode 是 Group 类型时,this.getGroup() 会一直返回空
|
|
93
|
+
// 导致了下面这段代码无法执行,也就是无法将当前添加的 Group 添加到 this.nodeLaneMap 中
|
|
94
|
+
// 这导致了折叠分组时触发的 foldEdge() 无法正确通过 getNodeGroup() 拿到正确的 groupId
|
|
95
|
+
// 从而导致折叠分组时一直都会创建一个虚拟边
|
|
96
|
+
// 而初始化分组时由于正确设置了nodeLaneMap的数据,因此不会产生虚拟边的错误情况
|
|
97
|
+
if (nodeModel.isGroup) {
|
|
98
|
+
var lane_1 = nodeModel;
|
|
99
|
+
forEach(Array.from(lane_1.children), function (childId) {
|
|
100
|
+
_this.nodeLaneMap.set(childId, node.id);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
var lane = _this.getLaneByBounds(bounds, node);
|
|
104
|
+
if (lane) {
|
|
105
|
+
var isAllowAppendIn = lane.isAllowAppendIn(node);
|
|
106
|
+
if (isAllowAppendIn) {
|
|
107
|
+
lane.addChild(node.id);
|
|
108
|
+
// 建立节点与 lane 的映射关系放在了 lane.addChild 触发的事件中,与直接调用 addChild 的行为保持一致
|
|
109
|
+
lane.setAllowAppendChild(false);
|
|
110
|
+
var nodeModel_1 = _this.lf.getNodeModelById(node.id);
|
|
111
|
+
nodeModel_1 === null || nodeModel_1 === void 0 ? void 0 : nodeModel_1.setProperties(__assign(__assign({}, nodeModel_1.properties), { parent: lane.id }));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// 抛出不允许插入的事件
|
|
115
|
+
_this.lf.emit('lane:not-allowed', {
|
|
116
|
+
lane: lane.getData(),
|
|
117
|
+
node: node,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
this.onGroupAddNode = function (_a) {
|
|
124
|
+
var groupData = _a.data, childId = _a.childId;
|
|
125
|
+
_this.nodeLaneMap.set(childId, groupData.id);
|
|
126
|
+
};
|
|
127
|
+
this.removeNodeFromGroup = function (_a) {
|
|
128
|
+
var node = _a.data, model = _a.model;
|
|
129
|
+
if (model.isGroup && node.children) {
|
|
130
|
+
forEach(Array.from(node.children), function (childId) {
|
|
131
|
+
_this.nodeLaneMap.delete(childId);
|
|
132
|
+
_this.lf.deleteNode(childId);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var laneId = _this.nodeLaneMap.get(node.id);
|
|
136
|
+
if (laneId) {
|
|
137
|
+
var lane = _this.lf.getNodeModelById(laneId);
|
|
138
|
+
lane && lane.removeChild(node.id);
|
|
139
|
+
_this.nodeLaneMap.delete(node.id);
|
|
140
|
+
var nodeModel = _this.lf.getNodeModelById(node.id);
|
|
141
|
+
// 移除时删除properties中的parent和relativeDistanceX、relativeDistanceY
|
|
142
|
+
var newProperties = __assign(__assign({}, nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.properties), { parent: undefined, relativeDistanceX: undefined, relativeDistanceY: undefined });
|
|
143
|
+
nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.setProperties(newProperties);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
this.onSelectionDrag = function () {
|
|
147
|
+
var selectedNodes = _this.lf.graphModel.getSelectElements().nodes;
|
|
148
|
+
selectedNodes.forEach(function (node) {
|
|
149
|
+
_this.setActiveGroup(node);
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
this.onNodeDrag = function (_a) {
|
|
153
|
+
var node = _a.data;
|
|
154
|
+
_this.setActiveGroup(node);
|
|
155
|
+
};
|
|
156
|
+
this.setActiveGroup = function (node) {
|
|
157
|
+
var _a;
|
|
158
|
+
var nodeModel = _this.lf.getNodeModelById(node.id);
|
|
159
|
+
var bounds = nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.getBounds();
|
|
160
|
+
if (nodeModel && bounds) {
|
|
161
|
+
var targetGroup = _this.getLaneByBounds(bounds, node);
|
|
162
|
+
if (_this.activeGroup) {
|
|
163
|
+
_this.activeGroup.setAllowAppendChild(false);
|
|
164
|
+
}
|
|
165
|
+
if (!targetGroup || (nodeModel.isGroup && targetGroup.id === node.id)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
var isAllowAppendIn = targetGroup.isAllowAppendIn(node);
|
|
169
|
+
if (!isAllowAppendIn)
|
|
170
|
+
return;
|
|
171
|
+
_this.activeGroup = targetGroup;
|
|
172
|
+
(_a = _this.activeGroup) === null || _a === void 0 ? void 0 : _a.setAllowAppendChild(true);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* @param node
|
|
177
|
+
* @param isMultiple
|
|
178
|
+
* @param isSelected
|
|
179
|
+
*/
|
|
180
|
+
this.onNodeSelect = function (_a) {
|
|
181
|
+
var node = _a.data, isMultiple = _a.isMultiple, isSelected = _a.isSelected;
|
|
182
|
+
var nodeModel = _this.lf.getNodeModelById(node.id);
|
|
183
|
+
// FIX #1004
|
|
184
|
+
// 如果节点被多选,
|
|
185
|
+
// 这个节点是分组,则将分组的所有子节点取消选中
|
|
186
|
+
// 这个节点是分组的子节点,且其所属分组节点已选,则取消选中
|
|
187
|
+
if (isMultiple && isSelected) {
|
|
188
|
+
if (nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.isGroup) {
|
|
189
|
+
var children = nodeModel.children;
|
|
190
|
+
forEach(Array.from(children), function (childId) {
|
|
191
|
+
var childModel = _this.lf.getNodeModelById(childId);
|
|
192
|
+
childModel === null || childModel === void 0 ? void 0 : childModel.setSelected(false);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
var laneId = _this.nodeLaneMap.get(node.id);
|
|
197
|
+
if (laneId) {
|
|
198
|
+
var laneModel = _this.lf.getNodeModelById(laneId);
|
|
199
|
+
(laneModel === null || laneModel === void 0 ? void 0 : laneModel.isSelected) && (nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.setSelected(false));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
this.onNodeMove = function (_a) {
|
|
205
|
+
var deltaX = _a.deltaX, deltaY = _a.deltaY, data = _a.data;
|
|
206
|
+
var id = data.id, x = data.x, y = data.y, properties = data.properties;
|
|
207
|
+
if (!properties) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
var width = properties.width, height = properties.height;
|
|
211
|
+
var groupId = _this.nodeLaneMap.get(id);
|
|
212
|
+
if (!groupId) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
var groupModel = _this.lf.getNodeModelById(groupId);
|
|
216
|
+
if (!groupModel || !groupModel.isRestrict || !groupModel.autoResize) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// 当父节点isRestrict=true & autoResize=true
|
|
220
|
+
// 子节点在父节点中移动时,父节点会自动调整大小
|
|
221
|
+
// step1: 计算出当前child的bounds
|
|
222
|
+
var newX = x + deltaX / 2;
|
|
223
|
+
var newY = y + deltaY / 2;
|
|
224
|
+
var minX = newX - width / 2;
|
|
225
|
+
var minY = newY - height / 2;
|
|
226
|
+
var maxX = newX + width / 2;
|
|
227
|
+
var maxY = newY + height / 2;
|
|
228
|
+
// step2:比较当前child.bounds与parent.bounds的差异,比如child.minX<parent.minX,那么parent.minX=child.minX
|
|
229
|
+
var hasChange = false;
|
|
230
|
+
var groupBounds = groupModel.getBounds();
|
|
231
|
+
var newGroupBounds = Object.assign({}, groupBounds);
|
|
232
|
+
if (minX < newGroupBounds.minX) {
|
|
233
|
+
newGroupBounds.minX = minX;
|
|
234
|
+
hasChange = true;
|
|
235
|
+
}
|
|
236
|
+
if (minY < newGroupBounds.minY) {
|
|
237
|
+
newGroupBounds.minY = minY;
|
|
238
|
+
hasChange = true;
|
|
239
|
+
}
|
|
240
|
+
if (maxX > newGroupBounds.maxX) {
|
|
241
|
+
newGroupBounds.maxX = maxX;
|
|
242
|
+
hasChange = true;
|
|
243
|
+
}
|
|
244
|
+
if (maxY > newGroupBounds.maxY) {
|
|
245
|
+
newGroupBounds.maxY = maxY;
|
|
246
|
+
hasChange = true;
|
|
247
|
+
}
|
|
248
|
+
if (!hasChange) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// step3: 根据当前parent.bounds去计算出最新的x、y、width、height
|
|
252
|
+
var newGroupX = newGroupBounds.minX + (newGroupBounds.maxX - newGroupBounds.minX) / 2;
|
|
253
|
+
var newGroupY = newGroupBounds.minY + (newGroupBounds.maxY - newGroupBounds.minY) / 2;
|
|
254
|
+
var newGroupWidth = newGroupBounds.maxX - newGroupBounds.minX;
|
|
255
|
+
var newGroupHeight = newGroupBounds.maxY - newGroupBounds.minY;
|
|
256
|
+
groupModel.moveTo(newGroupX, newGroupY);
|
|
257
|
+
groupModel.width = newGroupWidth;
|
|
258
|
+
groupModel.height = newGroupHeight;
|
|
259
|
+
};
|
|
260
|
+
this.onGraphRendered = function (_a) {
|
|
261
|
+
var data = _a.data;
|
|
262
|
+
forEach(data.nodes, function (node) {
|
|
263
|
+
if (node.children) {
|
|
264
|
+
forEach(node.children, function (childId) {
|
|
265
|
+
_this.nodeLaneMap.set(childId, node.id);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
lf.register(PoolNode);
|
|
271
|
+
lf.register(LaneNode);
|
|
272
|
+
this.lf = lf;
|
|
273
|
+
assign(this, options);
|
|
274
|
+
// 初始化插件,从监听事件开始及设置规则开始
|
|
275
|
+
this.init();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* 获取节点所属的泳道
|
|
279
|
+
* @param nodeId
|
|
280
|
+
*/
|
|
281
|
+
PoolElements.prototype.getLaneByNodeId = function (nodeId) {
|
|
282
|
+
var laneId = this.nodeLaneMap.get(nodeId);
|
|
283
|
+
if (laneId) {
|
|
284
|
+
return this.lf.getNodeModelById(laneId);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* 获取指定范围内的泳道
|
|
289
|
+
* 当泳道重合时,优先返回最上层的泳道
|
|
290
|
+
* @param bounds
|
|
291
|
+
* @param nodeData
|
|
292
|
+
*/
|
|
293
|
+
PoolElements.prototype.getLaneByBounds = function (bounds, nodeData) {
|
|
294
|
+
var nodes = this.lf.graphModel.nodes;
|
|
295
|
+
var lanes = filter(nodes, function (node) {
|
|
296
|
+
return (!!node.isGroup &&
|
|
297
|
+
isBoundsInLane(bounds, node) &&
|
|
298
|
+
node.id !== nodeData.id);
|
|
299
|
+
});
|
|
300
|
+
var count = lanes.length;
|
|
301
|
+
if (count <= 1) {
|
|
302
|
+
return lanes[0];
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
var topZIndexLane = lanes[count - 1];
|
|
306
|
+
for (var i = count - 2; i >= 0; i--) {
|
|
307
|
+
if (lanes[i].zIndex > topZIndexLane.zIndex) {
|
|
308
|
+
topZIndexLane = lanes[i];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return topZIndexLane;
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
PoolElements.prototype.removeChildrenInGroupNodeData = function (nodeData) {
|
|
315
|
+
var _a;
|
|
316
|
+
var newNodeData = cloneDeep(nodeData);
|
|
317
|
+
delete newNodeData.children;
|
|
318
|
+
if ((_a = newNodeData.properties) === null || _a === void 0 ? void 0 : _a.children) {
|
|
319
|
+
delete newNodeData.properties.children;
|
|
320
|
+
}
|
|
321
|
+
return newNodeData;
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* 创建一个 Group 类型节点内部所有子节点的副本
|
|
325
|
+
* 并且在遍历所有 nodes 的过程中,顺便拿到所有 edges (只在 Group 范围的 edges)
|
|
326
|
+
*/
|
|
327
|
+
PoolElements.prototype.initGroupChildNodes = function (nodeIdMap, children, curGroup, distance) {
|
|
328
|
+
var _this = this;
|
|
329
|
+
// Group 中所有子节点
|
|
330
|
+
var allChildNodes = [];
|
|
331
|
+
// 属于 Group 内部边的 EdgeData
|
|
332
|
+
var edgesDataArr = [];
|
|
333
|
+
// 所有有关联的连线
|
|
334
|
+
var allRelatedEdges = [];
|
|
335
|
+
forEach(Array.from(children), function (childId) {
|
|
336
|
+
var childNode = _this.lf.getNodeModelById(childId);
|
|
337
|
+
if (childNode) {
|
|
338
|
+
var childNodeChildren = childNode.children;
|
|
339
|
+
var childNodeData = childNode.getData();
|
|
340
|
+
var eventType = EventType.NODE_GROUP_COPY || 'node:group-copy-add';
|
|
341
|
+
var newNodeConfig = transformNodeData(_this.removeChildrenInGroupNodeData(childNodeData), distance);
|
|
342
|
+
var tempChildNode = _this.lf.addNode(newNodeConfig, eventType);
|
|
343
|
+
curGroup.addChild(tempChildNode.id);
|
|
344
|
+
nodeIdMap[childId] = tempChildNode.id; // id 同 childId,做映射存储
|
|
345
|
+
allChildNodes.push(tempChildNode);
|
|
346
|
+
// 1. 存储 children 内部节点相关的输入边(incoming)
|
|
347
|
+
allRelatedEdges.push.apply(allRelatedEdges, __spreadArray([], __read(__spreadArray(__spreadArray([], __read(tempChildNode.incoming.edges), false), __read(tempChildNode.outgoing.edges), false)), false));
|
|
348
|
+
if (childNodeChildren instanceof Set) {
|
|
349
|
+
var _a = _this.initGroupChildNodes(nodeIdMap, childNodeChildren, tempChildNode, distance), childNodes = _a.childNodes, edgesData = _a.edgesData;
|
|
350
|
+
allChildNodes.push.apply(allChildNodes, __spreadArray([], __read(childNodes), false));
|
|
351
|
+
edgesDataArr.push.apply(edgesDataArr, __spreadArray([], __read(edgesData), false));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
// 1. 判断每一条边的开始节点、目标节点是否在 Group 中
|
|
356
|
+
var edgesInnerGroup = filter(allRelatedEdges, function (edge) {
|
|
357
|
+
return (has(nodeIdMap, edge.sourceNodeId) && has(nodeIdMap, edge.targetNodeId));
|
|
358
|
+
});
|
|
359
|
+
// 2. 为「每一条 Group 的内部边」构建出 EdgeData 数据,得到 EdgeConfig,生成新的线
|
|
360
|
+
var edgesDataInnerGroup = map(edgesInnerGroup, function (edge) {
|
|
361
|
+
return edge.getData();
|
|
362
|
+
});
|
|
363
|
+
return {
|
|
364
|
+
childNodes: allChildNodes,
|
|
365
|
+
edgesData: edgesDataArr.concat(edgesDataInnerGroup),
|
|
366
|
+
};
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* 根据参数 edge 选择是新建边还是基于已有边,复制一条边出来
|
|
370
|
+
* @param edge
|
|
371
|
+
* @param nodeIdMap
|
|
372
|
+
* @param distance
|
|
373
|
+
*/
|
|
374
|
+
PoolElements.prototype.createEdge = function (edge, nodeIdMap, distance) {
|
|
375
|
+
var _a, _b;
|
|
376
|
+
var sourceNodeId = edge.sourceNodeId, targetNodeId = edge.targetNodeId;
|
|
377
|
+
var sourceId = (_a = nodeIdMap[sourceNodeId]) !== null && _a !== void 0 ? _a : sourceNodeId;
|
|
378
|
+
var targetId = (_b = nodeIdMap[targetNodeId]) !== null && _b !== void 0 ? _b : targetNodeId;
|
|
379
|
+
// 如果是有 id 且 text 是对象的边,需要重新计算位置,否则直接用 edgeConfig 生成边
|
|
380
|
+
var newEdgeConfig = cloneDeep(edge);
|
|
381
|
+
if (edge.id && typeof edge.text === 'object' && edge.text !== null) {
|
|
382
|
+
newEdgeConfig = transformEdgeData(edge, distance);
|
|
383
|
+
}
|
|
384
|
+
return this.lf.graphModel.addEdge(__assign(__assign({}, newEdgeConfig), { sourceNodeId: sourceId, targetNodeId: targetId }));
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* 检测group:resize后的bounds是否会小于children的bounds
|
|
388
|
+
* 限制group进行resize时不能小于内部的占地面积
|
|
389
|
+
* @param groupModel
|
|
390
|
+
* @param deltaX
|
|
391
|
+
* @param deltaY
|
|
392
|
+
* @param newWidth
|
|
393
|
+
* @param newHeight
|
|
394
|
+
*/
|
|
395
|
+
PoolElements.prototype.checkGroupBoundsWithChildren = function (groupModel, deltaX, deltaY, newWidth, newHeight) {
|
|
396
|
+
if (groupModel.children) {
|
|
397
|
+
var children = groupModel.children, x = groupModel.x, y = groupModel.y;
|
|
398
|
+
// 根据deltaX和deltaY计算出当前model的bounds
|
|
399
|
+
var newX = x + deltaX / 2;
|
|
400
|
+
var newY = y + deltaY / 2;
|
|
401
|
+
var groupMinX = newX - newWidth / 2;
|
|
402
|
+
var groupMinY = newY - newHeight / 2;
|
|
403
|
+
var groupMaxX = newX + newWidth / 2;
|
|
404
|
+
var groupMaxY = newY + newHeight / 2;
|
|
405
|
+
var childrenArray = Array.from(children);
|
|
406
|
+
for (var i = 0; i < childrenArray.length; i++) {
|
|
407
|
+
var childId = childrenArray[i];
|
|
408
|
+
var child = this.lf.getNodeModelById(childId);
|
|
409
|
+
if (!child) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
var childBounds = child.getBounds();
|
|
413
|
+
var minX = childBounds.minX, minY = childBounds.minY, maxX = childBounds.maxX, maxY = childBounds.maxY;
|
|
414
|
+
// parent:resize后的bounds不能小于child:bounds,否则阻止其resize
|
|
415
|
+
var canResize = groupMinX <= minX &&
|
|
416
|
+
groupMinY <= minY &&
|
|
417
|
+
groupMaxX >= maxX &&
|
|
418
|
+
groupMaxY >= maxY;
|
|
419
|
+
if (!canResize) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return true;
|
|
425
|
+
};
|
|
426
|
+
PoolElements.prototype.init = function () {
|
|
427
|
+
var _this = this;
|
|
428
|
+
var lf = this.lf;
|
|
429
|
+
var graphModel = lf.graphModel;
|
|
430
|
+
// 添加分组节点移动规则
|
|
431
|
+
// 1. 移动分组节点时,同时移动分组内所有节点
|
|
432
|
+
// 2. 移动子节点时,判断是否有限制规则(isRestrict)
|
|
433
|
+
graphModel.addNodeMoveRules(function (model, deltaX, deltaY) {
|
|
434
|
+
// 判断如果是 group,移动时需要同时移动组内的所有节点
|
|
435
|
+
if (model.isGroup) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
var groupId = _this.nodeLaneMap.get(model.id);
|
|
439
|
+
var groupModel = _this.lf.getNodeModelById(groupId);
|
|
440
|
+
if (groupModel && groupModel.isRestrict) {
|
|
441
|
+
if (groupModel.autoResize) {
|
|
442
|
+
// 子节点在父节点中移动时,父节点会自动调整大小
|
|
443
|
+
// 在node:mousemove中进行父节点的调整
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
// 如果移动的节点存在于某个分组中,且这个分组禁止子节点移出去
|
|
448
|
+
var groupBounds = groupModel.getBounds();
|
|
449
|
+
return isAllowMoveTo(groupBounds, model, deltaX, deltaY);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return true;
|
|
453
|
+
});
|
|
454
|
+
graphModel.addNodeResizeRules(function (model, deltaX, deltaY, width, height) {
|
|
455
|
+
if (model.isGroup && model.isRestrict) {
|
|
456
|
+
return _this.checkGroupBoundsWithChildren(model, deltaX, deltaY, width, height);
|
|
457
|
+
}
|
|
458
|
+
return true;
|
|
459
|
+
});
|
|
460
|
+
graphModel.dynamicGroup = this;
|
|
461
|
+
lf.on('node:add,node:drop,node:dnd-add', this.onNodeAddOrDrop);
|
|
462
|
+
lf.on('selection:drop', this.onSelectionDrop);
|
|
463
|
+
lf.on('node:delete', this.removeNodeFromGroup);
|
|
464
|
+
lf.on('node:drag,node:dnd-drag', this.onNodeDrag);
|
|
465
|
+
lf.on('selection:drag', this.onSelectionDrag);
|
|
466
|
+
lf.on('node:click', this.onNodeSelect);
|
|
467
|
+
lf.on('node:mousemove', this.onNodeMove);
|
|
468
|
+
lf.on('graph:rendered', this.onGraphRendered);
|
|
469
|
+
lf.on('group:add-node', this.onGroupAddNode);
|
|
470
|
+
lf.addElements = function (_a, distance) {
|
|
471
|
+
var selectedNodes = _a.nodes, selectedEdges = _a.edges;
|
|
472
|
+
if (distance === void 0) { distance = 40; }
|
|
473
|
+
// oldNodeId -> newNodeId 映射 Map
|
|
474
|
+
var nodeIdMap = {};
|
|
475
|
+
// 本次添加的所有节点和边
|
|
476
|
+
var elements = {
|
|
477
|
+
nodes: [],
|
|
478
|
+
edges: [],
|
|
479
|
+
};
|
|
480
|
+
// 所有属于分组内的边 -> sourceNodeId 和 targetNodeId 都在 Group 内
|
|
481
|
+
var edgesInnerGroup = [];
|
|
482
|
+
forEach(selectedNodes, function (node) {
|
|
483
|
+
var _a, _b;
|
|
484
|
+
var originId = node.id;
|
|
485
|
+
var children = (_b = (_a = node.properties) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : node.children;
|
|
486
|
+
var model = lf.addNode(_this.removeChildrenInGroupNodeData(node));
|
|
487
|
+
if (originId)
|
|
488
|
+
nodeIdMap[originId] = model.id;
|
|
489
|
+
elements.nodes.push(model); // 此时为 group 的 nodeModel
|
|
490
|
+
if (model.isGroup) {
|
|
491
|
+
var edgesData = _this.initGroupChildNodes(nodeIdMap, children, model, distance).edgesData;
|
|
492
|
+
edgesInnerGroup.push.apply(edgesInnerGroup, __spreadArray([], __read(edgesData), false));
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
forEach(edgesInnerGroup, function (edge) {
|
|
496
|
+
_this.createEdge(edge, nodeIdMap, distance);
|
|
497
|
+
});
|
|
498
|
+
forEach(selectedEdges, function (edge) {
|
|
499
|
+
elements.edges.push(_this.createEdge(edge, nodeIdMap, distance));
|
|
500
|
+
});
|
|
501
|
+
// 返回 elements 进行选中效果,即触发 element.selectElementById()
|
|
502
|
+
// shortcut.ts 也会对最外层的 nodes 和 edges 进行偏移,即 translationNodeData()
|
|
503
|
+
return elements;
|
|
504
|
+
};
|
|
505
|
+
this.render();
|
|
506
|
+
};
|
|
507
|
+
PoolElements.prototype.render = function () { };
|
|
508
|
+
PoolElements.prototype.destroy = function () {
|
|
509
|
+
// 销毁监听的事件,并移除渲染的 dom 内容
|
|
510
|
+
this.lf.off('node:add,node:drop,node:dnd-add', this.onNodeAddOrDrop);
|
|
511
|
+
this.lf.off('selection:drop', this.onSelectionDrop);
|
|
512
|
+
this.lf.off('node:delete', this.removeNodeFromGroup);
|
|
513
|
+
this.lf.off('node:drag,node:dnd-drag', this.onNodeDrag);
|
|
514
|
+
this.lf.off('selection:drag', this.onSelectionDrag);
|
|
515
|
+
this.lf.off('node:click', this.onNodeSelect);
|
|
516
|
+
this.lf.off('node:mousemove', this.onNodeMove);
|
|
517
|
+
this.lf.off('graph:rendered', this.onGraphRendered);
|
|
518
|
+
this.lf.off('group:add-node', this.onGroupAddNode);
|
|
519
|
+
};
|
|
520
|
+
PoolElements.pluginName = 'PoolElements';
|
|
521
|
+
return PoolElements;
|
|
522
|
+
}());
|
|
523
|
+
export { PoolElements };
|
|
524
|
+
export default PoolElements;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseNodeModel, Model } from '@logicflow/core';
|
|
2
|
+
import BoxBoundsPoint = Model.BoxBoundsPoint;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param bounds
|
|
6
|
+
* @param group
|
|
7
|
+
*/
|
|
8
|
+
export declare function isBoundsInLane(bounds: BoxBoundsPoint, group: BaseNodeModel): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 判断 bounds 是否可以移动到下一个范围
|
|
11
|
+
* @param groupBounds
|
|
12
|
+
* @param node
|
|
13
|
+
* @param deltaX
|
|
14
|
+
* @param deltaY
|
|
15
|
+
*/
|
|
16
|
+
export declare function isAllowMoveTo(groupBounds: BoxBoundsPoint, node: BaseNodeModel, deltaX: number, deltaY: number): {
|
|
17
|
+
x: boolean;
|
|
18
|
+
y: boolean;
|
|
19
|
+
};
|