@logicflow/extension 2.0.15 → 2.0.17
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 +18 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/components/menu/index.js +12 -0
- package/es/components/selection-select/index.d.ts +27 -3
- package/es/components/selection-select/index.js +236 -62
- package/es/dynamic-group/index.d.ts +6 -2
- package/es/dynamic-group/index.js +29 -18
- package/es/materials/group/GroupNode.js +0 -1
- package/lib/components/menu/index.js +12 -0
- package/lib/components/selection-select/index.d.ts +27 -3
- package/lib/components/selection-select/index.js +236 -62
- package/lib/dynamic-group/index.d.ts +6 -2
- package/lib/dynamic-group/index.js +29 -18
- package/lib/materials/group/GroupNode.js +0 -1
- package/package.json +3 -3
- package/src/components/menu/index.ts +4 -1
- package/src/components/selection-select/index.ts +238 -60
- package/src/dynamic-group/index.ts +32 -18
- package/src/materials/group/GroupNode.ts +0 -1
- package/stats.html +1 -1
|
@@ -1,3 +1,14 @@
|
|
|
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
|
+
};
|
|
1
12
|
var __read = (this && this.__read) || function (o, n) {
|
|
2
13
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
3
14
|
if (!m) return o;
|
|
@@ -205,6 +216,7 @@ var Menu = /** @class */ (function () {
|
|
|
205
216
|
var position = _a.position;
|
|
206
217
|
var menuList = (_c = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultGraphMenuKey)) !== null && _c !== void 0 ? _c : [];
|
|
207
218
|
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
219
|
+
_this.__currentData = __assign({}, position.canvasOverlayPosition);
|
|
208
220
|
_this.showMenu(x, y, menuList);
|
|
209
221
|
});
|
|
210
222
|
this.lf.on('selection:contextmenu', function (_a) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import LogicFlow from '@logicflow/core';
|
|
2
|
+
export interface SelectionConfig {
|
|
3
|
+
exclusiveMode?: boolean;
|
|
4
|
+
}
|
|
2
5
|
export declare class SelectionSelect {
|
|
3
6
|
static pluginName: string;
|
|
4
7
|
private container?;
|
|
@@ -7,11 +10,32 @@ export declare class SelectionSelect {
|
|
|
7
10
|
private startPoint?;
|
|
8
11
|
private endPoint?;
|
|
9
12
|
private disabled;
|
|
10
|
-
private isDefaultStopMoveGraph;
|
|
11
13
|
private isWholeNode;
|
|
12
14
|
private isWholeEdge;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
exclusiveMode: boolean;
|
|
16
|
+
private mouseDownInfo;
|
|
17
|
+
private originalStopMoveGraph;
|
|
18
|
+
constructor({ lf, options }: LogicFlow.IExtensionProps);
|
|
19
|
+
render(_: LogicFlow, domContainer: HTMLElement): void;
|
|
20
|
+
/**
|
|
21
|
+
* 清理选区状态
|
|
22
|
+
*/
|
|
23
|
+
private cleanupSelectionState;
|
|
24
|
+
/**
|
|
25
|
+
* 切换框选模式
|
|
26
|
+
* @param exclusive 是否为独占模式。true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
|
|
27
|
+
*/
|
|
28
|
+
setExclusiveMode(exclusive?: boolean): void;
|
|
29
|
+
private addEventListeners;
|
|
30
|
+
private removeEventListeners;
|
|
31
|
+
/**
|
|
32
|
+
* 处理画布空白处鼠标按下事件(非独占模式)
|
|
33
|
+
*/
|
|
34
|
+
private handleBlankMouseDown;
|
|
35
|
+
/**
|
|
36
|
+
* 处理鼠标按下事件
|
|
37
|
+
*/
|
|
38
|
+
private handleMouseDown;
|
|
15
39
|
/**
|
|
16
40
|
* 设置选中的灵敏度
|
|
17
41
|
* @param isWholeEdge 是否要边的起点终点都在选区范围才算选中。默认true
|
|
@@ -1,11 +1,49 @@
|
|
|
1
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
2
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
3
|
+
if (!m) return o;
|
|
4
|
+
var i = m.call(o), r, ar = [], e;
|
|
5
|
+
try {
|
|
6
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
7
|
+
}
|
|
8
|
+
catch (error) { e = { error: error }; }
|
|
9
|
+
finally {
|
|
10
|
+
try {
|
|
11
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
12
|
+
}
|
|
13
|
+
finally { if (e) throw e.error; }
|
|
14
|
+
}
|
|
15
|
+
return ar;
|
|
16
|
+
};
|
|
17
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
18
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
19
|
+
if (ar || !(i in from)) {
|
|
20
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
21
|
+
ar[i] = from[i];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
25
|
+
};
|
|
26
|
+
import { cloneDeep } from 'lodash-es';
|
|
1
27
|
var SelectionSelect = /** @class */ (function () {
|
|
2
28
|
function SelectionSelect(_a) {
|
|
3
|
-
var lf = _a.lf;
|
|
29
|
+
var lf = _a.lf, options = _a.options;
|
|
4
30
|
var _this = this;
|
|
31
|
+
var _b;
|
|
5
32
|
this.disabled = true;
|
|
6
|
-
this.isDefaultStopMoveGraph = false;
|
|
7
33
|
this.isWholeNode = true;
|
|
8
34
|
this.isWholeEdge = true;
|
|
35
|
+
this.exclusiveMode = false; // 框选独占模式:true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
|
|
36
|
+
// 用于区分选区和点击事件
|
|
37
|
+
this.mouseDownInfo = null;
|
|
38
|
+
// 记录原始的 stopMoveGraph 设置
|
|
39
|
+
this.originalStopMoveGraph = false;
|
|
40
|
+
/**
|
|
41
|
+
* 处理画布空白处鼠标按下事件(非独占模式)
|
|
42
|
+
*/
|
|
43
|
+
this.handleBlankMouseDown = function (_a) {
|
|
44
|
+
var e = _a.e;
|
|
45
|
+
_this.handleMouseDown(e);
|
|
46
|
+
};
|
|
9
47
|
this.draw = function (ev) {
|
|
10
48
|
var _a = _this.lf.getPointByClient(ev.clientX, ev.clientY).domOverlayPosition, x1 = _a.x, y1 = _a.y;
|
|
11
49
|
_this.endPoint = {
|
|
@@ -34,17 +72,33 @@ var SelectionSelect = /** @class */ (function () {
|
|
|
34
72
|
}
|
|
35
73
|
}
|
|
36
74
|
};
|
|
37
|
-
this.drawOff = function () {
|
|
38
|
-
|
|
75
|
+
this.drawOff = function (e) {
|
|
76
|
+
// 处理鼠标抬起事件
|
|
77
|
+
// 首先判断是否是点击,如果是,则清空框选
|
|
78
|
+
if (_this.mouseDownInfo) {
|
|
79
|
+
var _a = _this.mouseDownInfo, x = _a.x, y = _a.y, time = _a.time;
|
|
80
|
+
var isClick = Math.abs(e.clientX - x) < 5 &&
|
|
81
|
+
Math.abs(e.clientY - y) < 5 &&
|
|
82
|
+
Date.now() - time < 200;
|
|
83
|
+
if (isClick) {
|
|
84
|
+
_this.lf.clearSelectElements();
|
|
85
|
+
_this.cleanupSelectionState();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var curStartPoint = cloneDeep(_this.startPoint);
|
|
90
|
+
var curEndPoint = cloneDeep(_this.endPoint);
|
|
39
91
|
document.removeEventListener('mousemove', _this.draw);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
_this.wrapper.oncontextmenu = null;
|
|
43
|
-
(_a = _this.container) === null || _a === void 0 ? void 0 : _a.removeChild(_this.wrapper);
|
|
92
|
+
if (!_this.exclusiveMode) {
|
|
93
|
+
document.removeEventListener('mouseup', _this.drawOff);
|
|
44
94
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
95
|
+
// 恢复原始的 stopMoveGraph 设置
|
|
96
|
+
_this.lf.updateEditConfig({
|
|
97
|
+
stopMoveGraph: _this.originalStopMoveGraph,
|
|
98
|
+
});
|
|
99
|
+
if (curStartPoint && curEndPoint) {
|
|
100
|
+
var x = curStartPoint.x, y = curStartPoint.y;
|
|
101
|
+
var x1 = curEndPoint.x, y1 = curEndPoint.y;
|
|
48
102
|
// 返回框选范围,左上角和右下角的坐标
|
|
49
103
|
var lt = [Math.min(x, x1), Math.min(y, y1)];
|
|
50
104
|
var rb = [Math.max(x, x1), Math.max(y, y1)];
|
|
@@ -54,33 +108,71 @@ var SelectionSelect = /** @class */ (function () {
|
|
|
54
108
|
});
|
|
55
109
|
// 选区太小的情况就忽略
|
|
56
110
|
if (Math.abs(x1 - x) < 10 && Math.abs(y1 - y) < 10) {
|
|
111
|
+
if (_this.wrapper) {
|
|
112
|
+
_this.wrapper.oncontextmenu = null;
|
|
113
|
+
if (_this.container && _this.wrapper.parentNode === _this.container) {
|
|
114
|
+
_this.container.removeChild(_this.wrapper);
|
|
115
|
+
}
|
|
116
|
+
_this.wrapper = undefined;
|
|
117
|
+
}
|
|
57
118
|
return;
|
|
58
119
|
}
|
|
59
|
-
var
|
|
60
|
-
var
|
|
120
|
+
var elements_1 = _this.lf.graphModel.getAreaElement(lt, rb, _this.isWholeEdge, _this.isWholeNode, true);
|
|
121
|
+
var _b = _this.lf.graphModel, dynamicGroup_1 = _b.dynamicGroup, group_1 = _b.group;
|
|
61
122
|
var nonGroupedElements_1 = [];
|
|
62
|
-
|
|
123
|
+
var selectedElements = _this.lf.getSelectElements();
|
|
124
|
+
// 同时记录节点和边的ID
|
|
125
|
+
var selectedIds_1 = new Set(__spreadArray(__spreadArray([], __read(selectedElements.nodes.map(function (node) { return node.id; })), false), __read(selectedElements.edges.map(function (edge) { return edge.id; })), false));
|
|
126
|
+
elements_1.forEach(function (element) {
|
|
63
127
|
// 如果节点属于分组,则不选中节点,此处兼容旧版 Group 插件
|
|
64
|
-
if (group_1
|
|
65
|
-
|
|
128
|
+
if (group_1) {
|
|
129
|
+
var elementGroup = group_1.getNodeGroup(element.id);
|
|
130
|
+
if (elements_1.includes(elementGroup)) {
|
|
131
|
+
// 当被选中的元素的父分组被选中时,不选中该元素
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (dynamicGroup_1) {
|
|
136
|
+
var elementGroup = dynamicGroup_1.getGroupByNodeId(element.id);
|
|
137
|
+
if (elements_1.includes(elementGroup)) {
|
|
138
|
+
// 当被选中的元素的父分组被选中时,不选中该元素
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
66
141
|
}
|
|
67
|
-
|
|
142
|
+
// 在独占模式下,如果元素已经被选中,则取消选中
|
|
143
|
+
if (_this.exclusiveMode && selectedIds_1.has(element.id)) {
|
|
144
|
+
_this.lf.deselectElementById(element.id);
|
|
68
145
|
return;
|
|
69
146
|
}
|
|
147
|
+
// 非独占模式下,或者元素未被选中时,选中元素
|
|
70
148
|
_this.lf.selectElementById(element.id, true);
|
|
71
149
|
nonGroupedElements_1.push(element);
|
|
72
150
|
});
|
|
151
|
+
// 重置起始点和终点
|
|
152
|
+
// 注意:这两个值必须在触发closeSelectionSelect方法前充值,否则会导致独占模式下元素无法选中的问题
|
|
153
|
+
_this.startPoint = undefined;
|
|
154
|
+
_this.endPoint = undefined;
|
|
155
|
+
// 如果有选中的元素,触发 selection:drop 事件
|
|
156
|
+
if (nonGroupedElements_1.length > 0) {
|
|
157
|
+
_this.lf.emit('selection:drop', { e: e });
|
|
158
|
+
}
|
|
159
|
+
// 触发 selection:selected 事件
|
|
73
160
|
_this.lf.emit('selection:selected', {
|
|
74
161
|
elements: nonGroupedElements_1,
|
|
75
162
|
leftTopPoint: lt,
|
|
76
163
|
rightBottomPoint: rb,
|
|
77
164
|
});
|
|
78
165
|
}
|
|
166
|
+
if (_this.wrapper) {
|
|
167
|
+
_this.wrapper.oncontextmenu = null;
|
|
168
|
+
if (_this.container && _this.wrapper.parentNode === _this.container) {
|
|
169
|
+
_this.container.removeChild(_this.wrapper);
|
|
170
|
+
}
|
|
171
|
+
_this.wrapper = undefined;
|
|
172
|
+
}
|
|
79
173
|
};
|
|
80
174
|
this.lf = lf;
|
|
81
|
-
|
|
82
|
-
var stopMoveGraph = lf.getEditConfig().stopMoveGraph;
|
|
83
|
-
this.isDefaultStopMoveGraph = stopMoveGraph;
|
|
175
|
+
this.exclusiveMode = (_b = options === null || options === void 0 ? void 0 : options.exclusiveMode) !== null && _b !== void 0 ? _b : false;
|
|
84
176
|
// TODO: 有没有既能将方法挂载到lf上,又能提供类型提示的方法?
|
|
85
177
|
lf.openSelectionSelect = function () {
|
|
86
178
|
_this.openSelectionSelect();
|
|
@@ -88,43 +180,114 @@ var SelectionSelect = /** @class */ (function () {
|
|
|
88
180
|
lf.closeSelectionSelect = function () {
|
|
89
181
|
_this.closeSelectionSelect();
|
|
90
182
|
};
|
|
183
|
+
// 新增切换独占模式的方法
|
|
184
|
+
lf.setSelectionSelectMode = function (exclusive) {
|
|
185
|
+
_this.setExclusiveMode(exclusive);
|
|
186
|
+
};
|
|
187
|
+
// 绑定方法的 this 上下文
|
|
188
|
+
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
189
|
+
this.draw = this.draw.bind(this);
|
|
190
|
+
this.drawOff = this.drawOff.bind(this);
|
|
91
191
|
}
|
|
92
|
-
SelectionSelect.prototype.render = function (
|
|
93
|
-
var _this = this;
|
|
192
|
+
SelectionSelect.prototype.render = function (_, domContainer) {
|
|
94
193
|
this.container = domContainer;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* 清理选区状态
|
|
197
|
+
*/
|
|
198
|
+
SelectionSelect.prototype.cleanupSelectionState = function () {
|
|
199
|
+
// 清理当前的选区状态
|
|
200
|
+
if (this.wrapper) {
|
|
201
|
+
this.wrapper.oncontextmenu = null;
|
|
202
|
+
if (this.container && this.wrapper.parentNode === this.container) {
|
|
203
|
+
this.container.removeChild(this.wrapper);
|
|
106
204
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
205
|
+
this.wrapper = undefined;
|
|
206
|
+
}
|
|
207
|
+
this.startPoint = undefined;
|
|
208
|
+
this.endPoint = undefined;
|
|
209
|
+
this.mouseDownInfo = null;
|
|
210
|
+
// 移除事件监听
|
|
211
|
+
document.removeEventListener('mousemove', this.draw);
|
|
212
|
+
document.removeEventListener('mouseup', this.drawOff);
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* 切换框选模式
|
|
216
|
+
* @param exclusive 是否为独占模式。true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
|
|
217
|
+
*/
|
|
218
|
+
SelectionSelect.prototype.setExclusiveMode = function (exclusive) {
|
|
219
|
+
if (exclusive === void 0) { exclusive = false; }
|
|
220
|
+
if (this.exclusiveMode === exclusive)
|
|
221
|
+
return;
|
|
222
|
+
this.cleanupSelectionState();
|
|
223
|
+
this.exclusiveMode = exclusive;
|
|
224
|
+
if (this.container && !this.disabled) {
|
|
225
|
+
// 切换事件监听方式
|
|
226
|
+
this.removeEventListeners();
|
|
227
|
+
this.addEventListeners();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
SelectionSelect.prototype.addEventListeners = function () {
|
|
231
|
+
if (!this.container)
|
|
232
|
+
return;
|
|
233
|
+
if (this.exclusiveMode) {
|
|
234
|
+
// 独占模式:监听 container 的 mousedown 事件
|
|
235
|
+
this.container.style.pointerEvents = 'auto';
|
|
236
|
+
this.container.addEventListener('mousedown', this.handleMouseDown);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
// 非独占模式:监听画布的 blank:mousedown 事件
|
|
240
|
+
this.container.style.pointerEvents = 'none';
|
|
241
|
+
// 使用实例方法而不是箭头函数,这样可以正确移除事件监听
|
|
242
|
+
this.lf.on('blank:mousedown', this.handleBlankMouseDown);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
SelectionSelect.prototype.removeEventListeners = function () {
|
|
246
|
+
if (this.container) {
|
|
247
|
+
this.container.style.pointerEvents = 'none';
|
|
248
|
+
this.container.removeEventListener('mousedown', this.handleMouseDown);
|
|
249
|
+
}
|
|
250
|
+
// 移除 blank:mousedown 事件监听
|
|
251
|
+
this.lf.off('blank:mousedown', this.handleBlankMouseDown);
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* 处理鼠标按下事件
|
|
255
|
+
*/
|
|
256
|
+
SelectionSelect.prototype.handleMouseDown = function (e) {
|
|
257
|
+
var _a;
|
|
258
|
+
if (!this.container || this.disabled)
|
|
259
|
+
return;
|
|
260
|
+
// 禁用右键框选
|
|
261
|
+
var isRightClick = e.button === 2;
|
|
262
|
+
if (isRightClick)
|
|
263
|
+
return;
|
|
264
|
+
// 清理之前可能存在的选区状态
|
|
265
|
+
this.cleanupSelectionState();
|
|
266
|
+
// 记录鼠标按下时的位置和时间
|
|
267
|
+
this.mouseDownInfo = {
|
|
268
|
+
x: e.clientX,
|
|
269
|
+
y: e.clientY,
|
|
270
|
+
time: Date.now(),
|
|
271
|
+
};
|
|
272
|
+
// 记录原始设置并临时禁止画布移动
|
|
273
|
+
this.originalStopMoveGraph = this.lf.getEditConfig().stopMoveGraph;
|
|
274
|
+
this.lf.updateEditConfig({
|
|
275
|
+
stopMoveGraph: true,
|
|
127
276
|
});
|
|
277
|
+
var _b = this.lf.getPointByClient(e.clientX, e.clientY).domOverlayPosition, x = _b.x, y = _b.y;
|
|
278
|
+
this.startPoint = { x: x, y: y };
|
|
279
|
+
this.endPoint = { x: x, y: y };
|
|
280
|
+
var wrapper = document.createElement('div');
|
|
281
|
+
wrapper.className = 'lf-selection-select';
|
|
282
|
+
wrapper.oncontextmenu = function prevent(ev) {
|
|
283
|
+
ev.preventDefault();
|
|
284
|
+
};
|
|
285
|
+
wrapper.style.top = "".concat(this.startPoint.y, "px");
|
|
286
|
+
wrapper.style.left = "".concat(this.startPoint.x, "px");
|
|
287
|
+
(_a = this.container) === null || _a === void 0 ? void 0 : _a.appendChild(wrapper);
|
|
288
|
+
this.wrapper = wrapper;
|
|
289
|
+
document.addEventListener('mousemove', this.draw);
|
|
290
|
+
document.addEventListener('mouseup', this.drawOff);
|
|
128
291
|
};
|
|
129
292
|
/**
|
|
130
293
|
* 设置选中的灵敏度
|
|
@@ -141,24 +304,35 @@ var SelectionSelect = /** @class */ (function () {
|
|
|
141
304
|
* 开启选区
|
|
142
305
|
*/
|
|
143
306
|
SelectionSelect.prototype.openSelectionSelect = function () {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
307
|
+
if (!this.disabled) {
|
|
308
|
+
this.closeSelectionSelect();
|
|
309
|
+
}
|
|
310
|
+
if (!this.container) {
|
|
311
|
+
return;
|
|
150
312
|
}
|
|
313
|
+
this.cleanupSelectionState();
|
|
314
|
+
this.addEventListeners();
|
|
151
315
|
this.open();
|
|
152
316
|
};
|
|
153
317
|
/**
|
|
154
318
|
* 关闭选区
|
|
155
319
|
*/
|
|
156
320
|
SelectionSelect.prototype.closeSelectionSelect = function () {
|
|
157
|
-
if (!this.
|
|
158
|
-
|
|
159
|
-
|
|
321
|
+
if (!this.container) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
// 如果还有未完成的框选,先触发 drawOff 完成框选
|
|
325
|
+
if (this.wrapper && this.startPoint && this.endPoint) {
|
|
326
|
+
// 记录上一次的结束点,用于触发 mouseup 事件
|
|
327
|
+
var lastEndPoint = cloneDeep(this.endPoint);
|
|
328
|
+
var lastEvent = new MouseEvent('mouseup', {
|
|
329
|
+
clientX: lastEndPoint.x,
|
|
330
|
+
clientY: lastEndPoint.y,
|
|
160
331
|
});
|
|
332
|
+
this.drawOff(lastEvent);
|
|
161
333
|
}
|
|
334
|
+
this.cleanupSelectionState();
|
|
335
|
+
this.removeEventListeners();
|
|
162
336
|
this.close();
|
|
163
337
|
};
|
|
164
338
|
SelectionSelect.prototype.open = function () {
|
|
@@ -48,10 +48,14 @@ export declare class DynamicGroup {
|
|
|
48
48
|
* @param nodes
|
|
49
49
|
*/
|
|
50
50
|
calibrateTopGroupZIndex(nodes: NodeData[]): void;
|
|
51
|
-
|
|
51
|
+
onSelectionDrop: () => void;
|
|
52
|
+
onNodeAddOrDrop: ({ data: node }: CallbackArgs<'node:add'>) => void;
|
|
53
|
+
addNodeToGroup: (node: LogicFlow.NodeData) => void;
|
|
52
54
|
onGroupAddNode: ({ data: groupData, childId, }: CallbackArgs<'group:add-node'>) => void;
|
|
53
55
|
removeNodeFromGroup: ({ data: node, model, }: CallbackArgs<'node:delete'>) => void;
|
|
54
|
-
|
|
56
|
+
onSelectionDrag: () => void;
|
|
57
|
+
onNodeDrag: ({ data: node }: CallbackArgs<'node:drag'>) => void;
|
|
58
|
+
setActiveGroup: (node: LogicFlow.NodeData) => void;
|
|
55
59
|
/**
|
|
56
60
|
* 1. 分组节点默认在普通节点下面
|
|
57
61
|
* 2. 分组节点被选中后,会将分组节点以及其内部的其它分组节点放到其余分组节点的上面
|
|
@@ -55,9 +55,17 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
55
55
|
this.topGroupZIndex = DEFAULT_BOTTOM_Z_INDEX;
|
|
56
56
|
// 存储节点与 group 的映射关系
|
|
57
57
|
this.nodeGroupMap = new Map();
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
this.onSelectionDrop = function () {
|
|
59
|
+
var selectedNodes = _this.lf.graphModel.getSelectElements().nodes;
|
|
60
|
+
selectedNodes.forEach(function (node) {
|
|
61
|
+
_this.addNodeToGroup(node);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
this.onNodeAddOrDrop = function (_a) {
|
|
60
65
|
var node = _a.data;
|
|
66
|
+
_this.addNodeToGroup(node);
|
|
67
|
+
};
|
|
68
|
+
this.addNodeToGroup = function (node) {
|
|
61
69
|
// 1. 如果该节点之前已经在 group 中了,则将其从之前的 group 移除
|
|
62
70
|
var preGroupId = _this.nodeGroupMap.get(node.id);
|
|
63
71
|
if (preGroupId) {
|
|
@@ -97,12 +105,10 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
97
105
|
var group = _this.getGroupByBounds(bounds, node);
|
|
98
106
|
if (group) {
|
|
99
107
|
var isAllowAppendIn = group.isAllowAppendIn(node);
|
|
100
|
-
console.log('isAllowAppendIn', isAllowAppendIn);
|
|
101
108
|
if (isAllowAppendIn) {
|
|
102
109
|
group.addChild(node.id);
|
|
103
110
|
// 建立节点与 group 的映射关系放在了 group.addChild 触发的事件中,与直接调用 addChild 的行为保持一致
|
|
104
|
-
|
|
105
|
-
group.setAllowAppendChild(true);
|
|
111
|
+
group.setAllowAppendChild(false);
|
|
106
112
|
}
|
|
107
113
|
else {
|
|
108
114
|
// 抛出不允许插入的事件
|
|
@@ -116,7 +122,6 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
116
122
|
};
|
|
117
123
|
this.onGroupAddNode = function (_a) {
|
|
118
124
|
var groupData = _a.data, childId = _a.childId;
|
|
119
|
-
console.log('group:add-node', groupData);
|
|
120
125
|
_this.nodeGroupMap.set(childId, groupData.id);
|
|
121
126
|
};
|
|
122
127
|
this.removeNodeFromGroup = function (_a) {
|
|
@@ -134,8 +139,17 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
134
139
|
_this.nodeGroupMap.delete(node.id);
|
|
135
140
|
}
|
|
136
141
|
};
|
|
137
|
-
this.
|
|
142
|
+
this.onSelectionDrag = function () {
|
|
143
|
+
var selectedNodes = _this.lf.graphModel.getSelectElements().nodes;
|
|
144
|
+
selectedNodes.forEach(function (node) {
|
|
145
|
+
_this.setActiveGroup(node);
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
this.onNodeDrag = function (_a) {
|
|
138
149
|
var node = _a.data;
|
|
150
|
+
_this.setActiveGroup(node);
|
|
151
|
+
};
|
|
152
|
+
this.setActiveGroup = function (node) {
|
|
139
153
|
var nodeModel = _this.lf.getNodeModelById(node.id);
|
|
140
154
|
var bounds = nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.getBounds();
|
|
141
155
|
if (nodeModel && bounds) {
|
|
@@ -150,7 +164,6 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
150
164
|
if (!isAllowAppendIn)
|
|
151
165
|
return;
|
|
152
166
|
_this.activeGroup = targetGroup;
|
|
153
|
-
console.log('this.activeGroup', _this.activeGroup);
|
|
154
167
|
_this.activeGroup.setAllowAppendChild(true);
|
|
155
168
|
}
|
|
156
169
|
};
|
|
@@ -260,7 +273,6 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
260
273
|
};
|
|
261
274
|
this.onGraphRendered = function (_a) {
|
|
262
275
|
var data = _a.data;
|
|
263
|
-
console.log('data', data);
|
|
264
276
|
forEach(data.nodes, function (node) {
|
|
265
277
|
if (node.children) {
|
|
266
278
|
forEach(node.children, function (childId) {
|
|
@@ -567,16 +579,14 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
567
579
|
return true;
|
|
568
580
|
});
|
|
569
581
|
graphModel.dynamicGroup = this;
|
|
570
|
-
lf.on('node:add,node:drop,node:dnd-add', this.
|
|
582
|
+
lf.on('node:add,node:drop,node:dnd-add', this.onNodeAddOrDrop);
|
|
583
|
+
lf.on('selection:drop', this.onSelectionDrop);
|
|
571
584
|
lf.on('node:delete', this.removeNodeFromGroup);
|
|
572
|
-
lf.on('node:drag,node:dnd-drag', this.
|
|
585
|
+
lf.on('node:drag,node:dnd-drag', this.onNodeDrag);
|
|
586
|
+
lf.on('selection:drag', this.onSelectionDrag);
|
|
573
587
|
lf.on('node:click', this.onNodeSelect);
|
|
574
588
|
lf.on('node:mousemove', this.onNodeMove);
|
|
575
589
|
lf.on('graph:rendered', this.onGraphRendered);
|
|
576
|
-
lf.on('graph:updated', function (_a) {
|
|
577
|
-
var data = _a.data;
|
|
578
|
-
return console.log('data', data);
|
|
579
|
-
});
|
|
580
590
|
lf.on('group:add-node', this.onGroupAddNode);
|
|
581
591
|
// https://github.com/didi/LogicFlow/issues/1346
|
|
582
592
|
// 重写 addElements() 方法,在 addElements() 原有基础上增加对 group 内部所有 nodes 和 edges 的复制功能
|
|
@@ -610,7 +620,6 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
610
620
|
forEach(edgesInnerGroup, function (edge) {
|
|
611
621
|
_this.createEdge(edge, nodeIdMap, distance);
|
|
612
622
|
});
|
|
613
|
-
console.log('selectedEdges --->>>', selectedEdges);
|
|
614
623
|
forEach(selectedEdges, function (edge) {
|
|
615
624
|
elements.edges.push(_this.createEdge(edge, nodeIdMap, distance));
|
|
616
625
|
});
|
|
@@ -623,9 +632,11 @@ var DynamicGroup = /** @class */ (function () {
|
|
|
623
632
|
DynamicGroup.prototype.render = function () { };
|
|
624
633
|
DynamicGroup.prototype.destroy = function () {
|
|
625
634
|
// 销毁监听的事件,并移除渲染的 dom 内容
|
|
626
|
-
this.lf.off('node:add,node:drop,node:dnd-add', this.
|
|
635
|
+
this.lf.off('node:add,node:drop,node:dnd-add', this.onNodeAddOrDrop);
|
|
636
|
+
this.lf.off('selection:drop', this.onSelectionDrop);
|
|
627
637
|
this.lf.off('node:delete', this.removeNodeFromGroup);
|
|
628
|
-
this.lf.off('node:drag,node:dnd-drag', this.
|
|
638
|
+
this.lf.off('node:drag,node:dnd-drag', this.onNodeDrag);
|
|
639
|
+
this.lf.off('selection:drag', this.onSelectionDrag);
|
|
629
640
|
this.lf.off('node:click', this.onNodeSelect);
|
|
630
641
|
this.lf.off('node:mousemove', this.onNodeMove);
|
|
631
642
|
this.lf.off('graph:rendered', this.onGraphRendered);
|
|
@@ -326,7 +326,6 @@ var GroupNodeModel = /** @class */ (function (_super) {
|
|
|
326
326
|
var _this = this;
|
|
327
327
|
var data = _super.prototype.getData.call(this);
|
|
328
328
|
data.children = [];
|
|
329
|
-
console.log('this.children', this.children);
|
|
330
329
|
this.children.forEach(function (childId) {
|
|
331
330
|
var model = _this.graphModel.getNodeModelById(childId);
|
|
332
331
|
if (model && !model.virtual) {
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __read = (this && this.__read) || function (o, n) {
|
|
3
14
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
4
15
|
if (!m) return o;
|
|
@@ -208,6 +219,7 @@ var Menu = /** @class */ (function () {
|
|
|
208
219
|
var position = _a.position;
|
|
209
220
|
var menuList = (_c = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultGraphMenuKey)) !== null && _c !== void 0 ? _c : [];
|
|
210
221
|
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
222
|
+
_this.__currentData = __assign({}, position.canvasOverlayPosition);
|
|
211
223
|
_this.showMenu(x, y, menuList);
|
|
212
224
|
});
|
|
213
225
|
this.lf.on('selection:contextmenu', function (_a) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import LogicFlow from '@logicflow/core';
|
|
2
|
+
export interface SelectionConfig {
|
|
3
|
+
exclusiveMode?: boolean;
|
|
4
|
+
}
|
|
2
5
|
export declare class SelectionSelect {
|
|
3
6
|
static pluginName: string;
|
|
4
7
|
private container?;
|
|
@@ -7,11 +10,32 @@ export declare class SelectionSelect {
|
|
|
7
10
|
private startPoint?;
|
|
8
11
|
private endPoint?;
|
|
9
12
|
private disabled;
|
|
10
|
-
private isDefaultStopMoveGraph;
|
|
11
13
|
private isWholeNode;
|
|
12
14
|
private isWholeEdge;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
exclusiveMode: boolean;
|
|
16
|
+
private mouseDownInfo;
|
|
17
|
+
private originalStopMoveGraph;
|
|
18
|
+
constructor({ lf, options }: LogicFlow.IExtensionProps);
|
|
19
|
+
render(_: LogicFlow, domContainer: HTMLElement): void;
|
|
20
|
+
/**
|
|
21
|
+
* 清理选区状态
|
|
22
|
+
*/
|
|
23
|
+
private cleanupSelectionState;
|
|
24
|
+
/**
|
|
25
|
+
* 切换框选模式
|
|
26
|
+
* @param exclusive 是否为独占模式。true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
|
|
27
|
+
*/
|
|
28
|
+
setExclusiveMode(exclusive?: boolean): void;
|
|
29
|
+
private addEventListeners;
|
|
30
|
+
private removeEventListeners;
|
|
31
|
+
/**
|
|
32
|
+
* 处理画布空白处鼠标按下事件(非独占模式)
|
|
33
|
+
*/
|
|
34
|
+
private handleBlankMouseDown;
|
|
35
|
+
/**
|
|
36
|
+
* 处理鼠标按下事件
|
|
37
|
+
*/
|
|
38
|
+
private handleMouseDown;
|
|
15
39
|
/**
|
|
16
40
|
* 设置选中的灵敏度
|
|
17
41
|
* @param isWholeEdge 是否要边的起点终点都在选区范围才算选中。默认true
|