@logicflow/core 2.0.8 → 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.
Files changed (87) hide show
  1. package/.turbo/turbo-build$colon$dev.log +2 -2
  2. package/.turbo/turbo-build.log +19 -3
  3. package/CHANGELOG.md +22 -0
  4. package/dist/index.min.js +2 -0
  5. package/dist/index.min.js.map +1 -0
  6. package/es/LogicFlow.d.ts +3 -0
  7. package/es/LogicFlow.js +18 -1
  8. package/es/event/eventArgs.d.ts +10 -0
  9. package/es/event/eventEmitter.d.ts +1 -0
  10. package/es/event/eventEmitter.js +3 -0
  11. package/es/history/index.d.ts +1 -0
  12. package/es/history/index.js +6 -0
  13. package/es/keyboard/index.d.ts +1 -0
  14. package/es/keyboard/index.js +3 -0
  15. package/es/model/EditConfigModel.d.ts +3 -1
  16. package/es/model/EditConfigModel.js +5 -0
  17. package/es/model/GraphModel.d.ts +19 -4
  18. package/es/model/GraphModel.js +92 -41
  19. package/es/model/edge/BaseEdgeModel.js +6 -3
  20. package/es/model/edge/PolylineEdgeModel.d.ts +1 -0
  21. package/es/model/edge/PolylineEdgeModel.js +7 -0
  22. package/es/model/node/BaseNodeModel.d.ts +2 -2
  23. package/es/model/node/BaseNodeModel.js +3 -2
  24. package/es/model/node/TextNodeModel.d.ts +2 -2
  25. package/es/tool/index.d.ts +1 -0
  26. package/es/tool/index.js +4 -0
  27. package/es/util/geometry.d.ts +1 -1
  28. package/es/util/geometry.js +4 -1
  29. package/es/view/Graph.js +19 -2
  30. package/es/view/behavior/dnd.js +3 -2
  31. package/es/view/edge/BaseEdge.js +9 -2
  32. package/es/view/node/BaseNode.js +20 -7
  33. package/es/view/node/HtmlNode.js +1 -0
  34. package/es/view/overlay/CanvasOverlay.js +6 -4
  35. package/es/view/overlay/getTransformHoc.d.ts +1 -1
  36. package/es/view/text/BaseText.js +1 -0
  37. package/lib/LogicFlow.d.ts +3 -0
  38. package/lib/LogicFlow.js +17 -0
  39. package/lib/event/eventArgs.d.ts +10 -0
  40. package/lib/event/eventEmitter.d.ts +1 -0
  41. package/lib/event/eventEmitter.js +3 -0
  42. package/lib/history/index.d.ts +1 -0
  43. package/lib/history/index.js +6 -0
  44. package/lib/keyboard/index.d.ts +1 -0
  45. package/lib/keyboard/index.js +3 -0
  46. package/lib/model/EditConfigModel.d.ts +3 -1
  47. package/lib/model/EditConfigModel.js +5 -0
  48. package/lib/model/GraphModel.d.ts +19 -4
  49. package/lib/model/GraphModel.js +91 -40
  50. package/lib/model/edge/BaseEdgeModel.js +6 -3
  51. package/lib/model/edge/PolylineEdgeModel.d.ts +1 -0
  52. package/lib/model/edge/PolylineEdgeModel.js +7 -0
  53. package/lib/model/node/BaseNodeModel.d.ts +2 -2
  54. package/lib/model/node/BaseNodeModel.js +3 -2
  55. package/lib/model/node/TextNodeModel.d.ts +2 -2
  56. package/lib/tool/index.d.ts +1 -0
  57. package/lib/tool/index.js +4 -0
  58. package/lib/util/geometry.d.ts +1 -1
  59. package/lib/util/geometry.js +4 -1
  60. package/lib/view/Graph.js +19 -2
  61. package/lib/view/behavior/dnd.js +3 -2
  62. package/lib/view/edge/BaseEdge.js +9 -2
  63. package/lib/view/node/BaseNode.js +20 -7
  64. package/lib/view/node/HtmlNode.js +1 -0
  65. package/lib/view/overlay/CanvasOverlay.js +6 -4
  66. package/lib/view/overlay/getTransformHoc.d.ts +1 -1
  67. package/lib/view/text/BaseText.js +1 -0
  68. package/package.json +1 -1
  69. package/src/LogicFlow.tsx +19 -1
  70. package/src/event/eventEmitter.ts +4 -0
  71. package/src/history/index.ts +7 -0
  72. package/src/keyboard/index.ts +4 -0
  73. package/src/model/EditConfigModel.ts +4 -0
  74. package/src/model/GraphModel.ts +62 -70
  75. package/src/model/edge/BaseEdgeModel.ts +7 -2
  76. package/src/model/edge/PolylineEdgeModel.ts +8 -0
  77. package/src/model/node/BaseNodeModel.ts +5 -2
  78. package/src/tool/index.ts +5 -0
  79. package/src/util/geometry.ts +3 -1
  80. package/src/view/Graph.tsx +19 -2
  81. package/src/view/behavior/dnd.ts +5 -2
  82. package/src/view/edge/BaseEdge.tsx +9 -2
  83. package/src/view/node/BaseNode.tsx +20 -6
  84. package/src/view/node/HtmlNode.tsx +1 -0
  85. package/src/view/overlay/CanvasOverlay.tsx +6 -5
  86. package/src/view/text/BaseText.tsx +1 -0
  87. package/stats.html +1 -1
