@logicflow/core 2.0.9 → 2.0.10
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$colon$dev.log +2 -2
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +16 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/LogicFlow.js +14 -1
- package/es/event/eventEmitter.d.ts +1 -0
- package/es/event/eventEmitter.js +3 -0
- package/es/history/index.d.ts +1 -0
- package/es/history/index.js +6 -0
- package/es/keyboard/index.d.ts +1 -0
- package/es/keyboard/index.js +3 -0
- package/es/model/EditConfigModel.d.ts +3 -1
- package/es/model/EditConfigModel.js +5 -0
- package/es/model/GraphModel.d.ts +13 -1
- package/es/model/GraphModel.js +41 -41
- package/es/model/edge/BaseEdgeModel.js +6 -3
- package/es/model/edge/PolylineEdgeModel.d.ts +1 -0
- package/es/model/edge/PolylineEdgeModel.js +7 -0
- package/es/model/node/BaseNodeModel.js +3 -2
- package/es/tool/index.d.ts +1 -0
- package/es/tool/index.js +4 -0
- package/es/util/geometry.d.ts +1 -1
- package/es/util/geometry.js +4 -1
- package/es/view/Graph.js +19 -2
- package/es/view/behavior/dnd.js +3 -2
- package/es/view/edge/BaseEdge.js +9 -2
- package/es/view/node/BaseNode.js +19 -6
- package/es/view/node/HtmlNode.js +1 -0
- package/es/view/overlay/CanvasOverlay.js +6 -4
- package/es/view/text/BaseText.js +1 -0
- package/lib/LogicFlow.js +13 -0
- package/lib/event/eventEmitter.d.ts +1 -0
- package/lib/event/eventEmitter.js +3 -0
- package/lib/history/index.d.ts +1 -0
- package/lib/history/index.js +6 -0
- package/lib/keyboard/index.d.ts +1 -0
- package/lib/keyboard/index.js +3 -0
- package/lib/model/EditConfigModel.d.ts +3 -1
- package/lib/model/EditConfigModel.js +5 -0
- package/lib/model/GraphModel.d.ts +13 -1
- package/lib/model/GraphModel.js +40 -40
- package/lib/model/edge/BaseEdgeModel.js +6 -3
- package/lib/model/edge/PolylineEdgeModel.d.ts +1 -0
- package/lib/model/edge/PolylineEdgeModel.js +7 -0
- package/lib/model/node/BaseNodeModel.js +3 -2
- package/lib/tool/index.d.ts +1 -0
- package/lib/tool/index.js +4 -0
- package/lib/util/geometry.d.ts +1 -1
- package/lib/util/geometry.js +4 -1
- package/lib/view/Graph.js +19 -2
- package/lib/view/behavior/dnd.js +3 -2
- package/lib/view/edge/BaseEdge.js +9 -2
- package/lib/view/node/BaseNode.js +19 -6
- package/lib/view/node/HtmlNode.js +1 -0
- package/lib/view/overlay/CanvasOverlay.js +6 -4
- package/lib/view/text/BaseText.js +1 -0
- package/package.json +1 -1
- package/src/LogicFlow.tsx +19 -1
- package/src/event/eventEmitter.ts +4 -0
- package/src/history/index.ts +7 -0
- package/src/keyboard/index.ts +4 -0
- package/src/model/EditConfigModel.ts +4 -0
- package/src/model/GraphModel.ts +62 -70
- package/src/model/edge/BaseEdgeModel.ts +7 -2
- package/src/model/edge/PolylineEdgeModel.ts +8 -0
- package/src/model/node/BaseNodeModel.ts +5 -2
- package/src/tool/index.ts +5 -0
- package/src/util/geometry.ts +3 -1
- package/src/view/Graph.tsx +19 -2
- package/src/view/behavior/dnd.ts +5 -2
- package/src/view/edge/BaseEdge.tsx +9 -2
- package/src/view/node/BaseNode.tsx +20 -6
- package/src/view/node/HtmlNode.tsx +1 -0
- package/src/view/overlay/CanvasOverlay.tsx +6 -5
- package/src/view/text/BaseText.tsx +1 -0
- package/stats.html +1 -1
|
@@ -89,7 +89,7 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
89
89
|
var _b, _c, _d, _e;
|
|
90
90
|
var event = _a.event;
|
|
91
91
|
var _f = _this.props, model = _f.model, graphModel = _f.graphModel;
|
|
92
|
-
var _g = graphModel.editConfigModel, stopMoveGraph = _g.stopMoveGraph, autoExpand = _g.autoExpand, transformModel = graphModel.transformModel, selectNodes = graphModel.selectNodes, width = graphModel.width, height = graphModel.height, gridSize = graphModel.gridSize;
|
|
92
|
+
var _g = graphModel.editConfigModel, stopMoveGraph = _g.stopMoveGraph, autoExpand = _g.autoExpand, snapGrid = _g.snapGrid, transformModel = graphModel.transformModel, selectNodes = graphModel.selectNodes, width = graphModel.width, height = graphModel.height, gridSize = graphModel.gridSize;
|
|
93
93
|
model.isDragging = true;
|
|
94
94
|
var _h = event, clientX = _h.clientX, clientY = _h.clientY;
|
|
95
95
|
var _j = graphModel.getPointByClient({
|
|
@@ -101,9 +101,9 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
101
101
|
// 2. 考虑鼠标位置不再节点中心
|
|
102
102
|
x = x + ((_c = (_b = _this.moveOffset) === null || _b === void 0 ? void 0 : _b.dx) !== null && _c !== void 0 ? _c : 0);
|
|
103
103
|
y = y + ((_e = (_d = _this.moveOffset) === null || _d === void 0 ? void 0 : _d.dy) !== null && _e !== void 0 ? _e : 0);
|
|
104
|
-
//
|
|
105
|
-
x = (0, util_1.snapToGrid)(x, gridSize);
|
|
106
|
-
y = (0, util_1.snapToGrid)(y, gridSize);
|
|
104
|
+
// 校准坐标
|
|
105
|
+
x = (0, util_1.snapToGrid)(x, gridSize, snapGrid);
|
|
106
|
+
y = (0, util_1.snapToGrid)(y, gridSize, snapGrid);
|
|
107
107
|
if (!width || !height) {
|
|
108
108
|
graphModel.moveNode2Coordinate(model.id, x, y);
|
|
109
109
|
return;
|
|
@@ -217,7 +217,10 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
217
217
|
else {
|
|
218
218
|
graphModel.selectNodeById(model.id, isMultiple);
|
|
219
219
|
eventOptions.isSelected = true;
|
|
220
|
-
|
|
220
|
+
// 静默模式下点击节点不变更节点层级
|
|
221
|
+
if (!editConfigModel.isSilentMode) {
|
|
222
|
+
_this.toFront();
|
|
223
|
+
}
|
|
221
224
|
}
|
|
222
225
|
// 不是双击的,默认都是单击
|
|
223
226
|
if (isDoubleClick) {
|
|
@@ -237,6 +240,7 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
237
240
|
_this.handleContextMenu = function (ev) {
|
|
238
241
|
ev.preventDefault();
|
|
239
242
|
var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
|
|
243
|
+
var editConfigModel = graphModel.editConfigModel;
|
|
240
244
|
// 节点数据,多为事件对象数据抛出
|
|
241
245
|
var nodeData = model.getData();
|
|
242
246
|
var position = graphModel.getPointByClient({
|
|
@@ -252,7 +256,10 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
252
256
|
e: ev,
|
|
253
257
|
position: position,
|
|
254
258
|
});
|
|
255
|
-
|
|
259
|
+
// 静默模式下点击节点不变更节点层级
|
|
260
|
+
if (!editConfigModel.isSilentMode) {
|
|
261
|
+
_this.toFront();
|
|
262
|
+
}
|
|
256
263
|
};
|
|
257
264
|
_this.handleMouseDown = function (ev) {
|
|
258
265
|
var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
|
|
@@ -326,6 +333,12 @@ var BaseNode = /** @class */ (function (_super) {
|
|
|
326
333
|
if (this.modelDisposer) {
|
|
327
334
|
this.modelDisposer();
|
|
328
335
|
}
|
|
336
|
+
// 以下是 mobx-preact 中 componentWillUnmount 的回调逻辑,但是不知道出于什么考虑,mobx-preact 没有混入这一段逻辑
|
|
337
|
+
// @ts-ignore
|
|
338
|
+
if (this.render.$mobx) {
|
|
339
|
+
// @ts-ignore
|
|
340
|
+
this.render.$mobx.dispose();
|
|
341
|
+
}
|
|
329
342
|
};
|
|
330
343
|
BaseNode.prototype.componentDidMount = function () { };
|
|
331
344
|
BaseNode.prototype.componentDidUpdate = function () { };
|
|
@@ -119,6 +119,7 @@ var HtmlNode = /** @class */ (function (_super) {
|
|
|
119
119
|
}
|
|
120
120
|
};
|
|
121
121
|
HtmlNode.prototype.componentWillUnmount = function () {
|
|
122
|
+
_super.prototype.componentWillUnmount.call(this);
|
|
122
123
|
this.rootEl.innerHTML = '';
|
|
123
124
|
};
|
|
124
125
|
HtmlNode.prototype.getShape = function () {
|
|
@@ -66,8 +66,9 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
66
66
|
_this.zoomHandler = function (ev) {
|
|
67
67
|
var _a = _this.props, _b = _a.graphModel, editConfigModel = _b.editConfigModel, transformModel = _b.transformModel, gridSize = _b.gridSize, graphModel = _a.graphModel;
|
|
68
68
|
var eX = ev.deltaX, eY = ev.deltaY;
|
|
69
|
+
var stopScrollGraph = editConfigModel.stopScrollGraph, stopZoomGraph = editConfigModel.stopZoomGraph;
|
|
69
70
|
// 如果没有禁止滚动移动画布, 并且当前触发的时候ctrl键、cmd键没有按住, 那么移动画布
|
|
70
|
-
if (!
|
|
71
|
+
if (!stopScrollGraph && !ev.ctrlKey && !ev.metaKey) {
|
|
71
72
|
ev.preventDefault();
|
|
72
73
|
_this.stepScrollX += eX;
|
|
73
74
|
_this.stepScrollY += eY;
|
|
@@ -86,7 +87,7 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
89
|
// 如果没有禁止缩放画布,那么进行缩放. 在禁止缩放画布后,按住 ctrl、cmd 键也不能缩放了。
|
|
89
|
-
if (!
|
|
90
|
+
if (!stopZoomGraph) {
|
|
90
91
|
ev.preventDefault();
|
|
91
92
|
var position = graphModel.getPointByClient({
|
|
92
93
|
x: ev.clientX,
|
|
@@ -127,10 +128,11 @@ var CanvasOverlay = /** @class */ (function (_super) {
|
|
|
127
128
|
// 鼠标、触摸板 按下
|
|
128
129
|
_this.mouseDownHandler = function (ev) {
|
|
129
130
|
var _a = _this.props.graphModel, eventCenter = _a.eventCenter, editConfigModel = _a.editConfigModel, SCALE_X = _a.transformModel.SCALE_X, gridSize = _a.gridSize;
|
|
131
|
+
var adjustEdge = editConfigModel.adjustEdge, adjustNodePosition = editConfigModel.adjustNodePosition, stopMoveGraph = editConfigModel.stopMoveGraph;
|
|
130
132
|
var target = ev.target;
|
|
131
|
-
var isFrozenElement = !
|
|
133
|
+
var isFrozenElement = !adjustEdge && !adjustNodePosition;
|
|
132
134
|
if (target.getAttribute('name') === 'canvas-overlay' || isFrozenElement) {
|
|
133
|
-
if (
|
|
135
|
+
if (stopMoveGraph !== true) {
|
|
134
136
|
_this.stepDrag.setStep(gridSize * SCALE_X);
|
|
135
137
|
_this.stepDrag.handleMouseDown(ev);
|
|
136
138
|
}
|
|
@@ -60,6 +60,7 @@ var BaseText = /** @class */ (function (_super) {
|
|
|
60
60
|
var _a = _this.props, draggable = _a.draggable, model = _a.model, graphModel = _a.graphModel;
|
|
61
61
|
var nodeTextDraggable = graphModel.editConfigModel.nodeTextDraggable;
|
|
62
62
|
if (draggable !== null && draggable !== void 0 ? draggable : nodeTextDraggable) {
|
|
63
|
+
e.stopPropagation();
|
|
63
64
|
_this.stepperDrag.model = model;
|
|
64
65
|
_this.stepperDrag.handleMouseDown(e);
|
|
65
66
|
}
|
package/package.json
CHANGED
package/src/LogicFlow.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType, createElement as h, render } from 'preact/compat'
|
|
2
|
-
import { cloneDeep, forEach, indexOf } from 'lodash-es'
|
|
2
|
+
import { cloneDeep, forEach, indexOf, isNil } from 'lodash-es'
|
|
3
3
|
import { observer } from '.'
|
|
4
4
|
import { Options as LFOptions } from './options'
|
|
5
5
|
import * as _Model from './model'
|
|
@@ -885,12 +885,23 @@ export class LogicFlow {
|
|
|
885
885
|
*/
|
|
886
886
|
updateEditConfig(config: Partial<IEditConfigType>) {
|
|
887
887
|
const { editConfigModel, transformModel } = this.graphModel
|
|
888
|
+
const currentSnapGrid = editConfigModel.snapGrid
|
|
889
|
+
|
|
888
890
|
editConfigModel.updateEditConfig(config)
|
|
889
891
|
if (config?.stopMoveGraph !== undefined) {
|
|
890
892
|
transformModel.updateTranslateLimits(config.stopMoveGraph)
|
|
891
893
|
}
|
|
894
|
+
|
|
892
895
|
// 静默模式切换时,修改快捷键的启用状态
|
|
893
896
|
config?.isSilentMode ? this.keyboard.disable() : this.keyboard.enable(true)
|
|
897
|
+
|
|
898
|
+
// 切换网格对齐状态时,修改网格尺寸
|
|
899
|
+
if (!isNil(config?.snapGrid) && config.snapGrid !== currentSnapGrid) {
|
|
900
|
+
const {
|
|
901
|
+
grid: { size = 1 },
|
|
902
|
+
} = this.graphModel
|
|
903
|
+
this.graphModel.updateGridSize(config.snapGrid ? size : 1)
|
|
904
|
+
}
|
|
894
905
|
}
|
|
895
906
|
|
|
896
907
|
/**
|
|
@@ -1044,6 +1055,8 @@ export class LogicFlow {
|
|
|
1044
1055
|
*/
|
|
1045
1056
|
clearData() {
|
|
1046
1057
|
this.graphModel.clearData()
|
|
1058
|
+
// 强制刷新数据, 让 preact 清除对已删除节点的引用
|
|
1059
|
+
this.render({})
|
|
1047
1060
|
}
|
|
1048
1061
|
|
|
1049
1062
|
/*********************************************************
|
|
@@ -1372,7 +1385,12 @@ export class LogicFlow {
|
|
|
1372
1385
|
|
|
1373
1386
|
/** 销毁当前实例 */
|
|
1374
1387
|
destroy() {
|
|
1388
|
+
this.clearData()
|
|
1389
|
+
render(null, this.container)
|
|
1390
|
+
this.keyboard.destroy()
|
|
1375
1391
|
this.graphModel.destroy()
|
|
1392
|
+
this.tool.destroy()
|
|
1393
|
+
this.history.destroy()
|
|
1376
1394
|
}
|
|
1377
1395
|
}
|
|
1378
1396
|
|
package/src/history/index.ts
CHANGED
package/src/keyboard/index.ts
CHANGED
|
@@ -123,6 +123,8 @@ export interface IEditConfigType {
|
|
|
123
123
|
nodeTextMode: TextMode
|
|
124
124
|
// 边文本类型
|
|
125
125
|
edgeTextMode: TextMode
|
|
126
|
+
// 开启网格对齐
|
|
127
|
+
snapGrid: boolean
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
export type IConfigKeys = keyof IEditConfigType
|
|
@@ -154,6 +156,7 @@ const allKeys = [
|
|
|
154
156
|
'stopZoomGraph', // 禁止缩放画布
|
|
155
157
|
'stopScrollGraph', // 禁止鼠标滚动移动画布
|
|
156
158
|
'stopMoveGraph', // 禁止拖动画布
|
|
159
|
+
'snapGrid', // 是否开启网格对齐
|
|
157
160
|
'adjustEdge', // 允许调整边
|
|
158
161
|
'adjustEdgeMiddle', // 允许调整边中点
|
|
159
162
|
'adjustEdgeStartAndEnd', // 允许调整边起点和终点
|
|
@@ -198,6 +201,7 @@ export class EditConfigModel {
|
|
|
198
201
|
@observable stopZoomGraph = false
|
|
199
202
|
@observable stopMoveGraph = false
|
|
200
203
|
@observable stopScrollGraph = false
|
|
204
|
+
@observable snapGrid = false
|
|
201
205
|
/*********************************************************
|
|
202
206
|
* 文本相关配置(全局)
|
|
203
207
|
********************************************************/
|
package/src/model/GraphModel.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
find,
|
|
3
|
+
forEach,
|
|
4
|
+
map,
|
|
5
|
+
merge,
|
|
6
|
+
isBoolean,
|
|
7
|
+
debounce,
|
|
8
|
+
isNil,
|
|
9
|
+
} from 'lodash-es'
|
|
2
10
|
import { action, computed, observable } from 'mobx'
|
|
3
11
|
import {
|
|
4
12
|
BaseEdgeModel,
|
|
@@ -41,7 +49,6 @@ import Position = LogicFlow.Position
|
|
|
41
49
|
import PointTuple = LogicFlow.PointTuple
|
|
42
50
|
import GraphData = LogicFlow.GraphData
|
|
43
51
|
import NodeConfig = LogicFlow.NodeConfig
|
|
44
|
-
import AnchorConfig = Model.AnchorConfig
|
|
45
52
|
import BaseNodeModelCtor = LogicFlow.BaseNodeModelCtor
|
|
46
53
|
import BaseEdgeModelCtor = LogicFlow.BaseEdgeModelCtor
|
|
47
54
|
|
|
@@ -99,6 +106,15 @@ export class GraphModel {
|
|
|
99
106
|
*/
|
|
100
107
|
customTrajectory: LFOptions.Definition['customTrajectory']
|
|
101
108
|
|
|
109
|
+
/**
|
|
110
|
+
* 判断是否使用的是容器的宽度
|
|
111
|
+
*/
|
|
112
|
+
isContainerWidth: boolean
|
|
113
|
+
/**
|
|
114
|
+
* 判断是否使用的是容器的高度
|
|
115
|
+
*/
|
|
116
|
+
isContainerHeight: boolean
|
|
117
|
+
|
|
102
118
|
// 在图上操作创建边时,默认使用的边类型.
|
|
103
119
|
@observable edgeType: string
|
|
104
120
|
// 当前图上所有节点的model
|
|
@@ -144,7 +160,9 @@ export class GraphModel {
|
|
|
144
160
|
this.rootEl = container
|
|
145
161
|
this.partial = !!partial
|
|
146
162
|
this.background = background
|
|
147
|
-
if (typeof grid === 'object') {
|
|
163
|
+
if (typeof grid === 'object' && options.snapGrid) {
|
|
164
|
+
// 开启网格对齐时才根据网格尺寸设置步长
|
|
165
|
+
// TODO:需要让用户设置成 0 吗?后面可以讨论一下
|
|
148
166
|
this.gridSize = grid.size || 1 // 默认 gridSize 设置为 1
|
|
149
167
|
}
|
|
150
168
|
this.theme = setupTheme(options.style)
|
|
@@ -153,8 +171,10 @@ export class GraphModel {
|
|
|
153
171
|
this.animation = setupAnimation(animation)
|
|
154
172
|
this.overlapMode = options.overlapMode || OverlapMode.DEFAULT
|
|
155
173
|
|
|
156
|
-
this.width = options.width
|
|
157
|
-
this.
|
|
174
|
+
this.width = options.width ?? this.rootEl.getBoundingClientRect().width
|
|
175
|
+
this.isContainerWidth = isNil(options.width)
|
|
176
|
+
this.height = options.height ?? this.rootEl.getBoundingClientRect().height
|
|
177
|
+
this.isContainerHeight = isNil(options.height)
|
|
158
178
|
|
|
159
179
|
const resizeObserver = new ResizeObserver(
|
|
160
180
|
debounce(
|
|
@@ -438,18 +458,25 @@ export class GraphModel {
|
|
|
438
458
|
* @param { object } graphData 图数据
|
|
439
459
|
*/
|
|
440
460
|
graphDataToModel(graphData: Partial<LogicFlow.GraphConfigData>) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
461
|
+
// 宽度必然存在,取消重新计算
|
|
462
|
+
// if (!this.width || !this.height) {
|
|
463
|
+
// this.resize()
|
|
464
|
+
// }
|
|
444
465
|
if (!graphData) {
|
|
445
|
-
this.
|
|
446
|
-
this.edges = []
|
|
466
|
+
this.clearData()
|
|
447
467
|
return
|
|
448
468
|
}
|
|
469
|
+
this.elementsModelMap.clear()
|
|
470
|
+
this.nodeModelMap.clear()
|
|
471
|
+
this.edgeModelMap.clear()
|
|
472
|
+
|
|
449
473
|
if (graphData.nodes) {
|
|
450
|
-
this.nodes = map(graphData.nodes, (node: NodeConfig) =>
|
|
451
|
-
this.getModelAfterSnapToGrid(node)
|
|
452
|
-
|
|
474
|
+
this.nodes = map(graphData.nodes, (node: NodeConfig) => {
|
|
475
|
+
const nodeModel = this.getModelAfterSnapToGrid(node)
|
|
476
|
+
this.elementsModelMap.set(nodeModel.id, nodeModel)
|
|
477
|
+
this.nodeModelMap.set(nodeModel.id, nodeModel)
|
|
478
|
+
return nodeModel
|
|
479
|
+
})
|
|
453
480
|
} else {
|
|
454
481
|
this.nodes = []
|
|
455
482
|
}
|
|
@@ -463,58 +490,6 @@ export class GraphModel {
|
|
|
463
490
|
throw new Error(`找不到${edge.type}对应的边。`)
|
|
464
491
|
}
|
|
465
492
|
const edgeModel = new Model(edge, this)
|
|
466
|
-
// 根据edgeModel中存储的数据找到当前画布上的起终锚点坐标
|
|
467
|
-
// 判断当前起终锚点数据和Model中存储的起终点数据是否一致,不一致更新起终点信息
|
|
468
|
-
const {
|
|
469
|
-
sourceNodeId,
|
|
470
|
-
targetNodeId,
|
|
471
|
-
sourceAnchorId = '',
|
|
472
|
-
targetAnchorId = '',
|
|
473
|
-
startPoint,
|
|
474
|
-
endPoint,
|
|
475
|
-
text,
|
|
476
|
-
textPosition,
|
|
477
|
-
} = edgeModel
|
|
478
|
-
const updateAnchorPoint = (
|
|
479
|
-
node: BaseNodeModel | undefined,
|
|
480
|
-
anchorId: string,
|
|
481
|
-
point: Position,
|
|
482
|
-
updatePoint: (anchor: AnchorConfig) => void,
|
|
483
|
-
) => {
|
|
484
|
-
const anchor = node?.anchors.find((anchor) => anchor.id === anchorId)
|
|
485
|
-
if (anchor && !isEqual(anchor, point)) {
|
|
486
|
-
updatePoint(anchor)
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
const sourceNode = this.getNodeModelById(sourceNodeId)
|
|
491
|
-
const targetNode = this.getNodeModelById(targetNodeId)
|
|
492
|
-
|
|
493
|
-
updateAnchorPoint(
|
|
494
|
-
sourceNode,
|
|
495
|
-
sourceAnchorId,
|
|
496
|
-
startPoint,
|
|
497
|
-
edgeModel.updateStartPoint.bind(edgeModel),
|
|
498
|
-
)
|
|
499
|
-
updateAnchorPoint(
|
|
500
|
-
targetNode,
|
|
501
|
-
targetAnchorId,
|
|
502
|
-
endPoint,
|
|
503
|
-
edgeModel.updateEndPoint.bind(edgeModel),
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
// 而文本需要先算一下文本与默认文本位置之间的相对位置差
|
|
507
|
-
// 再计算新路径的文本默认位置,加上相对位置差,得到调整后边的文本的位置
|
|
508
|
-
if (text) {
|
|
509
|
-
const { x, y } = text
|
|
510
|
-
const { x: defaultX, y: defaultY } = textPosition
|
|
511
|
-
if (x && y && defaultX && defaultY) {
|
|
512
|
-
const deltaX = x - defaultX
|
|
513
|
-
const deltaY = y - defaultY
|
|
514
|
-
edgeModel.resetTextPosition()
|
|
515
|
-
edgeModel.moveText(deltaX, deltaY)
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
493
|
this.edgeModelMap.set(edgeModel.id, edgeModel)
|
|
519
494
|
this.elementsModelMap.set(edgeModel.id, edgeModel)
|
|
520
495
|
|
|
@@ -873,6 +848,7 @@ export class GraphModel {
|
|
|
873
848
|
*/
|
|
874
849
|
getModelAfterSnapToGrid(node: NodeConfig) {
|
|
875
850
|
const Model = this.getModel(node.type) as BaseNodeModelCtor
|
|
851
|
+
const { snapGrid } = this.editConfigModel
|
|
876
852
|
if (!Model) {
|
|
877
853
|
throw new Error(
|
|
878
854
|
`找不到${node.type}对应的节点,请确认是否已注册此类型节点。`,
|
|
@@ -881,8 +857,8 @@ export class GraphModel {
|
|
|
881
857
|
const { x: nodeX, y: nodeY } = node
|
|
882
858
|
// 根据 grid 修正节点的 x, y
|
|
883
859
|
if (nodeX && nodeY) {
|
|
884
|
-
node.x = snapToGrid(nodeX, this.gridSize)
|
|
885
|
-
node.y = snapToGrid(nodeY, this.gridSize)
|
|
860
|
+
node.x = snapToGrid(nodeX, this.gridSize, snapGrid)
|
|
861
|
+
node.y = snapToGrid(nodeY, this.gridSize, snapGrid)
|
|
886
862
|
if (typeof node.text === 'object' && node.text !== null) {
|
|
887
863
|
// 原来的处理是:node.text.x -= getGridOffset(nodeX, this.gridSize)
|
|
888
864
|
// 由于snapToGrid()使用了Math.round()四舍五入的做法,因此无法判断需要执行
|
|
@@ -1499,7 +1475,14 @@ export class GraphModel {
|
|
|
1499
1475
|
}
|
|
1500
1476
|
|
|
1501
1477
|
/**
|
|
1502
|
-
*
|
|
1478
|
+
* 更新网格尺寸
|
|
1479
|
+
*/
|
|
1480
|
+
updateGridSize(size: number) {
|
|
1481
|
+
this.gridSize = size
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
/**
|
|
1485
|
+
* 更新背景配置
|
|
1503
1486
|
*/
|
|
1504
1487
|
updateBackgroundOptions(
|
|
1505
1488
|
options: boolean | Partial<LFOptions.BackgroundConfig>,
|
|
@@ -1518,8 +1501,11 @@ export class GraphModel {
|
|
|
1518
1501
|
* 重新设置画布的宽高
|
|
1519
1502
|
*/
|
|
1520
1503
|
@action resize(width?: number, height?: number): void {
|
|
1521
|
-
this.width = width
|
|
1522
|
-
this.
|
|
1504
|
+
this.width = width ?? this.rootEl.getBoundingClientRect().width
|
|
1505
|
+
this.isContainerWidth = isNil(width)
|
|
1506
|
+
this.height = height ?? this.rootEl.getBoundingClientRect().height
|
|
1507
|
+
this.isContainerHeight = isNil(height)
|
|
1508
|
+
|
|
1523
1509
|
if (!this.width || !this.height) {
|
|
1524
1510
|
console.warn(
|
|
1525
1511
|
'渲染画布的时候无法获取画布宽高,请确认在container已挂载到DOM。@see https://github.com/didi/LogicFlow/issues/675',
|
|
@@ -1533,6 +1519,11 @@ export class GraphModel {
|
|
|
1533
1519
|
@action clearData(): void {
|
|
1534
1520
|
this.nodes = []
|
|
1535
1521
|
this.edges = []
|
|
1522
|
+
|
|
1523
|
+
// 清除对已清除节点的引用
|
|
1524
|
+
this.edgeModelMap.clear()
|
|
1525
|
+
this.nodeModelMap.clear()
|
|
1526
|
+
this.elementsModelMap.clear()
|
|
1536
1527
|
}
|
|
1537
1528
|
|
|
1538
1529
|
/**
|
|
@@ -1680,6 +1671,7 @@ export class GraphModel {
|
|
|
1680
1671
|
console.warn('error on destroy GraphModel', err)
|
|
1681
1672
|
}
|
|
1682
1673
|
this.waitCleanEffects.length = 0
|
|
1674
|
+
this.eventCenter.destroy()
|
|
1683
1675
|
}
|
|
1684
1676
|
}
|
|
1685
1677
|
|
|
@@ -392,6 +392,8 @@ export class BaseEdgeModel<P extends PropertiesType = PropertiesType>
|
|
|
392
392
|
properties,
|
|
393
393
|
sourceNodeId: this.sourceNodeId,
|
|
394
394
|
targetNodeId: this.targetNodeId,
|
|
395
|
+
sourceAnchorId: this.sourceAnchorId,
|
|
396
|
+
targetAnchorId: this.targetAnchorId,
|
|
395
397
|
startPoint: assign({}, this.startPoint),
|
|
396
398
|
endPoint: assign({}, this.endPoint),
|
|
397
399
|
}
|
|
@@ -515,14 +517,17 @@ export class BaseEdgeModel<P extends PropertiesType = PropertiesType>
|
|
|
515
517
|
* 内部方法,处理初始化文本格式
|
|
516
518
|
*/
|
|
517
519
|
@action formatText(data: EdgeConfig) {
|
|
520
|
+
const {
|
|
521
|
+
editConfigModel: { edgeTextDraggable, edgeTextEdit },
|
|
522
|
+
} = this.graphModel
|
|
518
523
|
const { x, y } = this.textPosition
|
|
519
524
|
const { text } = data
|
|
520
525
|
let textConfig: Required<TextConfig> = {
|
|
521
526
|
value: '',
|
|
522
527
|
x,
|
|
523
528
|
y,
|
|
524
|
-
draggable:
|
|
525
|
-
editable:
|
|
529
|
+
draggable: edgeTextDraggable,
|
|
530
|
+
editable: edgeTextEdit,
|
|
526
531
|
}
|
|
527
532
|
|
|
528
533
|
if (text) {
|
|
@@ -35,6 +35,9 @@ export class PolylineEdgeModel extends BaseEdgeModel {
|
|
|
35
35
|
|
|
36
36
|
initEdgeData(data: LogicFlow.EdgeConfig): void {
|
|
37
37
|
this.offset = 30
|
|
38
|
+
if (data.pointsList) {
|
|
39
|
+
this.pointsList = data.pointsList
|
|
40
|
+
}
|
|
38
41
|
super.initEdgeData(data)
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -315,6 +318,11 @@ export class PolylineEdgeModel extends BaseEdgeModel {
|
|
|
315
318
|
return list
|
|
316
319
|
}
|
|
317
320
|
|
|
321
|
+
updatePath(pointList: Point[]) {
|
|
322
|
+
this.pointsList = pointList
|
|
323
|
+
this.points = this.getPath(this.pointsList)
|
|
324
|
+
}
|
|
325
|
+
|
|
318
326
|
getData() {
|
|
319
327
|
const data = super.getData()
|
|
320
328
|
const pointsList = this.pointsList.map(({ x, y }) => ({
|
|
@@ -246,13 +246,16 @@ export class BaseNodeModel<P extends PropertiesType = PropertiesType>
|
|
|
246
246
|
* 始化文本属性
|
|
247
247
|
*/
|
|
248
248
|
private formatText(data: NodeConfig): void {
|
|
249
|
+
const {
|
|
250
|
+
editConfigModel: { nodeTextDraggable, nodeTextEdit },
|
|
251
|
+
} = this.graphModel
|
|
249
252
|
const { x, y, text } = data
|
|
250
253
|
let textConfig: TextConfig = {
|
|
251
254
|
value: '',
|
|
252
255
|
x,
|
|
253
256
|
y,
|
|
254
|
-
draggable:
|
|
255
|
-
editable:
|
|
257
|
+
draggable: nodeTextDraggable,
|
|
258
|
+
editable: nodeTextEdit,
|
|
256
259
|
}
|
|
257
260
|
if (text) {
|
|
258
261
|
if (typeof text === 'string') {
|
package/src/tool/index.ts
CHANGED
package/src/util/geometry.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import LogicFlow from '../LogicFlow'
|
|
2
2
|
import PointTuple = LogicFlow.PointTuple
|
|
3
3
|
|
|
4
|
-
export function snapToGrid(point: number, gridSize: number) {
|
|
4
|
+
export function snapToGrid(point: number, gridSize: number, snapGrid: boolean) {
|
|
5
|
+
// 开启节网格对齐时才根据网格尺寸校准坐标
|
|
6
|
+
if (!snapGrid) return point
|
|
5
7
|
// 保证 x, y 的值为 gridSize 的整数倍
|
|
6
8
|
return gridSize * Math.round(point / gridSize) || point
|
|
7
9
|
}
|
package/src/view/Graph.tsx
CHANGED
|
@@ -39,9 +39,26 @@ type ContainerStyle = {
|
|
|
39
39
|
@observer
|
|
40
40
|
class Graph extends Component<IGraphProps> {
|
|
41
41
|
private handleResize = () => {
|
|
42
|
-
this.props
|
|
42
|
+
const { graphModel, options } = this.props
|
|
43
|
+
const { width, height, isContainerWidth, isContainerHeight } = graphModel
|
|
44
|
+
let resizeWidth: number | undefined = width
|
|
45
|
+
let resizeHeight: number | undefined = height
|
|
46
|
+
let needUpdate = false
|
|
47
|
+
if (isContainerWidth) {
|
|
48
|
+
resizeWidth = undefined
|
|
49
|
+
needUpdate = true
|
|
50
|
+
}
|
|
51
|
+
if (isContainerHeight) {
|
|
52
|
+
resizeHeight = undefined
|
|
53
|
+
needUpdate = true
|
|
54
|
+
}
|
|
55
|
+
if (needUpdate) {
|
|
56
|
+
graphModel.resize(resizeWidth, resizeHeight)
|
|
57
|
+
}
|
|
58
|
+
options.width = width
|
|
59
|
+
options.height = height
|
|
43
60
|
}
|
|
44
|
-
private throttleResize =
|
|
61
|
+
private throttleResize = throttle(this.handleResize, 200)
|
|
45
62
|
|
|
46
63
|
componentDidMount() {
|
|
47
64
|
window.addEventListener('resize', this.throttleResize)
|
package/src/view/behavior/dnd.ts
CHANGED
|
@@ -26,10 +26,13 @@ export class Dnd {
|
|
|
26
26
|
})
|
|
27
27
|
// 处理缩放和偏移
|
|
28
28
|
const { x: x1, y: y1 } = position.canvasOverlayPosition
|
|
29
|
+
const {
|
|
30
|
+
editConfigModel: { snapGrid },
|
|
31
|
+
} = this.lf.graphModel
|
|
29
32
|
// x, y 对齐到网格的 size
|
|
30
33
|
return {
|
|
31
|
-
x: snapToGrid(x1, gridSize),
|
|
32
|
-
y: snapToGrid(y1, gridSize),
|
|
34
|
+
x: snapToGrid(x1, gridSize, snapGrid),
|
|
35
|
+
y: snapToGrid(y1, gridSize, snapGrid),
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -358,6 +358,7 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
358
358
|
clearTimeout(this.clickTimer)
|
|
359
359
|
}
|
|
360
360
|
const { model, graphModel } = this.props
|
|
361
|
+
const { editConfigModel } = graphModel
|
|
361
362
|
const position = graphModel.getPointByClient({
|
|
362
363
|
x: ev.clientX,
|
|
363
364
|
y: ev.clientY,
|
|
@@ -367,7 +368,10 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
367
368
|
ElementState.SHOW_MENU,
|
|
368
369
|
position.domOverlayPosition,
|
|
369
370
|
)
|
|
370
|
-
|
|
371
|
+
// 静默模式下点击节点不变更节点层级
|
|
372
|
+
if (!editConfigModel.isSilentMode) {
|
|
373
|
+
this.toFront()
|
|
374
|
+
}
|
|
371
375
|
if (!model.isSelected) {
|
|
372
376
|
graphModel.selectEdgeById(model.id)
|
|
373
377
|
}
|
|
@@ -456,7 +460,10 @@ export abstract class BaseEdge<P extends IProps> extends Component<
|
|
|
456
460
|
}
|
|
457
461
|
const { editConfigModel } = graphModel
|
|
458
462
|
graphModel.selectEdgeById(model.id, isMultipleSelect(e, editConfigModel))
|
|
459
|
-
|
|
463
|
+
// 静默模式下点击节点不变更节点层级
|
|
464
|
+
if (!editConfigModel.isSilentMode) {
|
|
465
|
+
this.toFront()
|
|
466
|
+
}
|
|
460
467
|
}
|
|
461
468
|
|
|
462
469
|
handleFocus = () => {
|