bpmn-auto-layout 0.2.0 → 0.3.0

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/lib/Tree.js DELETED
@@ -1,335 +0,0 @@
1
- /*
2
- This tree is a version of ECOTree.js (by Emilio Cortegoso Lobato), with modifications.
3
- These modifications include:
4
- - supporting multiple parents
5
- - removed all node styling code
6
- - removed tree orientation code in favour of left to right orientation
7
- References:
8
- - ECOTree.js, Emilio Cortegoso Lobato
9
- - "A Node-Positioning Algorithm for General Trees", Walker II, J. Q.
10
- */
11
-
12
- function TreeNode(id, dsc, w, h) {
13
- this.id = id;
14
- this.dsc = dsc;
15
- this.w = w;
16
- this.h = h;
17
- this.dbIndex = 0;
18
- this.XPosition = 0;
19
- this.YPosition = 0;
20
- this.prelim = 0;
21
- this.modifier = 0;
22
- this.leftNeighbor = null;
23
- this.rightNeighbor = null;
24
- this.parents = [];
25
- this.children = [];
26
- }
27
-
28
- TreeNode.prototype._getLevel = function() {
29
- if (this.id === -1 || this.parents === undefined || this.parents.length === 0) {
30
- return 0;
31
- } else {
32
- let maxLevel = 0;
33
- this.parents.forEach(parent => {
34
- var parentLevel = parent._getLevel();
35
- maxLevel = (maxLevel < parentLevel) ? parentLevel : maxLevel;
36
- });
37
- return maxLevel + 1;
38
- }
39
- };
40
-
41
- TreeNode.prototype._getChildrenCount = function() {
42
- return this.children ? this.children.length : 0;
43
- };
44
-
45
- TreeNode.prototype._getLeftSibling = function() {
46
- if (!this.leftNeighbor) {
47
- return null;
48
- }
49
- var haveSameParent = this.leftNeighbor.parents.find(lParent => {
50
- return this.parents.find(tParent => tParent.id === lParent.id);
51
- });
52
- return haveSameParent ? this.leftNeighbor : null;
53
- };
54
-
55
- TreeNode.prototype._getRightSibling = function() {
56
- if (!this.rightNeighbor) {
57
- return null;
58
- }
59
- var haveSameParent = this.rightNeighbor.parents.find(rParent => {
60
- return this.parents.find(tParent => tParent.id === rParent.id);
61
- });
62
- return haveSameParent ? this.rightNeighbor : null;
63
- };
64
-
65
- TreeNode.prototype._getChildAt = function(i) {
66
- return this.children[i];
67
- };
68
-
69
- TreeNode.prototype._getChildrenCenter = function(tree) {
70
- var first = this._getFirstChild();
71
- var last = this._getLastChild();
72
- return first.prelim + ((last.prelim - first.prelim) + tree._getNodeSize(last)) / 2;
73
- };
74
-
75
- TreeNode.prototype._getFirstChild = function() {
76
- return this._getChildAt(0);
77
- };
78
-
79
- TreeNode.prototype._getLastChild = function() {
80
- return this._getChildAt(this._getChildrenCount() - 1);
81
- };
82
-
83
- export default function Tree() {
84
- this.config = {
85
- iMaxDepth: 1000,
86
- iLevelSeparation: 40,
87
- iSiblingSeparation: 40,
88
- iSubtreeSeparation: 60,
89
- topXAdjustment: 0,
90
- topYAdjustment: 0
91
- };
92
- this.self = this;
93
- this.maxLevelHeight = [];
94
- this.maxLevelWidth = [];
95
- this.previousLevelNode = [];
96
- this.rootYOffset = 0;
97
- this.rootXOffset = 0;
98
- this.nDatabaseNodes = [];
99
- this.mapIDs = {};
100
- this.root = new TreeNode(-1, null, null, 2, 2);
101
- this.iLastSearch = 0;
102
- }
103
-
104
- // Layout algorithm
105
- Tree._firstWalk = function(tree, node, level, prevSiblings = []) {
106
-
107
- // console.log('_firstWalk()')
108
- var leftSibling = null;
109
- node.XPosition = 0;
110
- node.YPosition = 0;
111
- node.prelim = 0;
112
- node.modifier = 0;
113
- node.leftNeighbor = null;
114
- node.rightNeighbor = null;
115
- tree._setLevelHeight(node, level);
116
- tree._setLevelWidth(node, level);
117
- tree._setNeighbors(node, level);
118
- if (node._getChildrenCount() === 0 || level === tree.config.iMaxDepth) {
119
- leftSibling = node._getLeftSibling();
120
- if (leftSibling != null) {
121
- node.prelim = leftSibling.prelim + tree._getNodeSize(leftSibling) + tree.config.iSiblingSeparation;
122
- } else {
123
- node.prelim = 0;
124
- }
125
- } else {
126
- var n = node._getChildrenCount();
127
- for (var i = 0; i < n; i++) {
128
- var iChild = node._getChildAt(i);
129
- Tree._firstWalk(tree, iChild, level + 1, [ ...prevSiblings, iChild.id ]);
130
- }
131
- var midPoint = node._getChildrenCenter(tree);
132
- midPoint -= tree._getNodeSize(node) / 2;
133
- leftSibling = node._getLeftSibling();
134
- if (leftSibling != null && !prevSiblings.includes(leftSibling.id)) {
135
- node.prelim = leftSibling.prelim + tree._getNodeSize(leftSibling) + tree.config.iSiblingSeparation;
136
- node.modifier = node.prelim - midPoint;
137
- Tree._apportion(tree, node, level);
138
- } else {
139
- node.prelim = midPoint;
140
- }
141
- }
142
- };
143
-
144
- Tree._apportion = function(tree, node, level) {
145
-
146
- // console.log('_apportion()')
147
- var firstChild = node._getFirstChild();
148
- var firstChildLeftNeighbor = firstChild.leftNeighbor;
149
- var j = 1;
150
- for (var k = tree.config.iMaxDepth - level; firstChild != null && firstChildLeftNeighbor != null && j <= k;) {
151
- var modifierSumRight = 0;
152
- var modifierSumLeft = 0;
153
- var rightAncestor = firstChild;
154
- var leftAncestor = firstChildLeftNeighbor;
155
- for (var l = 0; l < j; l++) {
156
- rightAncestor = rightAncestor.parents[0];
157
- leftAncestor = leftAncestor.parents[0];
158
- modifierSumRight += rightAncestor.modifier;
159
- modifierSumLeft += leftAncestor.modifier;
160
- }
161
- var totalGap = (firstChildLeftNeighbor.prelim + modifierSumLeft + tree._getNodeSize(firstChildLeftNeighbor) + tree.config.iSubtreeSeparation) - (firstChild.prelim + modifierSumRight);
162
- if (totalGap > 0) {
163
- var subtreeAux = node;
164
- var numSubtrees = 0;
165
- for (; subtreeAux != null && subtreeAux !== leftAncestor; subtreeAux = subtreeAux._getLeftSibling()) {
166
- numSubtrees++;
167
- }
168
- if (subtreeAux != null) {
169
- var subtreeMoveAux = node;
170
- var singleGap = totalGap / numSubtrees;
171
- for (; subtreeMoveAux !== leftAncestor; subtreeMoveAux = subtreeMoveAux._getLeftSibling()) {
172
- subtreeMoveAux.prelim += totalGap;
173
- subtreeMoveAux.modifier += totalGap;
174
- totalGap -= singleGap;
175
- }
176
- }
177
- }
178
- j++;
179
- if (firstChild._getChildrenCount() === 0) {
180
- firstChild = tree._getLeftmost(node, 0, j);
181
- } else {
182
- firstChild = firstChild._getFirstChild();
183
- }
184
- if (firstChild != null) {
185
- firstChildLeftNeighbor = firstChild.leftNeighbor;
186
- }
187
- }
188
- };
189
-
190
- Tree._secondWalk = function(tree, node, level, X, Y, prevSiblings = []) {
191
-
192
- // console.log('_secondWalk()')
193
- if (level <= tree.config.iMaxDepth) {
194
- var xTmp = tree.rootXOffset + node.prelim + X;
195
- var yTmp = tree.rootYOffset + Y;
196
- var maxsizeTmp = 0;
197
- var nodesizeTmp = 0;
198
- var flag = false;
199
-
200
- maxsizeTmp = tree.maxLevelWidth[level];
201
- flag = true;
202
- nodesizeTmp = node.w;
203
-
204
- node.XPosition = xTmp;
205
- node.YPosition = yTmp + (maxsizeTmp - nodesizeTmp) / 2;
206
-
207
- if (flag) {
208
- var swapTmp = node.XPosition;
209
- node.XPosition = node.YPosition;
210
- node.YPosition = swapTmp;
211
- }
212
-
213
- if (node._getChildrenCount() !== 0) {
214
- Tree._secondWalk(tree, node._getFirstChild(), level + 1, X + node.modifier, Y + maxsizeTmp + tree.config.iLevelSeparation, [ ...prevSiblings, node.id ]);
215
- }
216
- var rightSibling = node._getRightSibling();
217
- if (rightSibling != null && !prevSiblings.includes(rightSibling.id)) { Tree._secondWalk(tree, rightSibling, level, X, Y, [ ...prevSiblings, node.id ]); }
218
- }
219
- };
220
-
221
- Tree.prototype._positionTree = function() {
222
-
223
- // console.log('_positionTree()')
224
- this.maxLevelHeight = [];
225
- this.maxLevelWidth = [];
226
- this.previousLevelNode = [];
227
- Tree._firstWalk(this.self, this.root, 0);
228
- this.rootXOffset = this.config.topXAdjustment + this.root.XPosition;
229
- this.rootYOffset = this.config.topYAdjustment + this.root.YPosition;
230
- Tree._secondWalk(this.self, this.root, 0, 0, 0);
231
- };
232
-
233
- Tree.prototype._setLevelHeight = function(node, level) {
234
- if (this.maxLevelHeight[level] == null) { this.maxLevelHeight[level] = 0; }
235
- if (this.maxLevelHeight[level] < node.h) { this.maxLevelHeight[level] = node.h; }
236
- };
237
-
238
- Tree.prototype._setLevelWidth = function(node, level) {
239
- if (this.maxLevelWidth[level] == null) { this.maxLevelWidth[level] = 0; }
240
- if (this.maxLevelWidth[level] < node.w) { this.maxLevelWidth[level] = node.w; }
241
- };
242
-
243
- Tree.prototype._setNeighbors = function(node, level) {
244
- var tempNeighbour = this.previousLevelNode[level];
245
- if (tempNeighbour && tempNeighbour.id !== node.id) {
246
- node.leftNeighbor = this.previousLevelNode[level];
247
- if (node.leftNeighbor != null) {
248
- node.leftNeighbor.rightNeighbor = node;
249
- }
250
- }
251
- this.previousLevelNode[level] = node;
252
- };
253
-
254
- Tree.prototype._getNodeSize = function(node) {
255
- return node.h;
256
- };
257
-
258
- Tree.prototype._getLeftmost = function(node, level, maxlevel) {
259
- if (level >= maxlevel) return node;
260
- if (node._getChildrenCount() === 0) return null;
261
-
262
- var n = node._getChildrenCount();
263
- for (var i = 0; i < n; i++) {
264
- var iChild = node._getChildAt(i);
265
- var leftmostDescendant = this._getLeftmost(iChild, level + 1, maxlevel);
266
- if (leftmostDescendant != null) { return leftmostDescendant; }
267
- }
268
-
269
- return null;
270
- };
271
-
272
- Tree.prototype.UpdateTree = function() {
273
- this._positionTree();
274
- };
275
-
276
- Tree.prototype.add = function(id, dsc, w, h) {
277
- var node = new TreeNode(id, dsc, w, h);
278
- var i = this.nDatabaseNodes.length;
279
- node.dbIndex = this.mapIDs[id] = i;
280
- this.nDatabaseNodes[i] = node;
281
- return node;
282
- };
283
-
284
- Tree.prototype.addParentToNode = function(nodeId, parentId) {
285
-
286
- // retrieve nodes from list
287
- var node = this.getNodeById(nodeId);
288
- var parent = (parentId === -1) ? this.root : this.getNodeById(parentId);
289
- if (node === undefined) {
290
- throw new Error('Node not found');
291
- }
292
- if (parent === undefined) {
293
- throw new Error('Parent node not found');
294
- }
295
-
296
- // confirm this parents hasn't already been added to this node
297
- var found = node.parents.find(parent => parent.id === parentId);
298
- if (found === undefined) {
299
- node.parents.push(parent);
300
-
301
- // confirm that the child hasnt been added to the parents children list
302
- found = parent.children.find(child => child.id === nodeId);
303
-
304
- if (found === undefined) {
305
- parent.children.push(node);
306
- }
307
- }
308
- };
309
-
310
- Tree.prototype.removeParentFromNode = function(nodeId, parentId) {
311
-
312
- // retrieve nodes from list
313
- var node = this.getNodeById(nodeId);
314
- var parent = (parentId === -1) ? this.root : this.getNodeById(parentId);
315
- if (node === undefined) {
316
- throw new Error('Node not found');
317
- }
318
- if (parent === undefined) {
319
- throw new Error('Parent node not found');
320
- }
321
-
322
- // remove the parent node from node parents
323
- node.parents = node.parents.filter(parent => parent.id !== parentId);
324
-
325
- // remove the ndoe form the parent children list
326
- parent.children = parent.children.filter(child => child.id !== nodeId);
327
- };
328
-
329
- Tree.prototype.getNodeById = function(id) {
330
- return this.nDatabaseNodes.find(node => node.id === id);
331
- };
332
-
333
- Tree.prototype.getNodeByName = function(name) {
334
- return this.nDatabaseNodes.find(node => node.dsc === name);
335
- };