@logicflow/layout 1.2.0-alpha.15 → 1.2.0-alpha.16

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/cjs/dagre.js CHANGED
@@ -10,22 +10,6 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
- var __read = (this && this.__read) || function (o, n) {
14
- var m = typeof Symbol === "function" && o[Symbol.iterator];
15
- if (!m) return o;
16
- var i = m.call(o), r, ar = [], e;
17
- try {
18
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
19
- }
20
- catch (error) { e = { error: error }; }
21
- finally {
22
- try {
23
- if (r && !r.done && (m = i["return"])) m.call(i);
24
- }
25
- finally { if (e) throw e.error; }
26
- }
27
- return ar;
28
- };
29
13
  Object.defineProperty(exports, "__esModule", { value: true });
30
14
  exports.Dagre = void 0;
31
15
  var layout_1 = require("@antv/layout");
@@ -35,6 +19,25 @@ var Dagre = /** @class */ (function () {
35
19
  Dagre.prototype.render = function (lf) {
36
20
  this.lf = lf;
37
21
  };
22
+ Dagre.prototype.getBytesLength = function (word) {
23
+ if (!word) {
24
+ return 0;
25
+ }
26
+ var totalLength = 0;
27
+ for (var i = 0; i < word.length; i++) {
28
+ var c = word.charCodeAt(i);
29
+ if ((word.match(/[A-Z]/))) {
30
+ totalLength += 1.5;
31
+ }
32
+ else if ((c >= 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) {
33
+ totalLength += 1;
34
+ }
35
+ else {
36
+ totalLength += 2;
37
+ }
38
+ }
39
+ return totalLength;
40
+ };
38
41
  /**
39
42
  * option: {
40
43
  * rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
@@ -42,8 +45,8 @@ var Dagre = /** @class */ (function () {
42
45
  * nodeSize: undefined, // 节点大小
43
46
  * nodesepFunc: undefined, // 节点水平间距(px)
44
47
  * ranksepFunc: undefined, // 每一层节点之间间距
45
- * nodesep: 50, // 节点水平间距(px)
46
- * ranksep: 50, // 每一层节点之间间距
48
+ * nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
49
+ * ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
47
50
  * controlPoints: false, // 是否保留布局连线的控制点
48
51
  * radial: false, // 是否基于 dagre 进行辐射布局
49
52
  * focusNode: null, // radial 为 true 时生效,关注的节点
@@ -52,8 +55,19 @@ var Dagre = /** @class */ (function () {
52
55
  Dagre.prototype.layout = function (option) {
53
56
  var _this = this;
54
57
  if (option === void 0) { option = {}; }
55
- var _a = this.lf.graphModel, nodes = _a.nodes, edges = _a.edges;
56
- this.option = __assign({ type: 'dagre', rankdir: 'LR', nodesep: 20, begin: [100, 100] }, option);
58
+ var _a = this.lf.graphModel, nodes = _a.nodes, edges = _a.edges, gridSize = _a.gridSize;
59
+ // 为了保证生成的节点在girdSize上,需要处理一下。
60
+ var nodesep = 40;
61
+ var ranksep = 40;
62
+ if (gridSize > 20) {
63
+ nodesep = gridSize * 2;
64
+ ranksep = gridSize * 2;
65
+ }
66
+ this.option = __assign({ type: 'dagre', rankdir: 'LR',
67
+ // align: 'UL',
68
+ // align: 'UR',
69
+ align: 'DR', nodesep: nodesep,
70
+ ranksep: ranksep, begin: [120, 120] }, option);
57
71
  var layoutInstance = new layout_1.DagreLayout(this.option);
58
72
  var layoutData = layoutInstance.layout({
59
73
  nodes: nodes.map(function (node) { return ({
@@ -90,12 +104,13 @@ var Dagre = /** @class */ (function () {
90
104
  var data = model.getData();
91
105
  data.pointsList = _this.calcPointsList(model, newGraphData.nodes);
92
106
  if (data.pointsList) {
93
- var _a = __read(data.pointsList, 4), first = _a[0], next = _a[1], third = _a[2], last = _a[3];
107
+ var first = data.pointsList[0];
108
+ var last = data.pointsList[data.pointsList.length - 1];
94
109
  data.startPoint = { x: first.x, y: first.y };
95
110
  data.endPoint = { x: last.x, y: last.y };
96
111
  if (data.text && data.text.value) {
97
112
  data.text = {
98
- x: (third.x + last.x) / 2,
113
+ x: last.x - _this.getBytesLength(data.text.value) * 6 - 10,
99
114
  y: last.y,
100
115
  value: data.text.value,
101
116
  };
@@ -112,31 +127,91 @@ var Dagre = /** @class */ (function () {
112
127
  });
113
128
  this.lf.render(newGraphData);
114
129
  };
130
+ Dagre.prototype.pointFilter = function (points) {
131
+ var allPoints = points;
132
+ var i = 1;
133
+ while (i < allPoints.length - 1) {
134
+ var pre = allPoints[i - 1];
135
+ var current = allPoints[i];
136
+ var next = allPoints[i + 1];
137
+ if ((pre.x === current.x && current.x === next.x)
138
+ || (pre.y === current.y && current.y === next.y)) {
139
+ allPoints.splice(i, 1);
140
+ }
141
+ else {
142
+ i++;
143
+ }
144
+ }
145
+ return allPoints;
146
+ };
115
147
  Dagre.prototype.calcPointsList = function (model, nodes) {
116
- console.log(this.option.rankdir, model.modelType);
117
148
  // 在节点确认从左向右后,通过计算来保证节点连线清晰。
149
+ // TODO: 避障
150
+ var pointsList = [];
118
151
  if (this.option.rankdir === 'LR' && model.modelType === 'polyline-edge') {
119
152
  var sourceNodeModel = this.lf.getNodeModelById(model.sourceNodeId);
120
153
  var targetNodeModel = this.lf.getNodeModelById(model.targetNodeId);
121
154
  var newSourceNodeData = nodes.find(function (node) { return node.id === model.sourceNodeId; });
122
155
  var newTargetNodeData = nodes.find(function (node) { return node.id === model.targetNodeId; });
123
- var firstPoint = {
124
- x: newSourceNodeData.x + sourceNodeModel.width / 2,
125
- y: newSourceNodeData.y,
126
- };
127
- var nextPoint = {
128
- x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
129
- y: newSourceNodeData.y,
130
- };
131
- var thirdPoint = {
132
- x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
133
- y: newTargetNodeData.y,
134
- };
135
- var lastPoint = {
136
- x: newTargetNodeData.x - targetNodeModel.width / 2,
137
- y: newTargetNodeData.y,
138
- };
139
- return [firstPoint, nextPoint, thirdPoint, lastPoint];
156
+ if (newSourceNodeData.x < newTargetNodeData.x) {
157
+ pointsList.push({
158
+ x: newSourceNodeData.x + sourceNodeModel.width / 2,
159
+ y: newSourceNodeData.y,
160
+ });
161
+ pointsList.push({
162
+ x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
163
+ y: newSourceNodeData.y,
164
+ });
165
+ pointsList.push({
166
+ x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
167
+ y: newTargetNodeData.y,
168
+ });
169
+ pointsList.push({
170
+ x: newTargetNodeData.x - targetNodeModel.width / 2,
171
+ y: newTargetNodeData.y,
172
+ });
173
+ return this.pointFilter(pointsList);
174
+ }
175
+ // 向回连线
176
+ if (newSourceNodeData.x > newTargetNodeData.x) {
177
+ if (newSourceNodeData.y >= newTargetNodeData.y) {
178
+ pointsList.push({
179
+ x: newSourceNodeData.x,
180
+ y: newSourceNodeData.y + sourceNodeModel.height / 2,
181
+ });
182
+ pointsList.push({
183
+ x: newSourceNodeData.x,
184
+ y: newSourceNodeData.y + sourceNodeModel.height / 2 + (model.offset || 50),
185
+ });
186
+ pointsList.push({
187
+ x: newTargetNodeData.x,
188
+ y: newSourceNodeData.y + sourceNodeModel.height / 2 + (model.offset || 50),
189
+ });
190
+ pointsList.push({
191
+ x: newTargetNodeData.x,
192
+ y: newTargetNodeData.y + targetNodeModel.height / 2,
193
+ });
194
+ }
195
+ else {
196
+ pointsList.push({
197
+ x: newSourceNodeData.x,
198
+ y: newSourceNodeData.y - sourceNodeModel.height / 2,
199
+ });
200
+ pointsList.push({
201
+ x: newSourceNodeData.x,
202
+ y: newSourceNodeData.y - sourceNodeModel.height / 2 - (model.offset || 50),
203
+ });
204
+ pointsList.push({
205
+ x: newTargetNodeData.x,
206
+ y: newSourceNodeData.y - sourceNodeModel.height / 2 - (model.offset || 50),
207
+ });
208
+ pointsList.push({
209
+ x: newTargetNodeData.x,
210
+ y: newTargetNodeData.y - targetNodeModel.height / 2,
211
+ });
212
+ }
213
+ return this.pointFilter(pointsList);
214
+ }
140
215
  }
141
216
  return undefined;
142
217
  };
package/es/dagre.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare class Dagre {
4
4
  lf: any;
5
5
  option: DagreLayoutOptions;
6
6
  render(lf: any): void;
7
+ getBytesLength(word: string): number;
7
8
  /**
8
9
  * option: {
9
10
  * rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
@@ -11,16 +12,14 @@ export declare class Dagre {
11
12
  * nodeSize: undefined, // 节点大小
12
13
  * nodesepFunc: undefined, // 节点水平间距(px)
13
14
  * ranksepFunc: undefined, // 每一层节点之间间距
14
- * nodesep: 50, // 节点水平间距(px)
15
- * ranksep: 50, // 每一层节点之间间距
15
+ * nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
16
+ * ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
16
17
  * controlPoints: false, // 是否保留布局连线的控制点
17
18
  * radial: false, // 是否基于 dagre 进行辐射布局
18
19
  * focusNode: null, // radial 为 true 时生效,关注的节点
19
20
  * };
20
21
  */
21
22
  layout(option?: {}): void;
22
- calcPointsList(model: any, nodes: any): {
23
- x: any;
24
- y: any;
25
- }[];
23
+ pointFilter(points: any): any;
24
+ calcPointsList(model: any, nodes: any): any;
26
25
  }
package/es/dagre.js CHANGED
@@ -9,22 +9,6 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
- var __read = (this && this.__read) || function (o, n) {
13
- var m = typeof Symbol === "function" && o[Symbol.iterator];
14
- if (!m) return o;
15
- var i = m.call(o), r, ar = [], e;
16
- try {
17
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
18
- }
19
- catch (error) { e = { error: error }; }
20
- finally {
21
- try {
22
- if (r && !r.done && (m = i["return"])) m.call(i);
23
- }
24
- finally { if (e) throw e.error; }
25
- }
26
- return ar;
27
- };
28
12
  import { DagreLayout } from '@antv/layout';
29
13
  var Dagre = /** @class */ (function () {
30
14
  function Dagre() {
@@ -32,6 +16,25 @@ var Dagre = /** @class */ (function () {
32
16
  Dagre.prototype.render = function (lf) {
33
17
  this.lf = lf;
34
18
  };
19
+ Dagre.prototype.getBytesLength = function (word) {
20
+ if (!word) {
21
+ return 0;
22
+ }
23
+ var totalLength = 0;
24
+ for (var i = 0; i < word.length; i++) {
25
+ var c = word.charCodeAt(i);
26
+ if ((word.match(/[A-Z]/))) {
27
+ totalLength += 1.5;
28
+ }
29
+ else if ((c >= 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) {
30
+ totalLength += 1;
31
+ }
32
+ else {
33
+ totalLength += 2;
34
+ }
35
+ }
36
+ return totalLength;
37
+ };
35
38
  /**
36
39
  * option: {
37
40
  * rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
@@ -39,8 +42,8 @@ var Dagre = /** @class */ (function () {
39
42
  * nodeSize: undefined, // 节点大小
40
43
  * nodesepFunc: undefined, // 节点水平间距(px)
41
44
  * ranksepFunc: undefined, // 每一层节点之间间距
42
- * nodesep: 50, // 节点水平间距(px)
43
- * ranksep: 50, // 每一层节点之间间距
45
+ * nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
46
+ * ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
44
47
  * controlPoints: false, // 是否保留布局连线的控制点
45
48
  * radial: false, // 是否基于 dagre 进行辐射布局
46
49
  * focusNode: null, // radial 为 true 时生效,关注的节点
@@ -49,8 +52,19 @@ var Dagre = /** @class */ (function () {
49
52
  Dagre.prototype.layout = function (option) {
50
53
  var _this = this;
51
54
  if (option === void 0) { option = {}; }
52
- var _a = this.lf.graphModel, nodes = _a.nodes, edges = _a.edges;
53
- this.option = __assign({ type: 'dagre', rankdir: 'LR', nodesep: 20, begin: [100, 100] }, option);
55
+ var _a = this.lf.graphModel, nodes = _a.nodes, edges = _a.edges, gridSize = _a.gridSize;
56
+ // 为了保证生成的节点在girdSize上,需要处理一下。
57
+ var nodesep = 40;
58
+ var ranksep = 40;
59
+ if (gridSize > 20) {
60
+ nodesep = gridSize * 2;
61
+ ranksep = gridSize * 2;
62
+ }
63
+ this.option = __assign({ type: 'dagre', rankdir: 'LR',
64
+ // align: 'UL',
65
+ // align: 'UR',
66
+ align: 'DR', nodesep: nodesep,
67
+ ranksep: ranksep, begin: [120, 120] }, option);
54
68
  var layoutInstance = new DagreLayout(this.option);
55
69
  var layoutData = layoutInstance.layout({
56
70
  nodes: nodes.map(function (node) { return ({
@@ -87,12 +101,13 @@ var Dagre = /** @class */ (function () {
87
101
  var data = model.getData();
88
102
  data.pointsList = _this.calcPointsList(model, newGraphData.nodes);
89
103
  if (data.pointsList) {
90
- var _a = __read(data.pointsList, 4), first = _a[0], next = _a[1], third = _a[2], last = _a[3];
104
+ var first = data.pointsList[0];
105
+ var last = data.pointsList[data.pointsList.length - 1];
91
106
  data.startPoint = { x: first.x, y: first.y };
92
107
  data.endPoint = { x: last.x, y: last.y };
93
108
  if (data.text && data.text.value) {
94
109
  data.text = {
95
- x: (third.x + last.x) / 2,
110
+ x: last.x - _this.getBytesLength(data.text.value) * 6 - 10,
96
111
  y: last.y,
97
112
  value: data.text.value,
98
113
  };
@@ -109,31 +124,91 @@ var Dagre = /** @class */ (function () {
109
124
  });
110
125
  this.lf.render(newGraphData);
111
126
  };
127
+ Dagre.prototype.pointFilter = function (points) {
128
+ var allPoints = points;
129
+ var i = 1;
130
+ while (i < allPoints.length - 1) {
131
+ var pre = allPoints[i - 1];
132
+ var current = allPoints[i];
133
+ var next = allPoints[i + 1];
134
+ if ((pre.x === current.x && current.x === next.x)
135
+ || (pre.y === current.y && current.y === next.y)) {
136
+ allPoints.splice(i, 1);
137
+ }
138
+ else {
139
+ i++;
140
+ }
141
+ }
142
+ return allPoints;
143
+ };
112
144
  Dagre.prototype.calcPointsList = function (model, nodes) {
113
- console.log(this.option.rankdir, model.modelType);
114
145
  // 在节点确认从左向右后,通过计算来保证节点连线清晰。
146
+ // TODO: 避障
147
+ var pointsList = [];
115
148
  if (this.option.rankdir === 'LR' && model.modelType === 'polyline-edge') {
116
149
  var sourceNodeModel = this.lf.getNodeModelById(model.sourceNodeId);
117
150
  var targetNodeModel = this.lf.getNodeModelById(model.targetNodeId);
118
151
  var newSourceNodeData = nodes.find(function (node) { return node.id === model.sourceNodeId; });
119
152
  var newTargetNodeData = nodes.find(function (node) { return node.id === model.targetNodeId; });
120
- var firstPoint = {
121
- x: newSourceNodeData.x + sourceNodeModel.width / 2,
122
- y: newSourceNodeData.y,
123
- };
124
- var nextPoint = {
125
- x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
126
- y: newSourceNodeData.y,
127
- };
128
- var thirdPoint = {
129
- x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
130
- y: newTargetNodeData.y,
131
- };
132
- var lastPoint = {
133
- x: newTargetNodeData.x - targetNodeModel.width / 2,
134
- y: newTargetNodeData.y,
135
- };
136
- return [firstPoint, nextPoint, thirdPoint, lastPoint];
153
+ if (newSourceNodeData.x < newTargetNodeData.x) {
154
+ pointsList.push({
155
+ x: newSourceNodeData.x + sourceNodeModel.width / 2,
156
+ y: newSourceNodeData.y,
157
+ });
158
+ pointsList.push({
159
+ x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
160
+ y: newSourceNodeData.y,
161
+ });
162
+ pointsList.push({
163
+ x: newSourceNodeData.x + sourceNodeModel.width / 2 + (model.offset || 50),
164
+ y: newTargetNodeData.y,
165
+ });
166
+ pointsList.push({
167
+ x: newTargetNodeData.x - targetNodeModel.width / 2,
168
+ y: newTargetNodeData.y,
169
+ });
170
+ return this.pointFilter(pointsList);
171
+ }
172
+ // 向回连线
173
+ if (newSourceNodeData.x > newTargetNodeData.x) {
174
+ if (newSourceNodeData.y >= newTargetNodeData.y) {
175
+ pointsList.push({
176
+ x: newSourceNodeData.x,
177
+ y: newSourceNodeData.y + sourceNodeModel.height / 2,
178
+ });
179
+ pointsList.push({
180
+ x: newSourceNodeData.x,
181
+ y: newSourceNodeData.y + sourceNodeModel.height / 2 + (model.offset || 50),
182
+ });
183
+ pointsList.push({
184
+ x: newTargetNodeData.x,
185
+ y: newSourceNodeData.y + sourceNodeModel.height / 2 + (model.offset || 50),
186
+ });
187
+ pointsList.push({
188
+ x: newTargetNodeData.x,
189
+ y: newTargetNodeData.y + targetNodeModel.height / 2,
190
+ });
191
+ }
192
+ else {
193
+ pointsList.push({
194
+ x: newSourceNodeData.x,
195
+ y: newSourceNodeData.y - sourceNodeModel.height / 2,
196
+ });
197
+ pointsList.push({
198
+ x: newSourceNodeData.x,
199
+ y: newSourceNodeData.y - sourceNodeModel.height / 2 - (model.offset || 50),
200
+ });
201
+ pointsList.push({
202
+ x: newTargetNodeData.x,
203
+ y: newSourceNodeData.y - sourceNodeModel.height / 2 - (model.offset || 50),
204
+ });
205
+ pointsList.push({
206
+ x: newTargetNodeData.x,
207
+ y: newTargetNodeData.y - targetNodeModel.height / 2,
208
+ });
209
+ }
210
+ return this.pointFilter(pointsList);
211
+ }
137
212
  }
138
213
  return undefined;
139
214
  };