@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
package/es/LogicFlow.d.ts CHANGED
@@ -568,6 +568,8 @@ export declare class LogicFlow {
568
568
  * 加载插件-内部方法
569
569
  */
570
570
  private installPlugin;
571
+ /** 销毁当前实例 */
572
+ destroy(): void;
571
573
  }
572
574
  export declare namespace LogicFlow {
573
575
  /**
@@ -638,6 +640,7 @@ export declare namespace LogicFlow {
638
640
  };
639
641
  type LabelConfig = {
640
642
  id?: string;
643
+ type?: string;
641
644
  x: number;
642
645
  y: number;
643
646
  content?: string;
package/es/LogicFlow.js CHANGED
@@ -36,7 +36,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
36
36
  };
37
37
  import { jsx as _jsx } from "preact/jsx-runtime";
38
38
  import { createElement as h, render } from 'preact/compat';
39
- import { cloneDeep, forEach, indexOf } from 'lodash-es';
39
+ import { cloneDeep, forEach, indexOf, isNil } from 'lodash-es';
40
40
  import { observer } from '.';
41
41
  import { Options as LFOptions } from './options';
42
42
  import * as _Model from './model';
@@ -777,12 +777,18 @@ var LogicFlow = /** @class */ (function () {
777
777
  */
778
778
  LogicFlow.prototype.updateEditConfig = function (config) {
779
779
  var _a = this.graphModel, editConfigModel = _a.editConfigModel, transformModel = _a.transformModel;
780
+ var currentSnapGrid = editConfigModel.snapGrid;
780
781
  editConfigModel.updateEditConfig(config);
781
782
  if ((config === null || config === void 0 ? void 0 : config.stopMoveGraph) !== undefined) {
782
783
  transformModel.updateTranslateLimits(config.stopMoveGraph);
783
784
  }
784
785
  // 静默模式切换时,修改快捷键的启用状态
785
786
  (config === null || config === void 0 ? void 0 : config.isSilentMode) ? this.keyboard.disable() : this.keyboard.enable(true);
787
+ // 切换网格对齐状态时,修改网格尺寸
788
+ if (!isNil(config === null || config === void 0 ? void 0 : config.snapGrid) && config.snapGrid !== currentSnapGrid) {
789
+ var _b = this.graphModel.grid.size, size = _b === void 0 ? 1 : _b;
790
+ this.graphModel.updateGridSize(config.snapGrid ? size : 1);
791
+ }
786
792
  };
787
793
  /**
788
794
  * 获取流程图当前编辑相关设置
@@ -907,6 +913,8 @@ var LogicFlow = /** @class */ (function () {
907
913
  */
908
914
  LogicFlow.prototype.clearData = function () {
909
915
  this.graphModel.clearData();
916
+ // 强制刷新数据, 让 preact 清除对已删除节点的引用
917
+ this.render({});
910
918
  };
911
919
  /*********************************************************
912
920
  * LogicFlow Render方法
@@ -1166,6 +1174,15 @@ var LogicFlow = /** @class */ (function () {
1166
1174
  this.components.push(extensionIns.render.bind(extensionIns));
1167
1175
  this.extension[pluginName] = extensionIns;
1168
1176
  };
1177
+ /** 销毁当前实例 */
1178
+ LogicFlow.prototype.destroy = function () {
1179
+ this.clearData();
1180
+ render(null, this.container);
1181
+ this.keyboard.destroy();
1182
+ this.graphModel.destroy();
1183
+ this.tool.destroy();
1184
+ this.history.destroy();
1185
+ };
1169
1186
  // 全局配置的插件,所有的LogicFlow示例都会使用
1170
1187
  LogicFlow.extensions = new Map();
1171
1188
  return LogicFlow;
@@ -349,6 +349,16 @@ interface CommonEventArgs {
349
349
  */
350
350
  data: GraphData;
351
351
  };
352
+ /**
353
+ * 画布容器大小发生变化触发,为了性能考虑对事件做了防抖处理,间隔为16ms
354
+ */
355
+ 'graph:resize': {
356
+ /**
357
+ * 更新后的画布数据
358
+ */
359
+ target: HTMLElement;
360
+ contentRect: DOMRectReadOnly;
361
+ };
352
362
  }
353
363
  type AnchorEventArgsPick<T extends 'data' | 'e' | 'nodeModel' | 'edgeModel'> = Pick<{
354
364
  /**
@@ -44,5 +44,6 @@ export default class EventEmitter {
44
44
  off<T extends keyof EventArgs>(evts: T, callback?: (args: EventArgs[T]) => void): void;
45
45
  off<T extends string>(evts: T, callback?: EventCallback<T>): void;
46
46
  getEvents(): EventsType<string>;
47
+ destroy(): void;
47
48
  }
48
49
  export { EventEmitter, EventArgs };
@@ -84,6 +84,9 @@ var EventEmitter = /** @class */ (function () {
84
84
  EventEmitter.prototype.getEvents = function () {
85
85
  return this._events;
86
86
  };
87
+ EventEmitter.prototype.destroy = function () {
88
+ this._events = {};
89
+ };
87
90
  return EventEmitter;
88
91
  }());
89
92
  export default EventEmitter;
@@ -19,5 +19,6 @@ export declare class History {
19
19
  redoAble(): boolean;
20
20
  redo(): LogicFlow.GraphData | undefined;
21
21
  watch(model: GraphModel): void;
22
+ destroy(): void;
22
23
  }
23
24
  export default History;
@@ -104,6 +104,12 @@ var History = /** @class */ (function () {
104
104
  }
105
105
  }, this.waitTime));
106
106
  };
107
+ History.prototype.destroy = function () {
108
+ this.undos = [];
109
+ this.redos = [];
110
+ this.curData = null;
111
+ this.stopWatch && this.stopWatch();
112
+ };
107
113
  return History;
108
114
  }());
109
115
  export { History };
@@ -26,6 +26,7 @@ export declare class Keyboard {
26
26
  off(keys: string | string[], action?: Action): void;
27
27
  enable(force: boolean): void;
28
28
  disable(): void;
29
+ destroy(): void;
29
30
  private getKeys;
30
31
  protected formatKey(key: string): string;
31
32
  }
@@ -68,6 +68,9 @@ var Keyboard = /** @class */ (function () {
68
68
  }
69
69
  }
70
70
  };