@@ -16,6 +16,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
16
16
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
17
17
  return c > 3 && r && Object.defineProperty(target, key, r), r;
18
18
  };
19
+ var __values = (this && this.__values) || function(o) {
20
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
21
+ if (m) return m.call(o);
22
+ if (o && typeof o.length === "number") return {
23
+ next: function () {
24
+ if (o && i >= o.length) o = void 0;
25
+ return { value: o && o[i++], done: !o };
26
+ }
27
+ };
28
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
29
+ };
19
30
  var __read = (this && this.__read) || function (o, n) {
20
31
  var m = typeof Symbol === "function" && o[Symbol.iterator];
21
32
  if (!m) return o;
@@ -55,6 +66,8 @@ var eventEmitter_1 = __importDefault(require("../event/eventEmitter"));
55
66
  var overlay_1 = require("../view/overlay");
56
67
  var GraphModel = /** @class */ (function () {
57
68
  function GraphModel(options) {
69
+ var _this = this;
70
+ var _a, _b;
58
71
  // 维护所有节点和边类型对应的 model
59
72
  this.modelMap = new Map();
60
73
  // Remind:用于记录当前画布上所有节点和边的 model 的 Map
@@ -87,11 +100,14 @@ var GraphModel = /** @class */ (function () {
87
100
  this.gridSize = 1;
88
101
  // 控制是否开启局部渲染
89
102
  this.partial = false;
90
- var container = options.container, partial = options.partial, _a = options.background, background = _a === void 0 ? {} : _a, grid = options.grid, idGenerator = options.idGenerator, edgeGenerator = options.edgeGenerator, animation = options.animation, customTrajectory = options.customTrajectory;
103
+ this.waitCleanEffects = [];
104
+ var container = options.container, partial = options.partial, _c = options.background, background = _c === void 0 ? {} : _c, grid = options.grid, idGenerator = options.idGenerator, edgeGenerator = options.edgeGenerator, animation = options.animation, customTrajectory = options.customTrajectory;
91
105
  this.rootEl = container;
92
106
  this.partial = !!partial;
93
107
  this.background = background;
94
- if (typeof grid === 'object') {
108
+ if (typeof grid === 'object' && options.snapGrid) {
109
+ // 开启网格对齐时才根据网格尺寸设置步长
110
+ // TODO:需要让用户设置成 0 吗?后面可以讨论一下
95
111
  this.gridSize = grid.size || 1; // 默认 gridSize 设置为 1
96
112
  }
97
113
  this.theme = (0, util_1.setupTheme)(options.style);
@@ -99,8 +115,36 @@ var GraphModel = /** @class */ (function () {
99
115
  this.edgeType = options.edgeType || 'polyline';
100
116
  this.animation = (0, util_1.setupAnimation)(animation);
101
117
  this.overlapMode = options.overlapMode || constant_1.OverlapMode.DEFAULT;
102
- this.width = options.width || this.rootEl.getBoundingClientRect().width;
103
- this.height = options.height || this.rootEl.getBoundingClientRect().height;
118
+ this.width = (_a = options.width) !== null && _a !== void 0 ? _a : this.rootEl.getBoundingClientRect().width;
119
+ this.isContainerWidth = (0, lodash_es_1.isNil)(options.width);
120
+ this.height = (_b = options.height) !== null && _b !== void 0 ? _b : this.rootEl.getBoundingClientRect().height;
121
+ this.isContainerHeight = (0, lodash_es_1.isNil)(options.height);
122
+ var resizeObserver = new ResizeObserver((0, lodash_es_1.debounce)((function (entries) {
123
+ var e_1, _a;
124
+ try {
125
+ for (var entries_1 = __values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
126
+ var entry = entries_1_1.value;
127
+ if (entry.target === _this.rootEl) {
128
+ _this.resize();
129
+ _this.eventCenter.emit('graph:resize', {
130
+ target: _this.rootEl,
131
+ contentRect: entry.contentRect,
132
+ });
133
+ }
134
+ }
135
+ }
136
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
137
+ finally {
138
+ try {
139
+ if (entries_1_1 && !entries_1_1.done && (_a = entries_1.return)) _a.call(entries_1);
140
+ }
141
+ finally { if (e_1) throw e_1.error; }
142
+ }
143
+ }), 16));
144
+ resizeObserver.observe(this.rootEl);
145
+ this.waitCleanEffects.push(function () {
146
+ resizeObserver.disconnect();
147
+ });
104
148
  this.eventCenter = new eventEmitter_1.default();
105
149
  this.editConfigModel = new _1.EditConfigModel(options);
106
150
  this.transformModel = new _1.TransformModel(this.eventCenter, options);
@@ -356,17 +400,23 @@ var GraphModel = /** @class */ (function () {
356
400
  */
357
401
  GraphModel.prototype.graphDataToModel = function (graphData) {
358
402
  var _this = this;
359
- if (!this.width || !this.height) {
360
- this.resize();
361
- }
403
+ // 宽度必然存在,取消重新计算
404
+ // if (!this.width || !this.height) {
405
+ // this.resize()
406
+ // }
362
407
  if (!graphData) {
363
- this.nodes = [];
364
- this.edges = [];
408
+ this.clearData();
365
409
  return;
366
410
  }
411
+ this.elementsModelMap.clear();
412
+ this.nodeModelMap.clear();
413
+ this.edgeModelMap.clear();
367
414
  if (graphData.nodes) {
368
415
  this.nodes = (0, lodash_es_1.map)(graphData.nodes, function (node) {
369
- return _this.getModelAfterSnapToGrid(node);
416
+ var nodeModel = _this.getModelAfterSnapToGrid(node);
417
+ _this.elementsModelMap.set(nodeModel.id, nodeModel);
418
+ _this.nodeModelMap.set(nodeModel.id, nodeModel);
419
+ return nodeModel;
370
420
  });
371
421
  }
372
422
  else {
@@ -381,31 +431,6 @@ var GraphModel = /** @class */ (function () {
381
431
  throw new Error("\u627E\u4E0D\u5230".concat(edge.type, "\u5BF9\u5E94\u7684\u8FB9\u3002"));
382
432
  }
383
433
  var edgeModel = new Model(edge, _this);
384
- // 根据edgeModel中存储的数据找到当前画布上的起终锚点坐标
385
- // 判断当前起终锚点数据和Model中存储的起终点数据是否一致,不一致更新起终点信息
386
- var sourceNodeId = edgeModel.sourceNodeId, targetNodeId = edgeModel.targetNodeId, _b = edgeModel.sourceAnchorId, sourceAnchorId = _b === void 0 ? '' : _b, _c = edgeModel.targetAnchorId, targetAnchorId = _c === void 0 ? '' : _c, startPoint = edgeModel.startPoint, endPoint = edgeModel.endPoint, text = edgeModel.text, textPosition = edgeModel.textPosition;
387
- var updateAnchorPoint = function (node, anchorId, point, updatePoint) {
388
- var anchor = node === null || node === void 0 ? void 0 : node.anchors.find(function (anchor) { return anchor.id === anchorId; });
389
- if (anchor && !(0, lodash_es_1.isEqual)(anchor, point)) {
390
- updatePoint(anchor);
391
- }
392
- };
393
- var sourceNode = _this.getNodeModelById(sourceNodeId);
394
- var targetNode = _this.getNodeModelById(targetNodeId);
395
- updateAnchorPoint(sourceNode, sourceAnchorId, startPoint, edgeModel.updateStartPoint.bind(edgeModel));
396
- updateAnchorPoint(targetNode, targetAnchorId, endPoint, edgeModel.updateEndPoint.bind(edgeModel));
397
- // 而文本需要先算一下文本与默认文本位置之间的相对位置差
398
- // 再计算新路径的文本默认位置,加上相对位置差,得到调整后边的文本的位置
399
- if (text) {
400
- var x = text.x, y = text.y;
401
- var defaultX = textPosition.x, defaultY = textPosition.y;
402
- if (x && y && defaultX && defaultY) {
403
- var deltaX = x - defaultX;
404
- var deltaY = y - defaultY;
405
- edgeModel.resetTextPosition();
406
- edgeModel.moveText(deltaX, deltaY);
407
- }
408
- }
409
434
  _this.edgeModelMap.set(edgeModel.id, edgeModel);
410
435
  _this.elementsModelMap.set(edgeModel.id, edgeModel);
411
436
  return edgeModel;
@@ -739,14 +764,15 @@ var GraphModel = /** @class */ (function () {
739
764
  */
740
765
  GraphModel.prototype.getModelAfterSnapToGrid = function (node) {
741
766
  var Model = this.getModel(node.type);
767
+ var snapGrid = this.editConfigModel.snapGrid;
742
768
  if (!Model) {
743
769
  throw new Error("\u627E\u4E0D\u5230".concat(node.type, "\u5BF9\u5E94\u7684\u8282\u70B9\uFF0C\u8BF7\u786E\u8BA4\u662F\u5426\u5DF2\u6CE8\u518C\u6B64\u7C7B\u578B\u8282\u70B9\u3002"));
744
770
  }
745
771
  var nodeX = node.x, nodeY = node.y;
746
772
  // 根据 grid 修正节点的 x, y
747
773
  if (nodeX && nodeY) {
748
- node.x = (0, util_1.snapToGrid)(nodeX, this.gridSize);
749
- node.y = (0, util_1.snapToGrid)(nodeY, this.gridSize);
774
+ node.x = (0, util_1.snapToGrid)(nodeX, this.gridSize, snapGrid);
775
+ node.y = (0, util_1.snapToGrid)(nodeY, this.gridSize, snapGrid);
750
776
  if (typeof node.text === 'object' && node.text !== null) {
751
777
  // 原来的处理是:node.text.x -= getGridOffset(nodeX, this.gridSize)
752
778
  // 由于snapToGrid()使用了Math.round()四舍五入的做法,因此无法判断需要执行
@@ -1282,7 +1308,13 @@ var GraphModel = /** @class */ (function () {
1282
1308
  (0, lodash_es_1.merge)(this.grid, options);
1283
1309
  };
1284
1310
  /**
1285
- * 更新网格配置
1311
+ * 更新网格尺寸
1312
+ */
1313
+ GraphModel.prototype.updateGridSize = function (size) {
1314
+ this.gridSize = size;
1315
+ };
1316
+ /**
1317
+ * 更新背景配置
1286
1318
  */
1287
1319
  GraphModel.prototype.updateBackgroundOptions = function (options) {
1288
1320
  if ((0, lodash_es_1.isBoolean)(options) || (0, lodash_es_1.isBoolean)(this.background)) {
@@ -1296,8 +1328,10 @@ var GraphModel = /** @class */ (function () {
1296
1328
  * 重新设置画布的宽高
1297
1329
  */
1298
1330
  GraphModel.prototype.resize = function (width, height) {
1299
- this.width = width || this.rootEl.getBoundingClientRect().width;
1300
- this.height = height || this.rootEl.getBoundingClientRect().height;
1331
+ this.width = width !== null && width !== void 0 ? width : this.rootEl.getBoundingClientRect().width;
1332
+ this.isContainerWidth = (0, lodash_es_1.isNil)(width);
1333
+ this.height = height !== null && height !== void 0 ? height : this.rootEl.getBoundingClientRect().height;
1334
+ this.isContainerHeight = (0, lodash_es_1.isNil)(height);
1301
1335
  if (!this.width || !this.height) {
1302
1336
  console.warn('渲染画布的时候无法获取画布宽高,请确认在container已挂载到DOM。@see https://github.com/didi/LogicFlow/issues/675');
1303
1337
  }
@@ -1308,6 +1342,10 @@ var GraphModel = /** @class */ (function () {
1308
1342
  GraphModel.prototype.clearData = function () {
1309
1343
  this.nodes = [];
1310
1344
  this.edges = [];
1345
+ // 清除对已清除节点的引用
1346
+ this.edgeModelMap.clear();
1347
+ this.nodeModelMap.clear();
1348
+ this.elementsModelMap.clear();
1311
1349
  };
1312
1350
  /**
1313
1351
  * 获取图形区域虚拟矩型的尺寸和中心坐标
@@ -1413,6 +1451,19 @@ var GraphModel = /** @class */ (function () {
1413
1451
  GraphModel.prototype.setPartial = function (partial) {
1414
1452
  this.partial = partial;
1415
1453
  };
1454
+ /** 销毁当前实例 */
1455
+ GraphModel.prototype.destroy = function () {
1456
+ try {
1457
+ this.waitCleanEffects.forEach(function (fn) {
1458
+ fn();
1459
+ });
1460
+ }
1461
+ catch (err) {
1462
+ console.warn('error on destroy GraphModel', err);
1463
+ }
1464
+ this.waitCleanEffects.length = 0;
1465
+ this.eventCenter.destroy();
1466
+ };
1416
1467
  __decorate([
1417
1468
  mobx_1.observable
1418
1469
  ], GraphModel.prototype, "width", void 0);
@@ -320,6 +320,8 @@ var BaseEdgeModel = /** @class */ (function () {
320
320
  properties: properties,
321
321
  sourceNodeId: this.sourceNodeId,
322
322
  targetNodeId: this.targetNodeId,
323
+ sourceAnchorId: this.sourceAnchorId,
324
+ targetAnchorId: this.targetAnchorId,
323
325
  startPoint: (0, lodash_es_1.assign)({}, this.startPoint),
324
326
  endPoint: (0, lodash_es_1.assign)({}, this.endPoint),
325
327
  };
@@ -419,14 +421,15 @@ var BaseEdgeModel = /** @class */ (function () {
419
421
  */
420
422
  BaseEdgeModel.prototype.formatText = function (data) {
421
423
  var _a, _b, _c;
422
- var _d = this.textPosition, x = _d.x, y = _d.y;
424
+ var _d = this.graphModel.editConfigModel, edgeTextDraggable = _d.edgeTextDraggable, edgeTextEdit = _d.edgeTextEdit;
425
+ var _e = this.textPosition, x = _e.x, y = _e.y;
423
426
  var text = data.text;
424
427
  var textConfig = {
425
428
  value: '',
426
429
  x: x,
427
430
  y: y,
428
- draggable: false,
429
- editable: true,
431
+ draggable: edgeTextDraggable,
432
+ editable: edgeTextEdit,
430
433
  };
431
434
  if (text) {
432
435
  if (typeof text === 'string') {
@@ -33,6 +33,7 @@ export declare class PolylineEdgeModel extends BaseEdgeModel {
33
33
  removeCrossPoints(startIndex: number, endIndex: number, pointList: Point[]): LogicFlow.Point[];
34
34
  getDraggingPoints(direction: SegmentDirection, positionType: string, position: Position, anchorList: AnchorConfig[], draggingPointList: Point[]): LogicFlow.Point[];
35
35
  updateCrossPoints(pointList: Point[]): LogicFlow.Point[];
36
+ updatePath(pointList: Point[]): void;
36
37
  getData(): LogicFlow.EdgeData & {
37
38
  pointsList: {
38
39
  x: number;
@@ -73,6 +73,9 @@ var PolylineEdgeModel = /** @class */ (function (_super) {
73
73
  }
74
74
  PolylineEdgeModel.prototype.initEdgeData = function (data) {
75
75
  this.offset = 30;
76
+ if (data.pointsList) {
77
+ this.pointsList = data.pointsList;
78
+ }
76
79
  _super.prototype.initEdgeData.call(this, data);
77
80
  };
78
81
  PolylineEdgeModel.prototype.getEdgeStyle = function () {
@@ -285,6 +288,10 @@ var PolylineEdgeModel = /** @class */ (function (_super) {
285
288
  }
286
289
  return list;
287
290
  };
291
+ PolylineEdgeModel.prototype.updatePath = function (pointList) {
292
+ this.pointsList = pointList;
293
+ this.points = this.getPath(this.pointsList);
294
+ };
288
295
  PolylineEdgeModel.prototype.getData = function () {
289
296
  var data = _super.prototype.getData.call(this);
290
297
  var pointsList = this.pointsList.map(function (_a) {
@@ -172,8 +172,8 @@ export declare class BaseNodeModel<P extends PropertiesType = PropertiesType> im
172
172
  color?: string | undefined;
173
173
  fontSize: number;
174
174
  lineHeight?: number | undefined;
175
- textAnchor?: "start" | "end" | "middle" | undefined;
176
- dominantBaseline?: "middle" | "auto" | "text-bottom" | "alphabetic" | "ideographic" | "central" | "mathematical" | "hanging" | "text-top" | undefined;
175
+ textAnchor?: "middle" | "start" | "end" | undefined;
176
+ dominantBaseline?: "middle" | "central" | "auto" | "text-bottom" | "alphabetic" | "ideographic" | "mathematical" | "hanging" | "text-top" | undefined;
177
177
  };
178
178
  /**
179
179
  * @overridable 支持重写
@@ -226,13 +226,14 @@ var BaseNodeModel = /** @class */ (function () {
226
226
  */
227
227
  BaseNodeModel.prototype.formatText = function (data) {
228
228
  var _a, _b, _c;
229
+ var _d = this.graphModel.editConfigModel, nodeTextDraggable = _d.nodeTextDraggable, nodeTextEdit = _d.nodeTextEdit;
229
230
  var x = data.x, y = data.y, text = data.text;
230
231
  var textConfig = {
231
232
  value: '',
232
233
  x: x,
233
234
  y: y,
234
- draggable: false,
235
- editable: true,
235
+ draggable: nodeTextDraggable,
236
+ editable: nodeTextEdit,
236
237
  };
237
238
  if (text) {
238
239
  if (typeof text === 'string') {
@@ -24,8 +24,8 @@ export declare class TextNodeModel<P extends ITextNodeProperties = ITextNodeProp
24
24
  fontSize: number;
25
25
  textWidth?: number | undefined;
26
26
  lineHeight?: number | undefined;
27
- textAnchor?: "start" | "end" | "middle" | undefined;
28
- dominantBaseline?: "middle" | "auto" | "text-bottom" | "alphabetic" | "ideographic" | "central" | "mathematical" | "hanging" | "text-top" | undefined;
27
+ textAnchor?: "middle" | "start" | "end" | undefined;
28
+ dominantBaseline?: "middle" | "central" | "auto" | "text-bottom" | "alphabetic" | "ideographic" | "mathematical" | "hanging" | "text-top" | undefined;
29
29
  overflowMode?: "default" | "autoWrap" | "ellipsis" | undefined;
30
30
  wrapPadding?: string | undefined;
31
31
  };
@@ -20,5 +20,6 @@ export declare class Tool {
20
20
  enableTool(name: string): boolean | Error;
21
21
  getTools(): ToolConstructor[];
22
22
  getInstance(): LogicFlow;
23
+ destroy(): void;
23
24
  }
24
25
  export default Tool;
package/lib/tool/index.js CHANGED
@@ -73,6 +73,10 @@ var Tool = /** @class */ (function () {
73
73
  Tool.prototype.getInstance = function () {
74
74
  return this.instance;
75
75
  };
76
+ Tool.prototype.destroy = function () {
77
+ this.toolMap.clear();
78
+ this.disabledToolMap.clear();
79
+ };
76
80
  __decorate([
77
81
  mobx_1.observable
78
82
  ], Tool.prototype, "toolMap", void 0);
@@ -1,6 +1,6 @@
1
1
  import LogicFlow from '../LogicFlow';
2
2
  import PointTuple = LogicFlow.PointTuple;
3
- export declare function snapToGrid(point: number, gridSize: number): number;
3
+ export declare function snapToGrid(point: number, gridSize: number, snapGrid: boolean): number;
4
4
  export declare function getGridOffset(distance: number, gridSize: number): number;
5
5
  /**
6
6
  * 多边形设置 points 后,坐标平移至原点 并 根据 width、height 缩放
@@ -26,7 +26,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
28
  exports.normalizePolygon = exports.getGridOffset = exports.snapToGrid = void 0;
29
- function snapToGrid(point, gridSize) {
29
+ function snapToGrid(point, gridSize, snapGrid) {
30
+ // 开启节网格对齐时才根据网格尺寸校准坐标
31
+ if (!snapGrid)
32
+ return point;
30
33
  // 保证 x, y 的值为 gridSize 的整数倍
31
34
  return gridSize * Math.round(point / gridSize) || point;
32
35
  }
package/lib/view/Graph.js CHANGED
@@ -57,9 +57,26 @@ var Graph = /** @class */ (function (_super) {
57
57
  function Graph() {
58
58
  var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
59
59
  _this.handleResize = function () {
60
- _this.props.graphModel.resize();
60
+ var _a = _this.props, graphModel = _a.graphModel, options = _a.options;
61
+ var width = graphModel.width, height = graphModel.height, isContainerWidth = graphModel.isContainerWidth, isContainerHeight = graphModel.isContainerHeight;
62
+ var resizeWidth = width;
63
+ var resizeHeight = height;
64
+ var needUpdate = false;
65
+ if (isContainerWidth) {
66
+ resizeWidth = undefined;
67
+ needUpdate = true;
68
+ }
69
+ if (isContainerHeight) {
70
+ resizeHeight = undefined;
71
+ needUpdate = true;
72
+ }
73
+ if (needUpdate) {
74
+ graphModel.resize(resizeWidth, resizeHeight);
75
+ }
76
+ options.width = width;
77
+ options.height = height;
61
78
  };
62
- _this.throttleResize = function () { return (0, lodash_es_1.throttle)(_this.handleResize, 200); };
79
+ _this.throttleResize = (0, lodash_es_1.throttle)(_this.handleResize, 200);
63
80
  return _this;
64
81
  }
65
82
  Graph.prototype.componentDidMount = function () {
@@ -84,10 +84,11 @@ var Dnd = /** @class */ (function () {
84
84
  });
85
85
  // 处理缩放和偏移
86
86
  var _b = position.canvasOverlayPosition, x1 = _b.x, y1 = _b.y;
87
+ var snapGrid = this.lf.graphModel.editConfigModel.snapGrid;
87
88
  // x, y 对齐到网格的 size
88
89
  return {
89
- x: (0, util_1.snapToGrid)(x1, gridSize),
90
- y: (0, util_1.snapToGrid)(y1, gridSize),
90
+ x: (0, util_1.snapToGrid)(x1, gridSize, snapGrid),
91
+ y: (0, util_1.snapToGrid)(y1, gridSize, snapGrid),
91
92
  };
92
93
  };
93
94
  Dnd.prototype.startDrag = function (nodeConfig) {
@@ -125,12 +125,16 @@ var BaseEdge = /** @class */ (function (_super) {
125
125
  clearTimeout(_this.clickTimer);
126
126
  }
127
127
  var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
128
+ var editConfigModel = graphModel.editConfigModel;
128
129
  var position = graphModel.getPointByClient({
129
130
  x: ev.clientX,
130
131
  y: ev.clientY,
131
132
  });
132
133
  graphModel.setElementStateById(model.id, constant_1.ElementState.SHOW_MENU, position.domOverlayPosition);
133
- _this.toFront();
134
+ // 静默模式下点击节点不变更节点层级
135
+ if (!editConfigModel.isSilentMode) {
136
+ _this.toFront();
137
+ }
134
138
  if (!model.isSelected) {
135
139
  graphModel.selectEdgeById(model.id);
136
140
  }
@@ -218,7 +222,10 @@ var BaseEdge = /** @class */ (function (_super) {
218
222
  }
219
223
  var editConfigModel = graphModel.editConfigModel;
220
224
  graphModel.selectEdgeById(model.id, (0, util_1.isMultipleSelect)(e, editConfigModel));
221
- _this.toFront();
225
+ // 静默模式下点击节点不变更节点层级
226
+ if (!editConfigModel.isSilentMode) {
227
+ _this.toFront();
228
+ }
222
229
  };
223
230
  _this.handleFocus = function () {
224
231
  var _a = _this.props, model = _a.model, graphModel = _a.graphModel;
@@ -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
- // 将x, y移动到grid上
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,12 +217,15 @@ var BaseNode = /** @class */ (function (_super) {
217
217
  else {
218
218
  graphModel.selectNodeById(model.id, isMultiple);
219
219
  eventOptions.isSelected = true;
220
- _this.toFront();
220
+ // 静默模式下点击节点不变更节点层级
221
+ if (!editConfigModel.isSilentMode) {
222
+ _this.toFront();
223
+ }
221
224
  }
222
225
  // 不是双击的,默认都是单击
223
226
  if (isDoubleClick) {
224
227
  if (editConfigModel.nodeTextEdit) {
225
- if (model.text.editable) {
228
+ if (model.text.editable && editConfigModel.textMode === constant_1.TextMode.TEXT) {
226
229
  model.setSelected(false);
227
230
  graphModel.setElementStateById(model.id, constant_1.ElementState.TEXT_EDIT);
228
231
  }
@@ -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
- _this.toFront();
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 (!editConfigModel.stopScrollGraph && !ev.ctrlKey && !ev.metaKey) {
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 (!editConfigModel.stopZoomGraph) {
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 = !editConfigModel.adjustEdge && !editConfigModel.adjustNodePosition;
133
+ var isFrozenElement = !adjustEdge && !adjustNodePosition;
132
134
  if (target.getAttribute('name') === 'canvas-overlay' || isFrozenElement) {
133
- if (editConfigModel.stopMoveGraph !== true) {
135
+ if (stopMoveGraph !== true) {
134
136
  _this.stepDrag.setStep(gridSize * SCALE_X);
135
137
  _this.stepDrag.handleMouseDown(ev);
136
138
  }
@@ -25,7 +25,7 @@ export declare function getTransform<P>(WrappedComponent: ComponentType<P>): {
25
25
  props: import("preact").RenderableProps<IProps & P, any>;
26
26
  context: any;
27
27
  base?: Element | Text | undefined;
28
- setState<K extends never>(state: ((prevState: Readonly<{}>, props: Readonly<IProps & P>) => Pick<{}, K> | Partial<{}> | null) | Pick<{}, K> | Partial<{}> | null, callback?: (() => void) | undefined): void;
28
+ setState<K extends never>(state: Partial<{}> | ((prevState: Readonly<{}>, props: Readonly<IProps & P>) => Partial<{}> | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
29
29
  forceUpdate(callback?: (() => void) | undefined): void;
30
30
  };
31
31
  displayName?: string | undefined;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logicflow/core",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "description": "LogicFlow, help you quickly create flowcharts",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
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
 
@@ -147,6 +147,10 @@ export default class EventEmitter {
147
147
  getEvents() {
148
148
  return this._events
149
149
  }
150
+
151
+ destroy() {
152
+ this._events = {}
153
+ }
150
154
  }
151
155
 
152
156
  export { EventEmitter, EventArgs }