bpmn-auto-layout 0.1.1 → 0.2.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/README.md CHANGED
@@ -3,28 +3,27 @@
3
3
 
4
4
  # bpmn-auto-layout
5
5
 
6
- Get a layouted diagram of a bpmn-process without graphical representation.
6
+ [![CI](https://github.com/bpmn-io/bpmn-auto-layout/actions/workflows/CI.yml/badge.svg)](https://github.com/bpmn-io/bpmn-auto-layout/actions/workflows/CI.yml)
7
+
8
+ Get a layouted diagram of a BPMN process without graphical representation.
7
9
 
8
10
 
9
11
  ## Usage
10
12
 
11
- __Preconditions:__ This library needs [Node.js](https://nodejs.org/en/) to run.
13
+ This library works in [Node.js](https://nodejs.org/) and in the browser.
12
14
 
13
- The diagram has to have __exactly one single startevent__.
15
+ To layout diagrams these must have __exactly one single start event__.
14
16
 
15
17
  ```javascript
16
- var AutoLayout = require('bpmn-auto-layout');
17
-
18
- var diagramXML = '<bpmn:defintions ...></bpmn:defintions>';
18
+ import AutoLayout from 'bpmn-auto-layout';
19
19
 
20
- var autoLayout = new AutoLayout();
20
+ const diagramXML = '<bpmn:defintions ...></bpmn:defintions>';
21
21
 
22
- (async () => {
23
- var layoutedDiagramXML = await autoLayout.layoutProcess(diagramXML);
22
+ const autoLayout = new AutoLayout();
24
23
 
25
- console.log(layoutedDiagramXML);
26
- })();
24
+ const layoutedDiagramXML = await autoLayout.layoutProcess(diagramXML);
27
25
 
26
+ console.log(layoutedDiagramXML);
28
27
  ```
29
28
 
30
29
 
@@ -35,7 +34,7 @@ var autoLayout = new AutoLayout();
35
34
 
36
35
  ## Building
37
36
 
38
- ```
37
+ ```sh
39
38
  npm install
40
39
  npm run all
41
40
  ```
package/index.js CHANGED
@@ -1 +1 @@
1
- module.exports = require('./lib/AutoLayout');
1
+ export { default } from './lib/AutoLayout.js';
package/lib/AutoLayout.js CHANGED
@@ -1,72 +1,56 @@
1
- var BpmnModdle = require('bpmn-moddle');
2
- var Tree = require('./Tree');
3
- var DiFactory = require('./DiFactory');
1
+ import BpmnModdle from 'bpmn-moddle';
4
2
 
5
- var DiUtil = require('./DiUtil');
6
-
7
- var is = DiUtil.is;
8
- var getExpandedBounds = DiUtil.getExpandedBounds;
9
- var getBendpoints = DiUtil.getBendpoints;
3
+ import Tree from './Tree.js';
4
+ import DiFactory from './DiFactory.js';
5
+ import { is,getExpandedBounds, getBendpoints } from './DiUtil.js';
10
6
 
11
7
  var PADDING_NODE = 'padding_node';
12
8
 
13
9
 
14
- function AutoLayout() {
10
+ export default function AutoLayout() {
15
11
  this.moddle = new BpmnModdle();
16
12
  this.DiFactory = new DiFactory(this.moddle);
17
13
  this.nodeCount = -1;
18
14
  }
19
15
 
20
- module.exports = AutoLayout;
21
-
22
- AutoLayout.prototype.layoutProcess = function(xmlStr, callback) {
16
+ AutoLayout.prototype.layoutProcess = async function(xmlStr) {
23
17
  var self = this;
24
18
  var moddle = this.moddle;
25
19
  var createDiPlane = this.DiFactory.createDiPlane.bind(this.DiFactory);
26
20
  var createDiDiagram = this.DiFactory.createDiDiagram.bind(this.DiFactory);
27
21
 
28
- return new Promise(function(resolve, reject) {
29
-
30
- moddle.fromXML(xmlStr, function(error, moddleWithoutDi) {
31
- if (error) {
32
- return reject(error);
33
- }
34
-
35
- // create new di section
36
- var root = moddleWithoutDi.get('rootElements').find(el => el.$type === 'bpmn:Process');
37
- var rootDi = createDiPlane({
38
- id: 'BPMNPlane_1',
39
- bpmnElement: root
40
- });
41
- var newDiagram = createDiDiagram({
42
- id: 'BPMNDiagram_1',
43
- plane: rootDi
44
- });
45
- moddleWithoutDi.diagrams = [newDiagram];
46
-
47
- // build the tree layout
48
- self.tree = new Tree();
49
- self._addTreeNode(root, root.flowElements);
50
- self._buildTreeBreadFirstSearch(root);
51
- console.log('tree built');
52
- self.tree.UpdateTree();
53
- console.log('tree updated');
54
-
55
- // create di
56
- self._layoutTreeBreadFirstSearch(root, rootDi);
57
- console.log('bpmn element layout complete');
22
+ try {
23
+ var { rootElement: moddleWithoutDi } = await moddle.fromXML(xmlStr);
58
24
 
59
- moddle.toXML(moddleWithoutDi, function(err, result) {
60
-
61
- if (err) {
62
- return reject(err);
63
- }
64
-
65
- return resolve(result);
66
- });
25
+ // create new di section
26
+ var root = moddleWithoutDi.get('rootElements').find(el => el.$type === 'bpmn:Process');
27
+ var rootDi = createDiPlane({
28
+ id: 'BPMNPlane_1',
29
+ bpmnElement: root
67
30
  });
68
- });
69
-
31
+ var newDiagram = createDiDiagram({
32
+ id: 'BPMNDiagram_1',
33
+ plane: rootDi
34
+ });
35
+ moddleWithoutDi.diagrams = [ newDiagram ];
36
+
37
+ // build the tree layout
38
+ self.tree = new Tree();
39
+ self._addTreeNode(root, root.flowElements);
40
+ self._buildTreeBreadFirstSearch(root);
41
+ console.log('tree built');
42
+ self.tree.UpdateTree();
43
+ console.log('tree updated');
44
+
45
+ // create di
46
+ self._layoutTreeBreadFirstSearch(root, rootDi);
47
+ console.log('bpmn element layout complete');
48
+
49
+ var { xml: result } = await moddle.toXML(moddleWithoutDi);
50
+ return Promise.resolve(result);
51
+ } catch (error) {
52
+ return Promise.reject(error);
53
+ }
70
54
  };
71
55
 
72
56
  AutoLayout.prototype._buildTreeBreadFirstSearch = function(rootFlowElement) {
@@ -74,7 +58,7 @@ AutoLayout.prototype._buildTreeBreadFirstSearch = function(rootFlowElement) {
74
58
  var children = rootFlowElement.flowElements;
75
59
 
76
60
  // queue holds visited elements
77
- var queue = children ? [...children] : [];
61
+ var queue = children ? [ ...children ] : [];
78
62
  var elementOrConnection;
79
63
  var outgoings;
80
64
  while (queue.length !== 0) {
@@ -159,7 +143,7 @@ AutoLayout.prototype._explodeSubprocess = function(flowElement, flowElements) {
159
143
  self.tree.addParentToNode(child.id, subprocessNode.id);
160
144
  });
161
145
  }
162
- var childNodes = [...subprocessNode.children].filter(child => {
146
+ var childNodes = [ ...subprocessNode.children ].filter(child => {
163
147
  return !subprocessStartNodes.find(startNode => startNode.id === child.id);
164
148
  });
165
149
  childNodes.forEach(childNode => {
@@ -174,7 +158,7 @@ AutoLayout.prototype._explodeSubprocess = function(flowElement, flowElements) {
174
158
 
175
159
  // remove parents from subprocessStartNodes
176
160
  subprocessStartNodes.forEach(subprocessStartNode => {
177
- var parents = [...subprocessStartNode.parents];
161
+ var parents = [ ...subprocessStartNode.parents ];
178
162
  parents.forEach(parentNode => {
179
163
  this.tree.removeParentFromNode(subprocessStartNode.id, parentNode.id);
180
164
  });
@@ -250,7 +234,7 @@ AutoLayout.prototype._balanceTreeNodeParentLevels = function(node) {
250
234
  var maxParentLevel = node._getLevel() - 1;
251
235
 
252
236
  // pad out levels such that node parents are at same level
253
- var oldParents = [...node.parents];
237
+ var oldParents = [ ...node.parents ];
254
238
  oldParents.forEach(parent => {
255
239
  let padParent = parent;
256
240
  while (padParent._getLevel() < maxParentLevel) {
@@ -290,7 +274,7 @@ AutoLayout.prototype._layoutTreeBreadFirstSearch = function(parentFlowElement, r
290
274
  }
291
275
 
292
276
  // queue holds visited elements
293
- var queue = startEvents ? [...startEvents] : [];
277
+ var queue = startEvents ? [ ...startEvents ] : [];
294
278
  var elementOrConnection;
295
279
  var outgoings;
296
280
  while (queue.length !== 0) {
@@ -342,8 +326,8 @@ AutoLayout.prototype._groupElement = function(elementOrConnection, group, parent
342
326
  } else {
343
327
  this._layoutGroup(group, parentDi);
344
328
  group = {
345
- elements: elementOrConnection.$type === 'bpmn:SequenceFlow' ? [] : [elementOrConnection],
346
- connections: elementOrConnection.$type === 'bpmn:SequenceFlow' ? [elementOrConnection] : [],
329
+ elements: elementOrConnection.$type === 'bpmn:SequenceFlow' ? [] : [ elementOrConnection ],
330
+ connections: elementOrConnection.$type === 'bpmn:SequenceFlow' ? [ elementOrConnection ] : [],
347
331
  distance: elementOrConnection.dist
348
332
  };
349
333
  }
@@ -430,7 +414,7 @@ AutoLayout.prototype._layoutConnections = function(group, parentDi) {
430
414
  // this connection needs to accommodate padding nodes
431
415
  // check for any padding nodes and go through those coords
432
416
  var oldPoints = connectionDi.waypoint;
433
- var newPoints = [oldPoints[0]];
417
+ var newPoints = [ oldPoints[0] ];
434
418
 
435
419
  // get node for sourceRef
436
420
  var pathNodes = getPathToTarget(sourceNode, targetRef.id);
@@ -486,7 +470,7 @@ function getPathToTarget(sourceNode, targetId) {
486
470
  return undefined;
487
471
  }
488
472
  if (sourceNode.dsc === targetId) {
489
- return [sourceNode];
473
+ return [ sourceNode ];
490
474
  }
491
475
  if (sourceNode.children) {
492
476
  let pathToTarget;
@@ -499,7 +483,7 @@ function getPathToTarget(sourceNode, targetId) {
499
483
  }
500
484
  });
501
485
  if (pathToTarget) {
502
- return [sourceNode, ...pathToTarget];
486
+ return [ sourceNode, ...pathToTarget ];
503
487
  }
504
488
  }
505
489
  return undefined;
package/lib/DiFactory.js CHANGED
@@ -1,23 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var map = require('min-dash').map;
4
- var assign = require('min-dash').assign;
5
- var pick = require('min-dash').pick;
3
+ import { map, assign, pick } from 'min-dash';
4
+ import { is, connectRectangles, getExpandedBounds } from './DiUtil.js';
6
5
 
7
- var DiUtil = require('./DiUtil');
8
-
9
- var is = DiUtil.is;
10
- var connectRectangles = DiUtil.connectRectangles;
11
- var getExpandedBounds = DiUtil.getExpandedBounds;
12
-
13
-
14
- function DiFactory(moddle) {
6
+ export default function DiFactory(moddle) {
15
7
  this._model = moddle;
16
8
  }
17
9
 
18
- module.exports = DiFactory;
19
-
20
-
21
10
  DiFactory.prototype._isExpanded = function(element) {
22
11
  return element && element.flowElements ? element.flowElements.length > 0 : false;
23
12
  };
@@ -52,7 +41,7 @@ DiFactory.prototype.createDiWaypoints = function(waypoints) {
52
41
  };
53
42
 
54
43
  DiFactory.prototype.createDiWaypoint = function(point) {
55
- return this.create('dc:Point', pick(point, ['x', 'y']));
44
+ return this.create('dc:Point', pick(point, [ 'x', 'y' ]));
56
45
  };
57
46
 
58
47
  DiFactory.prototype.createDiEdge = function(semantic, waypoints, attrs) {
package/lib/DiUtil.js CHANGED
@@ -138,12 +138,12 @@ function getBendpoints(a, b, directions) {
138
138
 
139
139
  // one point, next to a
140
140
  if (directions === 'h:v') {
141
- return [{ x: b.x, y: a.y }];
141
+ return [ { x: b.x, y: a.y } ];
142
142
  } else
143
143
 
144
144
  // one point, above a
145
145
  if (directions === 'v:h') {
146
- return [{ x: a.x, y: b.y }];
146
+ return [ { x: a.x, y: b.y } ];
147
147
  } else {
148
148
 
149
149
  // vertical edge xmid
@@ -248,7 +248,7 @@ function is(type, expected) {
248
248
  return findType;
249
249
  }
250
250
 
251
- module.exports = {
251
+ export {
252
252
  getExpandedBounds,
253
253
  connectRectangles,
254
254
  connectPoints,
package/lib/Tree.js CHANGED
@@ -80,7 +80,7 @@ TreeNode.prototype._getLastChild = function() {
80
80
  return this._getChildAt(this._getChildrenCount() - 1);
81
81
  };
82
82
 
83
- function Tree() {
83
+ export default function Tree() {
84
84
  this.config = {
85
85
  iMaxDepth: 1000,
86
86
  iLevelSeparation: 40,
@@ -101,8 +101,6 @@ function Tree() {
101
101
  this.iLastSearch = 0;
102
102
  }
103
103
 
104
- module.exports = Tree;
105
-
106
104
  // Layout algorithm
107
105
  Tree._firstWalk = function(tree, node, level, prevSiblings = []) {
108
106
 
@@ -128,7 +126,7 @@ Tree._firstWalk = function(tree, node, level, prevSiblings = []) {
128
126
  var n = node._getChildrenCount();
129
127
  for (var i = 0; i < n; i++) {
130
128
  var iChild = node._getChildAt(i);
131
- Tree._firstWalk(tree, iChild, level + 1, [...prevSiblings, iChild.id]);
129
+ Tree._firstWalk(tree, iChild, level + 1, [ ...prevSiblings, iChild.id ]);
132
130
  }
133
131
  var midPoint = node._getChildrenCenter(tree);
134
132
  midPoint -= tree._getNodeSize(node) / 2;
@@ -213,10 +211,10 @@ Tree._secondWalk = function(tree, node, level, X, Y, prevSiblings = []) {
213
211
  }
214
212
 
215
213
  if (node._getChildrenCount() !== 0) {
216
- Tree._secondWalk(tree, node._getFirstChild(), level + 1, X + node.modifier, Y + maxsizeTmp + tree.config.iLevelSeparation, [...prevSiblings, node.id]);
214
+ Tree._secondWalk(tree, node._getFirstChild(), level + 1, X + node.modifier, Y + maxsizeTmp + tree.config.iLevelSeparation, [ ...prevSiblings, node.id ]);
217
215
  }
218
216
  var rightSibling = node._getRightSibling();
219
- if (rightSibling != null && !prevSiblings.includes(rightSibling.id)) { Tree._secondWalk(tree, rightSibling, level, X, Y, [...prevSiblings, node.id]); }
217
+ if (rightSibling != null && !prevSiblings.includes(rightSibling.id)) { Tree._secondWalk(tree, rightSibling, level, X, Y, [ ...prevSiblings, node.id ]); }
220
218
  }
221
219
  };
222
220
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "bpmn-auto-layout",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Layout BPMN diagrams, generating missing DI information",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "files": [
7
8
  "lib"
8
9
  ],
@@ -26,13 +27,13 @@
26
27
  },
27
28
  "homepage": "https://github.com/bpmn-io/bpmn-auto-layout#readme",
28
29
  "dependencies": {
29
- "bpmn-moddle": "^6.0.0",
30
+ "bpmn-moddle": "^8.0.1",
30
31
  "min-dash": "^3.5.2"
31
32
  },
32
33
  "devDependencies": {
33
- "eslint": "^6.7.2",
34
- "eslint-plugin-bpmn-io": "^0.10.0",
35
- "mocha": "^6.2.2",
34
+ "eslint": "^8.41.0",
35
+ "eslint-plugin-bpmn-io": "^1.0.0",
36
+ "mocha": "^10.2.0",
36
37
  "npm-run-all": "^4.1.5"
37
38
  },
38
39
  "engines": {