71
+ Keyboard.prototype.destroy = function () {
72
+ this.mousetrap.reset();
73
+ };
71
74
  Keyboard.prototype.getKeys = function (keys) {
72
75
  var _this = this;
73
76
  return (Array.isArray(keys) ? keys : [keys]).map(function (key) {
@@ -113,6 +113,7 @@ export interface IEditConfigType {
113
113
  textMode: TextMode;
114
114
  nodeTextMode: TextMode;
115
115
  edgeTextMode: TextMode;
116
+ snapGrid: boolean;
116
117
  }
117
118
  export type IConfigKeys = keyof IEditConfigType;
118
119
  /**
@@ -127,6 +128,7 @@ export declare class EditConfigModel {
127
128
  stopZoomGraph: boolean;
128
129
  stopMoveGraph: boolean;
129
130
  stopScrollGraph: boolean;
131
+ snapGrid: boolean;
130
132
  /*********************************************************
131
133
  * 文本相关配置(全局)
132
134
  ********************************************************/
@@ -168,7 +170,7 @@ export declare class EditConfigModel {
168
170
  multipleSelectKey: string;
169
171
  constructor(config: Partial<IEditConfigType>);
170
172
  updateEditConfig(config: Partial<IEditConfigType>): void;
171
- computeConfig(config: Partial<IEditConfigType>): Partial<IEditConfigType> & Pick<Partial<IEditConfigType>, "textMode" | "adjustEdgeStartAndEnd" | "isSilentMode" | "stopZoomGraph" | "stopScrollGraph" | "stopMoveGraph" | "adjustEdge" | "adjustEdgeMiddle" | "adjustEdgeStart" | "adjustEdgeEnd" | "adjustNodePosition" | "hideAnchors" | "allowRotate" | "allowResize" | "autoExpand" | "hoverOutline" | "nodeSelectedOutline" | "edgeSelectedOutline" | "textEdit" | "nodeTextEdit" | "edgeTextEdit" | "textDraggable" | "nodeTextDraggable" | "edgeTextDraggable" | "multipleSelectKey" | "nodeTextMode" | "edgeTextMode" | "nodeTextMultiple" | "edgeTextMultiple" | "nodeTextVertical" | "edgeTextVertical">;
173
+ computeConfig(config: Partial<IEditConfigType>): Partial<IEditConfigType> & Pick<Partial<IEditConfigType>, "textMode" | "adjustEdgeStartAndEnd" | "edgeTextDraggable" | "edgeTextEdit" | "nodeTextDraggable" | "nodeTextEdit" | "isSilentMode" | "stopZoomGraph" | "stopScrollGraph" | "stopMoveGraph" | "snapGrid" | "adjustEdge" | "adjustEdgeMiddle" | "adjustEdgeStart" | "adjustEdgeEnd" | "adjustNodePosition" | "hideAnchors" | "allowRotate" | "allowResize" | "autoExpand" | "hoverOutline" | "nodeSelectedOutline" | "edgeSelectedOutline" | "textEdit" | "textDraggable" | "multipleSelectKey" | "nodeTextMode" | "edgeTextMode" | "nodeTextMultiple" | "edgeTextMultiple" | "nodeTextVertical" | "edgeTextVertical">;
172
174
  updateTextMode(textMode: TextMode): void;
173
175
  getConfig(): IEditConfigType;
174
176
  }
@@ -33,6 +33,7 @@ var allKeys = [
33
33
  'stopZoomGraph', // 禁止缩放画布
34
34
  'stopScrollGraph', // 禁止鼠标滚动移动画布
35
35
  'stopMoveGraph', // 禁止拖动画布
36
+ 'snapGrid', // 是否开启网格对齐
36
37
  'adjustEdge', // 允许调整边
37
38
  'adjustEdgeMiddle', // 允许调整边中点
38
39
  'adjustEdgeStartAndEnd', // 允许调整边起点和终点
@@ -74,6 +75,7 @@ var EditConfigModel = /** @class */ (function () {
74
75
  this.stopZoomGraph = false;
75
76
  this.stopMoveGraph = false;
76
77
  this.stopScrollGraph = false;
78
+ this.snapGrid = false;
77
79
  /*********************************************************
78
80
  * 文本相关配置(全局)
79
81
  ********************************************************/
@@ -188,6 +190,9 @@ var EditConfigModel = /** @class */ (function () {
188
190
  __decorate([
189
191
  observable
190
192
  ], EditConfigModel.prototype, "stopScrollGraph", void 0);
193
+ __decorate([
194
+ observable
195
+ ], EditConfigModel.prototype, "snapGrid", void 0);
191
196
  __decorate([
192
197
  observable
193
198
  ], EditConfigModel.prototype, "textMode", void 0);
@@ -46,6 +46,14 @@ export declare class GraphModel {
46
46
  * 获取自定义连线轨迹
47
47
  */
48
48
  customTrajectory: LFOptions.Definition['customTrajectory'];
49
+ /**
50
+ * 判断是否使用的是容器的宽度
51
+ */
52
+ isContainerWidth: boolean;
53
+ /**
54
+ * 判断是否使用的是容器的高度
55
+ */
56
+ isContainerHeight: boolean;
49
57
  edgeType: string;
50
58
  nodes: BaseNodeModel[];
51
59
  edges: BaseEdgeModel[];
@@ -62,6 +70,7 @@ export declare class GraphModel {
62
70
  editConfigModel: EditConfigModel;
63
71
  partial: boolean;
64
72
  [propName: string]: any;
73
+ private waitCleanEffects;
65
74
  constructor(options: LFOptions.Common);
66
75
  get nodesMap(): GraphModel.NodesMapType;
67
76
  get edgesMap(): GraphModel.EdgesMapType;
@@ -70,15 +79,15 @@ export declare class GraphModel {
70
79
  * 基于zIndex对元素进行排序。
71
80
  * todo: 性能优化
72
81
  */
73
- get sortElements(): (BaseEdgeModel<LogicFlow.PropertiesType> | BaseNodeModel<LogicFlow.PropertiesType>)[];
82
+ get sortElements(): (BaseNodeModel<LogicFlow.PropertiesType> | BaseEdgeModel<LogicFlow.PropertiesType>)[];
74
83
  /**
75
84
  * 当前编辑的元素,低频操作,先循环找。
76
85
  */
77
- get textEditElement(): BaseEdgeModel<LogicFlow.PropertiesType> | BaseNodeModel<LogicFlow.PropertiesType> | undefined;
86
+ get textEditElement(): BaseNodeModel<LogicFlow.PropertiesType> | BaseEdgeModel<LogicFlow.PropertiesType> | undefined;
78
87
  /**
79
88
  * 当前画布所有被选中的元素
80
89
  */
81
- get selectElements(): Map<string, BaseEdgeModel<LogicFlow.PropertiesType> | BaseNodeModel<LogicFlow.PropertiesType>>;
90
+ get selectElements(): Map<string, BaseNodeModel<LogicFlow.PropertiesType> | BaseEdgeModel<LogicFlow.PropertiesType>>;
82
91
  get selectNodes(): BaseNodeModel<LogicFlow.PropertiesType>[];
83
92
  /**
84
93
  * 获取指定区域内的所有元素
@@ -390,7 +399,11 @@ export declare class GraphModel {
390
399
  */
391
400
  updateGridOptions(options: Partial<Grid.GridOptions>): void;
392
401
  /**
393
- * 更新网格配置
402
+ * 更新网格尺寸
403
+ */
404
+ updateGridSize(size: number): void;
405
+ /**
406
+ * 更新背景配置
394
407
  */
395
408
  updateBackgroundOptions(options: boolean | Partial<LFOptions.BackgroundConfig>): void;
396
409
  /**
@@ -437,6 +450,8 @@ export declare class GraphModel {
437
450
  * @returns
438
451
  */
439
452
  setPartial(partial: boolean): void;
453
+ /** 销毁当前实例 */
454
+ destroy(): void;
440
455
  }
441
456
  export declare namespace GraphModel {
442
457
  type NodesMapType = Record<string, {
@@ -15,6 +15,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
15
15
  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;
16
16
  return c > 3 && r && Object.defineProperty(target, key, r), r;
17
17
  };
18
+ var __values = (this && this.__values) || function(o) {
19
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
20
+ if (m) return m.call(o);
21
+ if (o && typeof o.length === "number") return {
22
+ next: function () {
23
+ if (o && i >= o.length) o = void 0;
24
+ return { value: o && o[i++], done: !o };
25
+ }
26
+ };
27
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
28
+ };
18
29
  var __read = (this && this.__read) || function (o, n) {
19
30
  var m = typeof Symbol === "function" && o[Symbol.iterator];
20
31
  if (!m) return o;
@@ -40,7 +51,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
40
51
  }
41
52
  return to.concat(ar || Array.prototype.slice.call(from));
42
53
  };
43
- import { find, forEach, map, merge, isBoolean, isEqual } from 'lodash-es';
54
+ import { find, forEach, map, merge, isBoolean, debounce, isNil, } from 'lodash-es';
44
55
  import { action, computed, observable } from 'mobx';
45
56
  import { EditConfigModel, TransformModel, } from '.';
46
57
  import { DEFAULT_VISIBLE_SPACE, ELEMENT_MAX_Z_INDEX, ElementState, ElementType, EventType, ModelType, OverlapMode, TextMode, } from '../constant';
@@ -49,6 +60,8 @@ import EventEmitter from '../event/eventEmitter';
49
60
  import { Grid } from '../view/overlay';
50
61
  var GraphModel = /** @class */ (function () {
51
62
  function GraphModel(options) {
63
+ var _this = this;
64
+ var _a, _b;
52
65
  // 维护所有节点和边类型对应的 model
53
66
  this.modelMap = new Map();
54
67
  // Remind:用于记录当前画布上所有节点和边的 model 的 Map
@@ -81,11 +94,14 @@ var GraphModel = /** @class */ (function () {
81
94
  this.gridSize = 1;
82
95
  // 控制是否开启局部渲染
83
96
  this.partial = false;
84
- 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;
97
+ this.waitCleanEffects = [];
98
+ 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;
85
99
  this.rootEl = container;
86
100
  this.partial = !!partial;
87
101
  this.background = background;
88
- if (typeof grid === 'object') {
102
+ if (typeof grid === 'object' && options.snapGrid) {
103
+ // 开启网格对齐时才根据网格尺寸设置步长
104
+ // TODO:需要让用户设置成 0 吗?后面可以讨论一下
89
105
  this.gridSize = grid.size || 1; // 默认 gridSize 设置为 1
90
106
  }
91
107
  this.theme = setupTheme(options.style);
@@ -93,8 +109,36 @@ var GraphModel = /** @class */ (function () {
93
109
  this.edgeType = options.edgeType || 'polyline';
94
110
  this.animation = setupAnimation(animation);
95
111
  this.overlapMode = options.overlapMode || OverlapMode.DEFAULT;
96
- this.width = options.width || this.rootEl.getBoundingClientRect().width;
97
- this.height = options.height || this.rootEl.getBoundingClientRect().height;
112
+ this.width = (_a = options.width) !== null && _a !== void 0 ? _a : this.rootEl.getBoundingClientRect().width;
113
+ this.isContainerWidth = isNil(options.width);
114
+ this.height = (_b = options.height) !== null && _b !== void 0 ? _b : this.rootEl.getBoundingClientRect().height;
115
+ this.isContainerHeight = isNil(options.height);
116
+ var resizeObserver = new ResizeObserver(debounce((function (entries) {
117
+ var e_1, _a;
118
+ try {
119
+ for (var entries_1 = __values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
120
+ var entry = entries_1_1.value;
121
+ if (entry.target === _this.rootEl) {
122
+ _this.resize();
123
+ _this.eventCenter.emit('graph:resize', {
124
+ target: _this.rootEl,
125
+ contentRect: entry.contentRect,
126
+ });
127
+ }
128
+ }
129
+ }
130
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
131
+ finally {
132
+ try {
133
+ if (entries_1_1 && !entries_1_1.done && (_a = entries_1.return)) _a.call(entries_1);
134
+ }
135
+ finally { if (e_1) throw e_1.error; }
136
+ }
137
+ }), 16));
138
+ resizeObserver.observe(this.rootEl);
139
+ this.waitCleanEffects.push(function () {
140
+ resizeObserver.disconnect();
141
+ });
98
142
  this.eventCenter = new EventEmitter();
99
143
  this.editConfigModel = new EditConfigModel(options);
100
144
  this.transformModel = new TransformModel(this.eventCenter, options);
@@ -350,17 +394,23 @@ var GraphModel = /** @class */ (function () {
350
394
  */
351
395
  GraphModel.prototype.graphDataToModel = function (graphData) {
352
396
  var _this = this;
353
- if (!this.width || !this.height) {
354
- this.resize();
355
- }
397
+ // 宽度必然存在,取消重新计算
398
+ // if (!this.width || !this.height) {
399
+ // this.resize()
400
+ // }
356
401
  if (!graphData) {
357
- this.nodes = [];
358
- this.edges = [];
402
+ this.clearData();
359
403
  return;
360
404
  }
405
+ this.elementsModelMap.clear();
406
+ this.nodeModelMap.clear();
407
+ this.edgeModelMap.clear();
361
408
  if (graphData.nodes) {
362
409
  this.nodes = map(graphData.nodes, function (node) {
363
- return _this.getModelAfterSnapToGrid(node);
410
+ var nodeModel = _this.getModelAfterSnapToGrid(node);
411
+ _this.elementsModelMap.set(nodeModel.id, nodeModel);
412
+ _this.nodeModelMap.set(nodeModel.id, nodeModel);
413
+ return nodeModel;
364
414
  });
365
415
  }
366
416
  else {
@@ -375,31 +425,6 @@ var GraphModel = /** @class */ (function () {
375
425
  throw new Error("\u627E\u4E0D\u5230".concat(edge.type, "\u5BF9\u5E94\u7684\u8FB9\u3002"));
376
426
  }
377
427
  var edgeModel = new Model(edge, _this);
378
- // 根据edgeModel中存储的数据找到当前画布上的起终锚点坐标
379
- // 判断当前起终锚点数据和Model中存储的起终点数据是否一致,不一致更新起终点信息
380
- 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;
381
- var updateAnchorPoint = function (node, anchorId, point, updatePoint) {
382
- var anchor = node === null || node === void 0 ? void 0 : node.anchors.find(function (anchor) { return anchor.id === anchorId; });
383
- if (anchor && !isEqual(anchor, point)) {
384
- updatePoint(anchor);
385
- }
386
- };
387
- var sourceNode = _this.getNodeModelById(sourceNodeId);
388
- var targetNode = _this.getNodeModelById(targetNodeId);
389
- updateAnchorPoint(sourceNode, sourceAnchorId, startPoint, edgeModel.updateStartPoint.bind(edgeModel));
390
- updateAnchorPoint(targetNode, targetAnchorId, endPoint, edgeModel.updateEndPoint.bind(edgeModel));
391
- // 而文本需要先算一下文本与默认文本位置之间的相对位置差
392
- // 再计算新路径的文本默认位置,加上相对位置差,得到调整后边的文本的位置
393
- if (text) {
394
- var x = text.x, y = text.y;
395
- var defaultX = textPosition.x, defaultY = textPosition.y;
396
- if (x && y && defaultX && defaultY) {
397
- var deltaX = x - defaultX;
398
- var deltaY = y - defaultY;
399
- edgeModel.resetTextPosition();
400
- edgeModel.moveText(deltaX, deltaY);
401
- }
402
- }
403
428
  _this.edgeModelMap.set(edgeModel.id, edgeModel);
404
429
  _this.elementsModelMap.set(edgeModel.id, edgeModel);
405
430
  return edgeModel;
@@ -733,14 +758,15 @@ var GraphModel = /** @class */ (function () {
733
758
  */
734
759
  GraphModel.prototype.getModelAfterSnapToGrid = function (node) {
735
760
  var Model = this.getModel(node.type);
761
+ var snapGrid = this.editConfigModel.snapGrid;
736
762
  if (!Model) {
737
763
  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"));
738
764
  }
739
765
  var nodeX = node.x, nodeY = node.y;
740
766
  // 根据 grid 修正节点的 x, y
741
767
  if (nodeX && nodeY) {
742
- node.x = snapToGrid(nodeX, this.gridSize);
743
- node.y = snapToGrid(nodeY, this.gridSize);
768
+ node.x = snapToGrid(nodeX, this.gridSize, snapGrid);
769
+ node.y = snapToGrid(nodeY, this.gridSize, snapGrid);
744
770
  if (typeof node.text === 'object' && node.text !== null) {
745
771
  // 原来的处理是:node.text.x -= getGridOffset(nodeX, this.gridSize)
746
772
  // 由于snapToGrid()使用了Math.round()四舍五入的做法,因此无法判断需要执行
@@ -1276,7 +1302,13 @@ var GraphModel = /** @class */ (function () {
1276
1302
  merge(this.grid, options);
1277
1303
  };
1278
1304
  /**
1279
- * 更新网格配置
1305
+ * 更新网格尺寸
1306
+ */
1307
+ GraphModel.prototype.updateGridSize = function (size) {
1308
+ this.gridSize = size;
1309
+ };
1310
+ /**
1311
+ * 更新背景配置
1280
1312
  */
1281
1313
  GraphModel.prototype.updateBackgroundOptions = function (options) {
1282
1314
  if (isBoolean(options) || isBoolean(this.background)) {
@@ -1290,8 +1322,10 @@ var GraphModel = /** @class */ (function () {
1290
1322
  * 重新设置画布的宽高
1291
1323
  */
1292
1324
  GraphModel.prototype.resize = function (width, height) {
1293
- this.width = width || this.rootEl.getBoundingClientRect().width;
1294
- this.height = height || this.rootEl.getBoundingClientRect().height;
1325
+ this.width = width !== null && width !== void 0 ? width : this.rootEl.getBoundingClientRect().width;
1326
+ this.isContainerWidth = isNil(width);
1327
+ this.height = height !== null && height !== void 0 ? height : this.rootEl.getBoundingClientRect().height;
1328
+ this.isContainerHeight = isNil(height);
1295
1329
  if (!this.width || !this.height) {
1296
1330
  console.warn('渲染画布的时候无法获取画布宽高,请确认在container已挂载到DOM。@see https://github.com/didi/LogicFlow/issues/675');
1297
1331
  }
@@ -1302,6 +1336,10 @@ var GraphModel = /** @class */ (function () {
1302
1336
  GraphModel.prototype.clearData = function () {
1303
1337
  this.nodes = [];
1304
1338
  this.edges = [];
1339
+ // 清除对已清除节点的引用
1340
+ this.edgeModelMap.clear();
1341
+ this.nodeModelMap.clear();
1342
+ this.elementsModelMap.clear();
1305
1343
  };
1306
1344
  /**
1307
1345
  * 获取图形区域虚拟矩型的尺寸和中心坐标
@@ -1407,6 +1445,19 @@ var GraphModel = /** @class */ (function () {
1407
1445
  GraphModel.prototype.setPartial = function (partial) {
1408
1446
  this.partial = partial;
1409
1447
  };
1448
+ /** 销毁当前实例 */
1449
+ GraphModel.prototype.destroy = function () {
1450
+ try {
1451
+ this.waitCleanEffects.forEach(function (fn) {
1452
+ fn();
1453
+ });
1454
+ }
1455
+ catch (err) {
1456
+ console.warn('error on destroy GraphModel', err);
1457
+ }
1458
+ this.waitCleanEffects.length = 0;
1459
+ this.eventCenter.destroy();
1460
+ };
1410
1461
  __decorate([
1411
1462
  observable
1412
1463
  ], GraphModel.prototype, "width", void 0);
@@ -317,6 +317,8 @@ var BaseEdgeModel = /** @class */ (function () {
317
317
  properties: properties,
318
318
  sourceNodeId: this.sourceNodeId,
319
319
  targetNodeId: this.targetNodeId,
320
+ sourceAnchorId: this.sourceAnchorId,
321
+ targetAnchorId: this.targetAnchorId,
320
322
  startPoint: assign({}, this.startPoint),
321
323
  endPoint: assign({}, this.endPoint),
322
324
  };
@@ -416,14 +418,15 @@ var BaseEdgeModel = /** @class */ (function () {
416
418
  */
417
419
  BaseEdgeModel.prototype.formatText = function (data) {
418
420
  var _a, _b, _c;
419
- var _d = this.textPosition, x = _d.x, y = _d.y;
421
+ var _d = this.graphModel.editConfigModel, edgeTextDraggable = _d.edgeTextDraggable, edgeTextEdit = _d.edgeTextEdit;
422
+ var _e = this.textPosition, x = _e.x, y = _e.y;
420
423
  var text = data.text;
421
424
  var textConfig = {
422
425
  value: '',
423
426
  x: x,
424
427
  y: y,
425
- draggable: false,
426
- editable: true,
428
+ draggable: edgeTextDraggable,
429
+ editable: edgeTextEdit,
427
430
  };
428
431
  if (text) {
429
432
  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;
@@ -70,6 +70,9 @@ var PolylineEdgeModel = /** @class */ (function (_super) {
70
70
  }
71
71
  PolylineEdgeModel.prototype.initEdgeData = function (data) {
72
72
  this.offset = 30;
73
+ if (data.pointsList) {
74
+ this.pointsList = data.pointsList;
75
+ }
73
76
  _super.prototype.initEdgeData.call(this, data);
74
77
  };
75
78
  PolylineEdgeModel.prototype.getEdgeStyle = function () {
@@ -282,6 +285,10 @@ var PolylineEdgeModel = /** @class */ (function (_super) {
282
285
  }
283
286
  return list;
284
287
  };
288
+ PolylineEdgeModel.prototype.updatePath = function (pointList) {
289
+ this.pointsList = pointList;
290
+ this.points = this.getPath(this.pointsList);
291
+ };
285
292
  PolylineEdgeModel.prototype.getData = function () {
286
293
  var data = _super.prototype.getData.call(this);
287
294
  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 支持重写
@@ -223,13 +223,14 @@ var BaseNodeModel = /** @class */ (function () {
223
223
  */
224
224
  BaseNodeModel.prototype.formatText = function (data) {
225
225
  var _a, _b, _c;
226
+ var _d = this.graphModel.editConfigModel, nodeTextDraggable = _d.nodeTextDraggable, nodeTextEdit = _d.nodeTextEdit;
226
227
  var x = data.x, y = data.y, text = data.text;
227
228
  var textConfig = {
228
229
  value: '',
229
230
  x: x,
230
231
  y: y,
231
- draggable: false,
232
- editable: true,
232
+ draggable: nodeTextDraggable,
233
+ editable: nodeTextEdit,
233
234
  };
234
235
  if (text) {
235
236
  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/es/tool/index.js CHANGED
@@ -67,6 +67,10 @@ var Tool = /** @class */ (function () {
67
67
  Tool.prototype.getInstance = function () {
68
68
  return this.instance;
69
69
  };
70
+ Tool.prototype.destroy = function () {
71
+ this.toolMap.clear();
72
+ this.disabledToolMap.clear();
73
+ };
70
74
  __decorate([
71
75
  observable
72
76
  ], 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 缩放
@@ -23,7 +23,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
23
23
  }
24
24
  return to.concat(ar || Array.prototype.slice.call(from));
25
25
  };
26
- export function snapToGrid(point, gridSize) {
26
+ export function snapToGrid(point, gridSize, snapGrid) {
27
+ // 开启节网格对齐时才根据网格尺寸校准坐标
28
+ if (!snapGrid)
29
+ return point;
27
30
  // 保证 x, y 的值为 gridSize 的整数倍
28
31
  return gridSize * Math.round(point / gridSize) || point;
29
32
  }