@aranzatech/diagrams-bpmn 0.2.15 → 0.3.1
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 +34 -4
- package/dist/{catalog-xOMF2ifW.d.cts → catalog-DAGDhO-D.d.cts} +1 -1
- package/dist/{catalog-CK3_4cOb.d.ts → catalog-Q1QmKLDD.d.ts} +1 -1
- package/dist/{chunk-YUE5EM3W.js → chunk-334WN4JZ.js} +276 -107
- package/dist/chunk-334WN4JZ.js.map +1 -0
- package/dist/chunk-77L6O76M.js +3 -0
- package/dist/chunk-77L6O76M.js.map +1 -0
- package/dist/{chunk-QSMP34CT.js → chunk-CPFUQM6H.js} +80 -44
- package/dist/chunk-CPFUQM6H.js.map +1 -0
- package/dist/{chunk-XMVV7FRZ.js → chunk-FFWJA5BV.js} +3 -3
- package/dist/{chunk-XMVV7FRZ.js.map → chunk-FFWJA5BV.js.map} +1 -1
- package/dist/{chunk-FBTGIYZS.js → chunk-JEGYVEJO.js} +80 -3
- package/dist/{chunk-FBTGIYZS.js.map → chunk-JEGYVEJO.js.map} +1 -1
- package/dist/chunk-TB6V4S5N.js +104 -0
- package/dist/chunk-TB6V4S5N.js.map +1 -0
- package/dist/{chunk-HOWK3ZOO.js → chunk-YAYZW45I.js} +379 -16
- package/dist/chunk-YAYZW45I.js.map +1 -0
- package/dist/edges/index.cjs +78 -42
- package/dist/edges/index.cjs.map +1 -1
- package/dist/edges/index.js +1 -1
- package/dist/elements/index.cjs +78 -0
- package/dist/elements/index.cjs.map +1 -1
- package/dist/elements/index.d.cts +24 -5
- package/dist/elements/index.d.ts +24 -5
- package/dist/elements/index.js +1 -1
- package/dist/elk-QT7H4252.js +6 -0
- package/dist/elk-QT7H4252.js.map +1 -0
- package/dist/extensions/index.cjs +108 -0
- package/dist/extensions/index.cjs.map +1 -0
- package/dist/extensions/index.d.cts +145 -0
- package/dist/extensions/index.d.ts +145 -0
- package/dist/extensions/index.js +4 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/index.cjs +922 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/layout/index.cjs +366 -90
- package/dist/layout/index.cjs.map +1 -1
- package/dist/layout/index.d.cts +4 -3
- package/dist/layout/index.d.ts +4 -3
- package/dist/layout/index.js +358 -92
- package/dist/layout/index.js.map +1 -1
- package/dist/modeling/index.cjs +387 -13
- package/dist/modeling/index.cjs.map +1 -1
- package/dist/modeling/index.d.cts +62 -4
- package/dist/modeling/index.d.ts +62 -4
- package/dist/modeling/index.js +1 -1
- package/dist/types-BX_o95GC.d.cts +40 -0
- package/dist/{types-y-ZbX-ff.d.ts → types-BYN4Zuee.d.cts} +15 -1
- package/dist/{types-y-ZbX-ff.d.cts → types-BYN4Zuee.d.ts} +15 -1
- package/dist/{types-jIDz306Y.d.cts → types-CggktCqr.d.cts} +4 -1
- package/dist/types-D7zel9dq.d.ts +40 -0
- package/dist/{types-DG5yPKld.d.ts → types-DmDODKlh.d.ts} +4 -1
- package/dist/validation/index.cjs +81 -125
- package/dist/validation/index.cjs.map +1 -1
- package/dist/validation/index.d.cts +22 -5
- package/dist/validation/index.d.ts +22 -5
- package/dist/validation/index.js +82 -126
- package/dist/validation/index.js.map +1 -1
- package/dist/xml/index.cjs +319 -49
- package/dist/xml/index.cjs.map +1 -1
- package/dist/xml/index.d.cts +5 -3
- package/dist/xml/index.d.ts +5 -3
- package/dist/xml/index.js +2 -1
- package/package.json +6 -1
- package/dist/chunk-HOWK3ZOO.js.map +0 -1
- package/dist/chunk-QSMP34CT.js.map +0 -1
- package/dist/chunk-YUE5EM3W.js.map +0 -1
- package/dist/elk-FSFIEL6O.js +0 -6
- package/dist/elk-FSFIEL6O.js.map +0 -1
- package/dist/guards-C70uIY_O.d.cts +0 -16
- package/dist/guards-foB6XIfZ.d.ts +0 -16
package/dist/layout/index.cjs
CHANGED
|
@@ -706,7 +706,9 @@ function inferBpmnEdgeType(state, sourceId, targetId) {
|
|
|
706
706
|
if (source.data.elementType === "Conversation" || source.data.elementType === "SubConversation" || source.data.elementType === "CallConversation" || target.data.elementType === "Conversation" || target.data.elementType === "SubConversation" || target.data.elementType === "CallConversation") {
|
|
707
707
|
return "conversationLink";
|
|
708
708
|
}
|
|
709
|
-
|
|
709
|
+
const sourcePoolId = getAncestorContainerId(state, source, "Pool");
|
|
710
|
+
const targetPoolId = getAncestorContainerId(state, target, "Pool");
|
|
711
|
+
if (sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId) {
|
|
710
712
|
return "messageFlow";
|
|
711
713
|
}
|
|
712
714
|
return "sequenceFlow";
|
|
@@ -744,6 +746,14 @@ function canContainBpmnElement(parentType, childType) {
|
|
|
744
746
|
}
|
|
745
747
|
return `${parentType} cannot contain BPMN child elements.`;
|
|
746
748
|
}
|
|
749
|
+
function getAncestorContainerId(state, node, elementType) {
|
|
750
|
+
let current = node;
|
|
751
|
+
while (current) {
|
|
752
|
+
if (current.data.elementType === elementType) return current.id;
|
|
753
|
+
current = current.parentId ? diagramsCore.getNode(state, current.parentId) : void 0;
|
|
754
|
+
}
|
|
755
|
+
return void 0;
|
|
756
|
+
}
|
|
747
757
|
function getBpmnNodeSize(node) {
|
|
748
758
|
return diagramsCore.getNodeSize(node, getBpmnElementSize(node.data.elementType));
|
|
749
759
|
}
|
|
@@ -1301,63 +1311,197 @@ function assignRows(nodes, forwardEdges, columns, gatewayPairs) {
|
|
|
1301
1311
|
|
|
1302
1312
|
// src/layout/bpmn-custom-layout.ts
|
|
1303
1313
|
var LANE_LABEL_W = 28;
|
|
1304
|
-
var LANE_H_PAD =
|
|
1305
|
-
var COL_GAP =
|
|
1306
|
-
var ROW_HEIGHT =
|
|
1307
|
-
var ROW_GAP =
|
|
1308
|
-
var LANE_V_PAD =
|
|
1309
|
-
var POOL_H_PAD =
|
|
1310
|
-
var POOL_V_GAP =
|
|
1311
|
-
var LANE_MIN_H =
|
|
1312
|
-
var POOL_MIN_W =
|
|
1313
|
-
var POOL_INNER_PAD =
|
|
1314
|
+
var LANE_H_PAD = 40;
|
|
1315
|
+
var COL_GAP = 100;
|
|
1316
|
+
var ROW_HEIGHT = 100;
|
|
1317
|
+
var ROW_GAP = 80;
|
|
1318
|
+
var LANE_V_PAD = 60;
|
|
1319
|
+
var POOL_H_PAD = 80;
|
|
1320
|
+
var POOL_V_GAP = 60;
|
|
1321
|
+
var LANE_MIN_H = 200;
|
|
1322
|
+
var POOL_MIN_W = 840;
|
|
1323
|
+
var POOL_INNER_PAD = 10;
|
|
1324
|
+
var BACK_EDGE_CLEARANCE = 70;
|
|
1325
|
+
var LAYOUT_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
1326
|
+
"DataObject",
|
|
1327
|
+
"DataObjectReference",
|
|
1328
|
+
"DataInput",
|
|
1329
|
+
"DataOutput",
|
|
1330
|
+
"DataStore",
|
|
1331
|
+
"DataStoreReference",
|
|
1332
|
+
"Annotation",
|
|
1333
|
+
"Group"
|
|
1334
|
+
]);
|
|
1335
|
+
var COLLAPSED_SUBPROCESS_TYPES = /* @__PURE__ */ new Set([
|
|
1336
|
+
"SubProcess",
|
|
1337
|
+
"Transaction",
|
|
1338
|
+
"EventSubProcess",
|
|
1339
|
+
"AdHocSubProcess"
|
|
1340
|
+
]);
|
|
1314
1341
|
function nW(node) {
|
|
1315
1342
|
return node.width ?? node.measured?.width ?? 120;
|
|
1316
1343
|
}
|
|
1317
1344
|
function nH(node) {
|
|
1318
1345
|
return node.height ?? node.measured?.height ?? 60;
|
|
1319
1346
|
}
|
|
1347
|
+
var BOUNDARY_SPACING = 10;
|
|
1348
|
+
function repositionBoundaryEvents(boundaryEvents, positionedContent) {
|
|
1349
|
+
if (boundaryEvents.length === 0) return [];
|
|
1350
|
+
const hostById = new Map(positionedContent.map((n) => [n.id, n]));
|
|
1351
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
1352
|
+
for (const be of boundaryEvents) {
|
|
1353
|
+
const hostId = be.data.attachedToRef;
|
|
1354
|
+
if (!hostId) continue;
|
|
1355
|
+
if (!byHost.has(hostId)) byHost.set(hostId, []);
|
|
1356
|
+
byHost.get(hostId).push(be);
|
|
1357
|
+
}
|
|
1358
|
+
const result = [];
|
|
1359
|
+
for (const be of boundaryEvents) {
|
|
1360
|
+
const hostId = be.data.attachedToRef;
|
|
1361
|
+
if (!hostId) {
|
|
1362
|
+
result.push(be);
|
|
1363
|
+
continue;
|
|
1364
|
+
}
|
|
1365
|
+
const host = hostById.get(hostId);
|
|
1366
|
+
if (!host) {
|
|
1367
|
+
result.push(be);
|
|
1368
|
+
continue;
|
|
1369
|
+
}
|
|
1370
|
+
const hostGroup = byHost.get(hostId);
|
|
1371
|
+
const siblingIdx = hostGroup.findIndex((n) => n.id === be.id);
|
|
1372
|
+
const hostW = nW(host);
|
|
1373
|
+
const hostH = nH(host);
|
|
1374
|
+
const beH = nH(be);
|
|
1375
|
+
const totalGroupW = hostGroup.reduce((s, b) => s + nW(b), 0) + (hostGroup.length - 1) * BOUNDARY_SPACING;
|
|
1376
|
+
const groupStartX = host.position.x + hostW / 2 - totalGroupW / 2;
|
|
1377
|
+
const offsetX = hostGroup.slice(0, siblingIdx).reduce((s, b) => s + nW(b) + BOUNDARY_SPACING, 0);
|
|
1378
|
+
result.push({
|
|
1379
|
+
...be,
|
|
1380
|
+
position: {
|
|
1381
|
+
x: groupStartX + offsetX,
|
|
1382
|
+
y: host.position.y + hostH - beH / 2
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
return result;
|
|
1387
|
+
}
|
|
1388
|
+
var SP_PAD = 48;
|
|
1389
|
+
function layoutSubProcess(children, edges) {
|
|
1390
|
+
if (children.length === 0) {
|
|
1391
|
+
return { children: [], width: 280, height: 160 };
|
|
1392
|
+
}
|
|
1393
|
+
const boundaryEvents = children.filter((n) => n.data.elementType === "BoundaryEvent");
|
|
1394
|
+
const mainChildren = children.filter((n) => n.data.elementType !== "BoundaryEvent");
|
|
1395
|
+
if (mainChildren.length === 0) {
|
|
1396
|
+
return {
|
|
1397
|
+
children: repositionBoundaryEvents(boundaryEvents, []),
|
|
1398
|
+
width: 280,
|
|
1399
|
+
height: 160
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
const contentIds = new Set(mainChildren.map((n) => n.id));
|
|
1403
|
+
const seqEdges = extractSeqEdges(edges, contentIds);
|
|
1404
|
+
const backIds = detectBackEdges([...contentIds], seqEdges);
|
|
1405
|
+
const fwdEdges = seqEdges.filter((e) => !backIds.has(e.id));
|
|
1406
|
+
const columns = assignColumns([...contentIds], fwdEdges);
|
|
1407
|
+
const pairs = detectGatewayPairs(mainChildren, fwdEdges);
|
|
1408
|
+
const rows = assignRows(mainChildren, fwdEdges, columns, pairs);
|
|
1409
|
+
const maxCol = Math.max(0, ...[...columns.values()]);
|
|
1410
|
+
const colW = /* @__PURE__ */ new Map();
|
|
1411
|
+
for (let c = 0; c <= maxCol; c++) colW.set(c, 0);
|
|
1412
|
+
for (const node of mainChildren) {
|
|
1413
|
+
const c = columns.get(node.id) ?? 0;
|
|
1414
|
+
colW.set(c, Math.max(colW.get(c) ?? 0, nW(node)));
|
|
1415
|
+
}
|
|
1416
|
+
const colX = /* @__PURE__ */ new Map();
|
|
1417
|
+
let cumX = 0;
|
|
1418
|
+
for (let c = 0; c <= maxCol; c++) {
|
|
1419
|
+
colX.set(c, cumX);
|
|
1420
|
+
cumX += (colW.get(c) ?? 120) + COL_GAP;
|
|
1421
|
+
}
|
|
1422
|
+
const contentW = cumX - COL_GAP;
|
|
1423
|
+
const rowVals = [...rows.values()];
|
|
1424
|
+
const minRow = Math.min(0, ...rowVals);
|
|
1425
|
+
const maxRow = Math.max(0, ...rowVals);
|
|
1426
|
+
const rowCount = maxRow - minRow + 1;
|
|
1427
|
+
const contentH = rowCount * ROW_HEIGHT + Math.max(0, rowCount - 1) * ROW_GAP;
|
|
1428
|
+
const spW = Math.max(280, SP_PAD * 2 + contentW);
|
|
1429
|
+
const spH = Math.max(160, SP_PAD * 2 + contentH);
|
|
1430
|
+
const positionedChildren = mainChildren.map((node) => {
|
|
1431
|
+
const c = columns.get(node.id) ?? 0;
|
|
1432
|
+
const r = rows.get(node.id) ?? 0;
|
|
1433
|
+
const colOffset = (colX.get(c) ?? 0) + (colW.get(c) ?? 120) / 2 - nW(node) / 2;
|
|
1434
|
+
const rowOffset = (r - minRow) * (ROW_HEIGHT + ROW_GAP) + ROW_HEIGHT / 2 - nH(node) / 2;
|
|
1435
|
+
return {
|
|
1436
|
+
...node,
|
|
1437
|
+
position: { x: SP_PAD + colOffset, y: SP_PAD + rowOffset }
|
|
1438
|
+
};
|
|
1439
|
+
});
|
|
1440
|
+
const positionedBoundaries = repositionBoundaryEvents(boundaryEvents, positionedChildren);
|
|
1441
|
+
return {
|
|
1442
|
+
children: [...positionedChildren, ...positionedBoundaries],
|
|
1443
|
+
width: spW,
|
|
1444
|
+
height: spH
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1320
1447
|
function layoutPool(pool, lanes, content, allEdges) {
|
|
1321
|
-
|
|
1448
|
+
const boundaryEvents = content.filter((n) => n.data.elementType === "BoundaryEvent");
|
|
1449
|
+
const mainContent = content.filter((n) => n.data.elementType !== "BoundaryEvent");
|
|
1450
|
+
if (mainContent.length === 0) {
|
|
1451
|
+
const positionedBoundaries2 = repositionBoundaryEvents(boundaryEvents, []);
|
|
1322
1452
|
if (lanes.length === 0) {
|
|
1323
|
-
return { nodes:
|
|
1453
|
+
return { nodes: positionedBoundaries2, width: 300, height: 140 };
|
|
1324
1454
|
}
|
|
1325
1455
|
const laneH = LANE_MIN_H;
|
|
1326
1456
|
const h = POOL_INNER_PAD * 2 + lanes.length * laneH + Math.max(0, lanes.length - 1) * POOL_INNER_PAD;
|
|
1327
|
-
const w = POOL_MIN_W;
|
|
1328
1457
|
return {
|
|
1329
|
-
nodes:
|
|
1330
|
-
...
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1458
|
+
nodes: [
|
|
1459
|
+
...positionedBoundaries2,
|
|
1460
|
+
...lanes.map((lane, i) => ({
|
|
1461
|
+
...lane,
|
|
1462
|
+
position: { x: POOL_INNER_PAD, y: POOL_INNER_PAD + i * (laneH + POOL_INNER_PAD) },
|
|
1463
|
+
width: POOL_MIN_W - POOL_INNER_PAD * 2,
|
|
1464
|
+
height: laneH
|
|
1465
|
+
}))
|
|
1466
|
+
],
|
|
1467
|
+
width: POOL_MIN_W,
|
|
1336
1468
|
height: h
|
|
1337
1469
|
};
|
|
1338
1470
|
}
|
|
1339
|
-
const contentIds = new Set(content.map((n) => n.id));
|
|
1340
|
-
const seqEdges = extractSeqEdges(allEdges, contentIds);
|
|
1341
|
-
const backIds = detectBackEdges([...contentIds], seqEdges);
|
|
1342
|
-
const fwdEdges = seqEdges.filter((e) => !backIds.has(e.id));
|
|
1343
|
-
const columns = assignColumns([...contentIds], fwdEdges);
|
|
1344
|
-
const pairs = detectGatewayPairs(content, fwdEdges);
|
|
1345
|
-
const rows = assignRows(content, fwdEdges, columns, pairs);
|
|
1346
1471
|
const lanePositionsDistinct = lanes.some((l) => Math.abs(l.position.y) > 10);
|
|
1347
1472
|
const sortedLanes = lanePositionsDistinct ? [...lanes].sort((a, b) => a.position.y - b.position.y) : [...lanes];
|
|
1348
1473
|
const hasLanes = sortedLanes.length > 0;
|
|
1474
|
+
const laneIdSet = new Set(sortedLanes.map((l) => l.id));
|
|
1349
1475
|
const nodeLaneId = /* @__PURE__ */ new Map();
|
|
1350
|
-
for (const node of
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1476
|
+
for (const node of mainContent) {
|
|
1477
|
+
const lId = hasLanes && node.parentId && laneIdSet.has(node.parentId) ? node.parentId : "_pool_";
|
|
1478
|
+
nodeLaneId.set(node.id, lId);
|
|
1479
|
+
}
|
|
1480
|
+
const contentIds = new Set(mainContent.map((n) => n.id));
|
|
1481
|
+
const seqEdges = extractSeqEdges(allEdges, contentIds);
|
|
1482
|
+
const backIds = detectBackEdges([...contentIds], seqEdges);
|
|
1483
|
+
const fwdEdges = seqEdges.filter((e) => !backIds.has(e.id));
|
|
1484
|
+
const columns = assignColumns([...contentIds], fwdEdges);
|
|
1485
|
+
const rows = /* @__PURE__ */ new Map();
|
|
1486
|
+
const contentByLane = /* @__PURE__ */ new Map();
|
|
1487
|
+
for (const node of mainContent) {
|
|
1488
|
+
const lId = nodeLaneId.get(node.id) ?? "_pool_";
|
|
1489
|
+
if (!contentByLane.has(lId)) contentByLane.set(lId, []);
|
|
1490
|
+
contentByLane.get(lId).push(node);
|
|
1491
|
+
}
|
|
1492
|
+
for (const [, laneNodes] of contentByLane) {
|
|
1493
|
+
const laneNodeIds = new Set(laneNodes.map((n) => n.id));
|
|
1494
|
+
const intraEdges = fwdEdges.filter(
|
|
1495
|
+
(e) => laneNodeIds.has(e.source) && laneNodeIds.has(e.target)
|
|
1496
|
+
);
|
|
1497
|
+
const lanePairs = detectGatewayPairs(laneNodes, intraEdges);
|
|
1498
|
+
const laneRows = assignRows(laneNodes, intraEdges, columns, lanePairs);
|
|
1499
|
+
for (const [id, row] of laneRows) rows.set(id, row);
|
|
1356
1500
|
}
|
|
1357
1501
|
const laneIds = hasLanes ? sortedLanes.map((l) => l.id) : ["_pool_"];
|
|
1358
1502
|
const laneStats = /* @__PURE__ */ new Map();
|
|
1359
1503
|
for (const laneId of laneIds) {
|
|
1360
|
-
const laneRows =
|
|
1504
|
+
const laneRows = mainContent.filter((n) => nodeLaneId.get(n.id) === laneId).map((n) => rows.get(n.id) ?? 0);
|
|
1361
1505
|
if (laneRows.length === 0) {
|
|
1362
1506
|
laneStats.set(laneId, { minRow: 0, maxRow: 0, rowCount: 1, height: LANE_MIN_H });
|
|
1363
1507
|
} else {
|
|
@@ -1372,7 +1516,7 @@ function layoutPool(pool, lanes, content, allEdges) {
|
|
|
1372
1516
|
const maxCol = Math.max(0, ...[...columns.values()]);
|
|
1373
1517
|
const colW = /* @__PURE__ */ new Map();
|
|
1374
1518
|
for (let c = 0; c <= maxCol; c++) colW.set(c, 0);
|
|
1375
|
-
for (const node of
|
|
1519
|
+
for (const node of mainContent) {
|
|
1376
1520
|
const c = columns.get(node.id) ?? 0;
|
|
1377
1521
|
colW.set(c, Math.max(colW.get(c) ?? 0, nW(node)));
|
|
1378
1522
|
}
|
|
@@ -1395,7 +1539,7 @@ function layoutPool(pool, lanes, content, allEdges) {
|
|
|
1395
1539
|
if (i < laneIds.length - 1) cumY += POOL_INNER_PAD;
|
|
1396
1540
|
}
|
|
1397
1541
|
const poolH = cumY + POOL_INNER_PAD;
|
|
1398
|
-
const positionedContent =
|
|
1542
|
+
const positionedContent = mainContent.map((node) => {
|
|
1399
1543
|
const c = columns.get(node.id) ?? 0;
|
|
1400
1544
|
const r = rows.get(node.id) ?? 0;
|
|
1401
1545
|
const laneId = nodeLaneId.get(node.id) ?? "_pool_";
|
|
@@ -1403,14 +1547,14 @@ function layoutPool(pool, lanes, content, allEdges) {
|
|
|
1403
1547
|
const lYOff = laneY.get(laneId) ?? 0;
|
|
1404
1548
|
const colOffset = (colX.get(c) ?? 0) + (colW.get(c) ?? 120) / 2 - nW(node) / 2;
|
|
1405
1549
|
const rowOffset = (r - stat.minRow) * (ROW_HEIGHT + ROW_GAP) + ROW_HEIGHT / 2 - nH(node) / 2;
|
|
1406
|
-
const isLaneChild = hasLanes && !!node.parentId && node.parentId !== pool.id;
|
|
1407
1550
|
const contentH_stat = stat.rowCount * ROW_HEIGHT + Math.max(0, stat.rowCount - 1) * ROW_GAP;
|
|
1408
1551
|
const vertTopOffset = Math.max(LANE_V_PAD, (stat.height - contentH_stat) / 2);
|
|
1552
|
+
const isLaneChild = hasLanes && !!node.parentId && node.parentId !== pool.id;
|
|
1409
1553
|
const x = isLaneChild ? LANE_LABEL_W + LANE_H_PAD + colOffset : POOL_H_PAD + colOffset;
|
|
1410
1554
|
const y = isLaneChild ? vertTopOffset + rowOffset : lYOff + vertTopOffset + rowOffset;
|
|
1411
1555
|
return { ...node, position: { x, y } };
|
|
1412
1556
|
});
|
|
1413
|
-
const NODE_MIN_GAP =
|
|
1557
|
+
const NODE_MIN_GAP = 24;
|
|
1414
1558
|
const resolvedContent = [...positionedContent];
|
|
1415
1559
|
for (const laneId of laneIds) {
|
|
1416
1560
|
const laneNodeIndices = resolvedContent.map((n, i) => ({ n, i })).filter(({ n }) => (nodeLaneId.get(n.id) ?? "_pool_") === laneId).sort((a, b) => a.n.position.x - b.n.position.x);
|
|
@@ -1427,30 +1571,24 @@ function layoutPool(pool, lanes, content, allEdges) {
|
|
|
1427
1571
|
if (prevRight + NODE_MIN_GAP > curr.position.x) {
|
|
1428
1572
|
resolvedContent[laneNodeIndices[k].i] = {
|
|
1429
1573
|
...curr,
|
|
1430
|
-
position: {
|
|
1431
|
-
x: prevRight + NODE_MIN_GAP,
|
|
1432
|
-
y: curr.position.y
|
|
1433
|
-
}
|
|
1574
|
+
position: { x: prevRight + NODE_MIN_GAP, y: curr.position.y }
|
|
1434
1575
|
};
|
|
1435
1576
|
}
|
|
1436
1577
|
}
|
|
1437
1578
|
}
|
|
1579
|
+
const positionedBoundaries = repositionBoundaryEvents(boundaryEvents, resolvedContent);
|
|
1438
1580
|
const positionedLanes = hasLanes ? sortedLanes.map((lane) => ({
|
|
1439
1581
|
...lane,
|
|
1440
|
-
// x: after pool label strip + left inner padding
|
|
1441
|
-
// y: laneY already includes top POOL_INNER_PAD offset
|
|
1442
1582
|
position: { x: POOL_INNER_PAD, y: laneY.get(lane.id) ?? POOL_INNER_PAD },
|
|
1443
1583
|
width: laneW,
|
|
1444
1584
|
height: laneStats.get(lane.id)?.height ?? LANE_MIN_H
|
|
1445
1585
|
})) : [];
|
|
1446
1586
|
return {
|
|
1447
|
-
nodes: [...resolvedContent, ...positionedLanes],
|
|
1587
|
+
nodes: [...resolvedContent, ...positionedBoundaries, ...positionedLanes],
|
|
1448
1588
|
width: poolW,
|
|
1449
1589
|
height: poolH
|
|
1450
1590
|
};
|
|
1451
1591
|
}
|
|
1452
|
-
var BACK_EDGE_CLEARANCE = 50;
|
|
1453
|
-
var SAME_ROW_THRESHOLD = 15;
|
|
1454
1592
|
function absolutePos(nodeId, byId, cache) {
|
|
1455
1593
|
const cached = cache.get(nodeId);
|
|
1456
1594
|
if (cached) return cached;
|
|
@@ -1469,10 +1607,17 @@ function absolutePos(nodeId, byId, cache) {
|
|
|
1469
1607
|
function laneOf(node, laneIds) {
|
|
1470
1608
|
return node.parentId && laneIds.has(node.parentId) ? node.parentId : void 0;
|
|
1471
1609
|
}
|
|
1610
|
+
function gapMidX(sAbs, sW, tAbs, tW) {
|
|
1611
|
+
const leftRightEdge = Math.min(sAbs.x + sW, tAbs.x + tW);
|
|
1612
|
+
const rightLeftEdge = Math.max(sAbs.x, tAbs.x);
|
|
1613
|
+
return leftRightEdge < rightLeftEdge ? (leftRightEdge + rightLeftEdge) / 2 : sAbs.x + sW / 2;
|
|
1614
|
+
}
|
|
1615
|
+
var SAME_ROW_THRESHOLD = 15;
|
|
1472
1616
|
function routeEdges(edges, layoutNodes, backEdgeIds, laneIds, poolIds) {
|
|
1473
1617
|
const byId = new Map(layoutNodes.map((n) => [n.id, n]));
|
|
1474
1618
|
const cache = /* @__PURE__ */ new Map();
|
|
1475
1619
|
const abs = (id) => absolutePos(id, byId, cache);
|
|
1620
|
+
const sortedLanes = [...laneIds].map((id) => byId.get(id)).filter((n) => !!n).sort((a, b) => abs(a.id).y - abs(b.id).y);
|
|
1476
1621
|
return edges.map((edge) => {
|
|
1477
1622
|
const edgeType = edge.data?.edgeType ?? edge.type;
|
|
1478
1623
|
if (edgeType !== "sequenceFlow") {
|
|
@@ -1487,11 +1632,22 @@ function routeEdges(edges, layoutNodes, backEdgeIds, laneIds, poolIds) {
|
|
|
1487
1632
|
const tAbs = abs(tgt.id);
|
|
1488
1633
|
const sW = nW(src), sH = nH(src);
|
|
1489
1634
|
const tW = nW(tgt), tH = nH(tgt);
|
|
1490
|
-
const sCX = sAbs.x + sW / 2
|
|
1491
|
-
const tCX = tAbs.x + tW / 2
|
|
1492
|
-
const
|
|
1493
|
-
const
|
|
1494
|
-
|
|
1635
|
+
const sCX = sAbs.x + sW / 2;
|
|
1636
|
+
const tCX = tAbs.x + tW / 2;
|
|
1637
|
+
const sCY = sAbs.y + sH / 2;
|
|
1638
|
+
const tCY = tAbs.y + tH / 2;
|
|
1639
|
+
const getPool = (nodeId) => {
|
|
1640
|
+
const node = byId.get(nodeId);
|
|
1641
|
+
if (!node) return null;
|
|
1642
|
+
if (poolIds.has(nodeId)) return nodeId;
|
|
1643
|
+
if (node.parentId && poolIds.has(node.parentId)) return node.parentId;
|
|
1644
|
+
if (node.parentId) {
|
|
1645
|
+
const gp = byId.get(node.parentId)?.parentId ?? null;
|
|
1646
|
+
if (gp && poolIds.has(gp)) return gp;
|
|
1647
|
+
}
|
|
1648
|
+
return node.parentId ?? null;
|
|
1649
|
+
};
|
|
1650
|
+
if (getPool(edge.source) !== getPool(edge.target)) {
|
|
1495
1651
|
const d = { ...edge.data };
|
|
1496
1652
|
delete d.routingPoints;
|
|
1497
1653
|
return { ...edge, data: d };
|
|
@@ -1501,33 +1657,49 @@ function routeEdges(edges, layoutNodes, backEdgeIds, laneIds, poolIds) {
|
|
|
1501
1657
|
const topY = Math.min(sAbs.y, tAbs.y) - BACK_EDGE_CLEARANCE;
|
|
1502
1658
|
routingPoints = [
|
|
1503
1659
|
{ x: sCX, y: sAbs.y },
|
|
1504
|
-
// [0] discarded
|
|
1505
1660
|
{ x: sCX, y: topY },
|
|
1506
|
-
// [1] go up
|
|
1507
1661
|
{ x: tCX, y: topY },
|
|
1508
|
-
|
|
1509
|
-
{ x: tCX, y: tAbs.y }
|
|
1510
|
-
// [3] discarded
|
|
1662
|
+
{ x: tCX, y: tAbs.y + tH }
|
|
1511
1663
|
];
|
|
1512
1664
|
} else if (laneOf(src, laneIds) !== laneOf(tgt, laneIds)) {
|
|
1513
|
-
const goingDown = tAbs.y > sAbs.y;
|
|
1514
|
-
const sharedX = Math.abs(sCX - tCX) < 10 ? sCX : (sCX + tCX) / 2;
|
|
1515
1665
|
const srcLane = byId.get(src.parentId ?? "");
|
|
1516
1666
|
const tgtLane = byId.get(tgt.parentId ?? "");
|
|
1517
1667
|
if (srcLane && tgtLane && laneIds.has(srcLane.id) && laneIds.has(tgtLane.id)) {
|
|
1518
|
-
const
|
|
1519
|
-
const
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
{ x: sharedX, y:
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1668
|
+
const goingDown = tAbs.y > sAbs.y;
|
|
1669
|
+
const sharedX = gapMidX(sAbs, sW, tAbs, tW);
|
|
1670
|
+
const srcLaneIdx = sortedLanes.findIndex((l) => l.id === srcLane.id);
|
|
1671
|
+
const tgtLaneIdx = sortedLanes.findIndex((l) => l.id === tgtLane.id);
|
|
1672
|
+
const pts = [];
|
|
1673
|
+
if (goingDown) {
|
|
1674
|
+
pts.push({ x: sCX, y: sAbs.y + sH });
|
|
1675
|
+
pts.push({ x: sharedX, y: sAbs.y + sH });
|
|
1676
|
+
const fromIdx = Math.min(srcLaneIdx, tgtLaneIdx);
|
|
1677
|
+
const toIdx = Math.max(srcLaneIdx, tgtLaneIdx);
|
|
1678
|
+
for (let i = fromIdx; i < toIdx; i++) {
|
|
1679
|
+
const lane = sortedLanes[i];
|
|
1680
|
+
const laneBot = abs(lane.id).y + (lane.height ?? LANE_MIN_H);
|
|
1681
|
+
pts.push({ x: sharedX, y: laneBot });
|
|
1682
|
+
}
|
|
1683
|
+
const lastY = pts[pts.length - 1].y;
|
|
1684
|
+
pts.push({ x: tCX, y: lastY });
|
|
1685
|
+
pts.push({ x: tCX, y: tAbs.y + tH });
|
|
1686
|
+
} else {
|
|
1687
|
+
pts.push({ x: sCX, y: sAbs.y });
|
|
1688
|
+
pts.push({ x: sharedX, y: sAbs.y });
|
|
1689
|
+
const fromIdx = Math.min(srcLaneIdx, tgtLaneIdx);
|
|
1690
|
+
const toIdx = Math.max(srcLaneIdx, tgtLaneIdx);
|
|
1691
|
+
for (let i = toIdx; i > fromIdx; i--) {
|
|
1692
|
+
const lane = sortedLanes[i];
|
|
1693
|
+
const laneTop = abs(lane.id).y;
|
|
1694
|
+
pts.push({ x: sharedX, y: laneTop });
|
|
1695
|
+
}
|
|
1696
|
+
const lastY = pts[pts.length - 1].y;
|
|
1697
|
+
pts.push({ x: tCX, y: lastY });
|
|
1698
|
+
pts.push({ x: tCX, y: tAbs.y });
|
|
1699
|
+
}
|
|
1700
|
+
routingPoints = pts;
|
|
1530
1701
|
} else {
|
|
1702
|
+
const sharedX = gapMidX(sAbs, sW, tAbs, tW);
|
|
1531
1703
|
routingPoints = [
|
|
1532
1704
|
{ x: sCX, y: sCY },
|
|
1533
1705
|
{ x: sharedX, y: sCY },
|
|
@@ -1546,39 +1718,108 @@ function routeEdges(edges, layoutNodes, backEdgeIds, laneIds, poolIds) {
|
|
|
1546
1718
|
if (exitsTop || exitsBottom) {
|
|
1547
1719
|
routingPoints = [
|
|
1548
1720
|
{ x: sCX, y: exitsTop ? sAbs.y : sAbs.y + sH },
|
|
1549
|
-
// [0] discarded
|
|
1550
1721
|
{ x: sCX, y: tCY },
|
|
1551
|
-
// [1] vertical to target row
|
|
1552
1722
|
{ x: tCX, y: tCY },
|
|
1553
|
-
// [2] horizontal to target
|
|
1554
1723
|
{ x: tCX, y: exitsTop ? tAbs.y + tH : tAbs.y }
|
|
1555
|
-
// [3] discarded
|
|
1556
1724
|
];
|
|
1557
1725
|
} else {
|
|
1558
|
-
const
|
|
1559
|
-
const midX = goingRight ? sAbs.x + sW + COL_GAP / 2 : sAbs.x - COL_GAP / 2;
|
|
1726
|
+
const midX = gapMidX(sAbs, sW, tAbs, tW);
|
|
1560
1727
|
routingPoints = [
|
|
1561
1728
|
{ x: sAbs.x + sW, y: sCY },
|
|
1562
|
-
// [0] discarded
|
|
1563
1729
|
{ x: midX, y: sCY },
|
|
1564
|
-
// [1] horizontal exit
|
|
1565
1730
|
{ x: midX, y: tCY },
|
|
1566
|
-
// [2] vertical to target row
|
|
1567
1731
|
{ x: tAbs.x, y: tCY }
|
|
1568
|
-
// [3] discarded
|
|
1569
1732
|
];
|
|
1570
1733
|
}
|
|
1571
1734
|
}
|
|
1572
1735
|
return { ...edge, data: { ...edge.data, routingPoints } };
|
|
1573
1736
|
});
|
|
1574
1737
|
}
|
|
1738
|
+
var ARTIFACT_ABOVE_GAP = 16;
|
|
1739
|
+
var ARTIFACT_H_SPACING = 12;
|
|
1740
|
+
function positionArtifacts(artifacts, resultNodes, edges) {
|
|
1741
|
+
if (artifacts.length === 0) return [];
|
|
1742
|
+
const byId = new Map(resultNodes.map((n) => [n.id, n]));
|
|
1743
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1744
|
+
const absPos = (id) => absolutePos(id, byId, cache);
|
|
1745
|
+
const artifactsByNode = /* @__PURE__ */ new Map();
|
|
1746
|
+
const ungrouped = [];
|
|
1747
|
+
for (const artifact of artifacts) {
|
|
1748
|
+
if (artifact.data.elementType === "Group") {
|
|
1749
|
+
ungrouped.push(artifact);
|
|
1750
|
+
continue;
|
|
1751
|
+
}
|
|
1752
|
+
const connEdge = edges.find((e) => {
|
|
1753
|
+
const t = e.data?.edgeType ?? e.type;
|
|
1754
|
+
return (t === "association" || t === "dataAssociation") && (e.source === artifact.id || e.target === artifact.id);
|
|
1755
|
+
});
|
|
1756
|
+
if (!connEdge) {
|
|
1757
|
+
ungrouped.push(artifact);
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
const connId = connEdge.source === artifact.id ? connEdge.target : connEdge.source;
|
|
1761
|
+
if (!byId.has(connId)) {
|
|
1762
|
+
ungrouped.push(artifact);
|
|
1763
|
+
continue;
|
|
1764
|
+
}
|
|
1765
|
+
if (!artifactsByNode.has(connId)) artifactsByNode.set(connId, []);
|
|
1766
|
+
artifactsByNode.get(connId).push(artifact);
|
|
1767
|
+
}
|
|
1768
|
+
const positioned = [...ungrouped];
|
|
1769
|
+
for (const [connId, arts] of artifactsByNode) {
|
|
1770
|
+
const connNode = byId.get(connId);
|
|
1771
|
+
const connAbsP = absPos(connId);
|
|
1772
|
+
const totalW = arts.reduce((s, a) => s + nW(a), 0) + (arts.length - 1) * ARTIFACT_H_SPACING;
|
|
1773
|
+
const desiredAbsY = connAbsP.y - ARTIFACT_ABOVE_GAP - Math.max(...arts.map(nH));
|
|
1774
|
+
let desiredAbsX = connAbsP.x + nW(connNode) / 2 - totalW / 2;
|
|
1775
|
+
for (const artifact of arts) {
|
|
1776
|
+
const parentAbsP = artifact.parentId ? absPos(artifact.parentId) : { x: 0, y: 0 };
|
|
1777
|
+
positioned.push({
|
|
1778
|
+
...artifact,
|
|
1779
|
+
position: {
|
|
1780
|
+
x: desiredAbsX - parentAbsP.x,
|
|
1781
|
+
y: desiredAbsY - parentAbsP.y
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
desiredAbsX += nW(artifact) + ARTIFACT_H_SPACING;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
return positioned;
|
|
1788
|
+
}
|
|
1575
1789
|
async function bpmnCustomLayout(nodes, edges) {
|
|
1576
|
-
const
|
|
1577
|
-
const
|
|
1578
|
-
const
|
|
1790
|
+
const artifacts = nodes.filter((n) => LAYOUT_ARTIFACT_TYPES.has(n.data.elementType));
|
|
1791
|
+
const mainNodes = nodes.filter((n) => !LAYOUT_ARTIFACT_TYPES.has(n.data.elementType));
|
|
1792
|
+
const pools = mainNodes.filter((n) => n.data.elementType === "Pool");
|
|
1793
|
+
const lanes = mainNodes.filter((n) => n.data.elementType === "Lane");
|
|
1794
|
+
const expandedSubProcesses = mainNodes.filter(
|
|
1795
|
+
(n) => COLLAPSED_SUBPROCESS_TYPES.has(n.data.elementType) && n.data.isExpanded
|
|
1796
|
+
);
|
|
1797
|
+
const subProcessLayouts = /* @__PURE__ */ new Map();
|
|
1798
|
+
const workingMainNodes = [...mainNodes];
|
|
1799
|
+
for (const sp of expandedSubProcesses) {
|
|
1800
|
+
const spChildren = workingMainNodes.filter((n) => n.parentId === sp.id);
|
|
1801
|
+
const result = layoutSubProcess(spChildren, edges);
|
|
1802
|
+
subProcessLayouts.set(sp.id, result);
|
|
1803
|
+
const spIdx = workingMainNodes.findIndex((n) => n.id === sp.id);
|
|
1804
|
+
if (spIdx >= 0) {
|
|
1805
|
+
workingMainNodes[spIdx] = {
|
|
1806
|
+
...workingMainNodes[spIdx],
|
|
1807
|
+
width: result.width,
|
|
1808
|
+
height: result.height,
|
|
1809
|
+
measured: { width: result.width, height: result.height }
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
const content = workingMainNodes.filter((n) => {
|
|
1814
|
+
if (!LAYOUT_CONTAINER_TYPES.has(n.data.elementType)) return true;
|
|
1815
|
+
if (COLLAPSED_SUBPROCESS_TYPES.has(n.data.elementType)) return true;
|
|
1816
|
+
return false;
|
|
1817
|
+
});
|
|
1579
1818
|
if (pools.length === 0) {
|
|
1580
1819
|
const { bpmnElkLayout: bpmnElkLayout2 } = await Promise.resolve().then(() => (init_elk(), elk_exports));
|
|
1581
|
-
|
|
1820
|
+
const elkResult = await bpmnElkLayout2(nodes.filter((n) => !LAYOUT_ARTIFACT_TYPES.has(n.data.elementType)), edges);
|
|
1821
|
+
const posArtifacts = positionArtifacts(artifacts, elkResult.nodes, edges);
|
|
1822
|
+
return { nodes: [...elkResult.nodes, ...posArtifacts], edges: elkResult.edges };
|
|
1582
1823
|
}
|
|
1583
1824
|
const poolIds = new Set(pools.map((p) => p.id));
|
|
1584
1825
|
const allLaneIds = new Set(lanes.map((l) => l.id));
|
|
@@ -1598,7 +1839,10 @@ async function bpmnCustomLayout(nodes, edges) {
|
|
|
1598
1839
|
const poolContent = content.filter(
|
|
1599
1840
|
(n) => n.parentId === pool.id || n.parentId != null && laneIds.has(n.parentId)
|
|
1600
1841
|
);
|
|
1601
|
-
const
|
|
1842
|
+
const poolBoundaries = workingMainNodes.filter(
|
|
1843
|
+
(n) => n.data.elementType === "BoundaryEvent" && (n.parentId === pool.id || n.parentId != null && laneIds.has(n.parentId))
|
|
1844
|
+
);
|
|
1845
|
+
const result = layoutPool(pool, poolLanes, [...poolContent, ...poolBoundaries], edges);
|
|
1602
1846
|
resultNodes.push({
|
|
1603
1847
|
...pool,
|
|
1604
1848
|
position: { x: 0, y: stackY },
|
|
@@ -1610,12 +1854,44 @@ async function bpmnCustomLayout(nodes, edges) {
|
|
|
1610
1854
|
}
|
|
1611
1855
|
stackY += result.height + POOL_V_GAP;
|
|
1612
1856
|
}
|
|
1857
|
+
for (const [, spLayout] of subProcessLayouts) {
|
|
1858
|
+
for (const child of spLayout.children) {
|
|
1859
|
+
resultNodes.push(child);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1613
1862
|
const layoutted = new Set(resultNodes.map((n) => n.id));
|
|
1614
|
-
|
|
1615
|
-
|
|
1863
|
+
const freeNodes = workingMainNodes.filter((n) => !layoutted.has(n.id));
|
|
1864
|
+
if (freeNodes.length > 0) {
|
|
1865
|
+
const freeEdges = edges.filter(
|
|
1866
|
+
(e) => freeNodes.some((n) => n.id === e.source || n.id === e.target)
|
|
1867
|
+
);
|
|
1868
|
+
try {
|
|
1869
|
+
const { bpmnElkLayout: bpmnElkLayout2 } = await Promise.resolve().then(() => (init_elk(), elk_exports));
|
|
1870
|
+
const elkFree = await bpmnElkLayout2(freeNodes, freeEdges);
|
|
1871
|
+
const offsetY = stackY;
|
|
1872
|
+
for (const node of elkFree.nodes) {
|
|
1873
|
+
resultNodes.push({
|
|
1874
|
+
...node,
|
|
1875
|
+
position: { x: node.position.x, y: node.position.y + offsetY }
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
const freeEdgeIds = new Set(freeEdges.map((e) => e.id));
|
|
1879
|
+
const elkEdgeMap = new Map(elkFree.edges.map((e) => [e.id, e]));
|
|
1880
|
+
for (let i = 0; i < edges.length; i++) {
|
|
1881
|
+
if (freeEdgeIds.has(edges[i].id) && elkEdgeMap.has(edges[i].id)) {
|
|
1882
|
+
edges[i] = elkEdgeMap.get(edges[i].id);
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
} catch {
|
|
1886
|
+
for (const node of freeNodes) resultNodes.push(node);
|
|
1887
|
+
}
|
|
1616
1888
|
}
|
|
1617
1889
|
const routedEdges = routeEdges(edges, resultNodes, allBackEdgeIds, allLaneIds, poolIds);
|
|
1618
|
-
|
|
1890
|
+
const positionedArtifacts = positionArtifacts(artifacts, resultNodes, edges);
|
|
1891
|
+
return {
|
|
1892
|
+
nodes: [...resultNodes, ...positionedArtifacts],
|
|
1893
|
+
edges: routedEdges
|
|
1894
|
+
};
|
|
1619
1895
|
}
|
|
1620
1896
|
|
|
1621
1897
|
// src/layout/index.ts
|