@metadev/daga 1.0.0 → 1.1.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/Changelog.md +5 -0
- package/fesm2022/metadev-daga.mjs +827 -709
- package/fesm2022/metadev-daga.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/lib/diagram-editor/diagram/diagram-canvas.d.ts +4 -0
- package/lib/diagram-editor/diagram/diagram-connection.d.ts +12 -3
- package/lib/diagram-editor/diagram/diagram-element.d.ts +74 -2
- package/lib/diagram-editor/diagram/diagram-field.d.ts +13 -3
- package/lib/diagram-editor/diagram/diagram-model.d.ts +10 -42
- package/lib/diagram-editor/diagram/diagram-node.d.ts +11 -2
- package/lib/diagram-editor/diagram/diagram-port.d.ts +12 -3
- package/lib/diagram-editor/diagram/diagram-section.d.ts +9 -1
- package/package.json +1 -1
|
@@ -223,8 +223,8 @@ class AdjacencyLayout {
|
|
|
223
223
|
arrangeNode(nodesToBeArranged[0], nodeArrangement, [0, 0], nodesToBeArranged);
|
|
224
224
|
}
|
|
225
225
|
// place nodes according to arrangement
|
|
226
|
-
const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
|
|
227
|
-
const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
|
|
226
|
+
const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
|
|
227
|
+
const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
|
|
228
228
|
const gapSize = (model.canvas?.gridSize || 0) * 2;
|
|
229
229
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
230
230
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
@@ -294,8 +294,8 @@ class BreadthAdjacencyLayout {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
// place nodes according to arrangement
|
|
297
|
-
const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
|
|
298
|
-
const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
|
|
297
|
+
const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
|
|
298
|
+
const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
|
|
299
299
|
const gapSize = (model.canvas?.gridSize || 0) * 2;
|
|
300
300
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
301
301
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
@@ -634,7 +634,7 @@ class HorizontalLayout {
|
|
|
634
634
|
return model;
|
|
635
635
|
}
|
|
636
636
|
const gapSize = (model.canvas?.gridSize || 0) * 2;
|
|
637
|
-
const nodesToBeArranged = model.nodes;
|
|
637
|
+
const nodesToBeArranged = model.nodes.all();
|
|
638
638
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
639
639
|
let widthAccumulator = 0;
|
|
640
640
|
for (const node of nodesToBeArranged) {
|
|
@@ -654,8 +654,8 @@ class PriorityLayout {
|
|
|
654
654
|
// nothing to arrange...
|
|
655
655
|
return model;
|
|
656
656
|
}
|
|
657
|
-
const maximumPriority = Math.max(...model.
|
|
658
|
-
const minimumPriority = Math.min(...model.
|
|
657
|
+
const maximumPriority = Math.max(...model.nodes.types.all().map((n) => n.priority));
|
|
658
|
+
const minimumPriority = Math.min(...model.nodes.types.all().map((n) => n.priority));
|
|
659
659
|
if (maximumPriority === minimumPriority) {
|
|
660
660
|
// if there's no disparity in priorities, just use breadth layout
|
|
661
661
|
new BreadthLayout().apply(model);
|
|
@@ -664,7 +664,7 @@ class PriorityLayout {
|
|
|
664
664
|
const gapSize = (model.canvas?.gridSize || 0) * 2;
|
|
665
665
|
const nodesToBeArranged = [...model.nodes];
|
|
666
666
|
const nodeArrangement = [];
|
|
667
|
-
const nodesWithMaximumPriorityToBeArranged = model.
|
|
667
|
+
const nodesWithMaximumPriorityToBeArranged = model.nodes.filter(undefined, maximumPriority);
|
|
668
668
|
const nodesWithMaximumPriority = [];
|
|
669
669
|
if (nodesWithMaximumPriorityToBeArranged.length > 1) {
|
|
670
670
|
// use bfs to sort nodes by distance to the first node
|
|
@@ -762,7 +762,7 @@ class VerticalLayout {
|
|
|
762
762
|
return model;
|
|
763
763
|
}
|
|
764
764
|
const gapSize = (model.canvas?.gridSize || 0) * 2;
|
|
765
|
-
const nodesToBeArranged = model.nodes;
|
|
765
|
+
const nodesToBeArranged = model.nodes.all();
|
|
766
766
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
767
767
|
let heightAccumulator = 0;
|
|
768
768
|
for (const node of nodesToBeArranged) {
|
|
@@ -1336,14 +1336,11 @@ class AddNodeAction {
|
|
|
1336
1336
|
}
|
|
1337
1337
|
undo() {
|
|
1338
1338
|
if (this.id) {
|
|
1339
|
-
|
|
1340
|
-
if (node) {
|
|
1341
|
-
this.canvas.model.deleteNode(node);
|
|
1342
|
-
}
|
|
1339
|
+
this.canvas.model.nodes.remove(this.id);
|
|
1343
1340
|
}
|
|
1344
1341
|
}
|
|
1345
1342
|
redo() {
|
|
1346
|
-
const node = this.canvas.model.
|
|
1343
|
+
const node = this.canvas.model.nodes.new(this.type, this.coords, this.id, this.sectionIds, this.sectionPortIds, this.sectionPortLabelIds, this.portIds, this.portLabelIds, this.labelId);
|
|
1347
1344
|
if (this.values !== undefined) {
|
|
1348
1345
|
node.valueSet.setValues(structuredClone({
|
|
1349
1346
|
...node.valueSet.getValues(),
|
|
@@ -1372,16 +1369,10 @@ class MoveNodeAction {
|
|
|
1372
1369
|
this.to = to;
|
|
1373
1370
|
}
|
|
1374
1371
|
undo() {
|
|
1375
|
-
|
|
1376
|
-
if (node) {
|
|
1377
|
-
node.move(this.from);
|
|
1378
|
-
}
|
|
1372
|
+
this.canvas.model.nodes.get(this.nodeId)?.move(this.from);
|
|
1379
1373
|
}
|
|
1380
1374
|
redo() {
|
|
1381
|
-
|
|
1382
|
-
if (node) {
|
|
1383
|
-
node.move(this.to);
|
|
1384
|
-
}
|
|
1375
|
+
this.canvas.model.nodes.get(this.nodeId)?.move(this.to);
|
|
1385
1376
|
}
|
|
1386
1377
|
}
|
|
1387
1378
|
class StretchNodeAction {
|
|
@@ -1393,16 +1384,14 @@ class StretchNodeAction {
|
|
|
1393
1384
|
this.to = to;
|
|
1394
1385
|
}
|
|
1395
1386
|
undo() {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
}
|
|
1387
|
+
this.canvas.model.nodes
|
|
1388
|
+
.get(this.nodeId)
|
|
1389
|
+
?.stretch(this.direction, this.from - this.to);
|
|
1400
1390
|
}
|
|
1401
1391
|
redo() {
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1392
|
+
this.canvas.model.nodes
|
|
1393
|
+
.get(this.nodeId)
|
|
1394
|
+
?.stretch(this.direction, this.to - this.from);
|
|
1406
1395
|
}
|
|
1407
1396
|
}
|
|
1408
1397
|
class StretchSectionAction {
|
|
@@ -1414,14 +1403,14 @@ class StretchSectionAction {
|
|
|
1414
1403
|
this.to = to;
|
|
1415
1404
|
}
|
|
1416
1405
|
undo() {
|
|
1417
|
-
const section = this.canvas.model.
|
|
1406
|
+
const section = this.canvas.model.sections.get(this.sectionId);
|
|
1418
1407
|
const node = section?.node;
|
|
1419
1408
|
if (node) {
|
|
1420
1409
|
node.stretchSections(this.direction, this.from - this.to, section.coords);
|
|
1421
1410
|
}
|
|
1422
1411
|
}
|
|
1423
1412
|
redo() {
|
|
1424
|
-
const section = this.canvas.model.
|
|
1413
|
+
const section = this.canvas.model.sections.get(this.sectionId);
|
|
1425
1414
|
const node = section?.node;
|
|
1426
1415
|
if (node) {
|
|
1427
1416
|
node.stretchSections(this.direction, this.to - this.from, section.coords);
|
|
@@ -1438,17 +1427,14 @@ class AddConnectionAction {
|
|
|
1438
1427
|
}
|
|
1439
1428
|
undo() {
|
|
1440
1429
|
if (this.id) {
|
|
1441
|
-
|
|
1442
|
-
if (connection) {
|
|
1443
|
-
this.canvas.model.deleteConnection(connection);
|
|
1444
|
-
}
|
|
1430
|
+
this.canvas.model.connections.remove(this.id);
|
|
1445
1431
|
}
|
|
1446
1432
|
}
|
|
1447
1433
|
redo() {
|
|
1448
|
-
const start = this.canvas.model.
|
|
1449
|
-
const end = this.canvas.model.
|
|
1434
|
+
const start = this.canvas.model.ports.get(this.startId);
|
|
1435
|
+
const end = this.canvas.model.ports.get(this.endId);
|
|
1450
1436
|
if (start && end) {
|
|
1451
|
-
const connection = this.canvas.model.
|
|
1437
|
+
const connection = this.canvas.model.connections.new(this.type, start, end, this.id);
|
|
1452
1438
|
// reset our id in case it was automatically generated
|
|
1453
1439
|
this.id = connection.id;
|
|
1454
1440
|
}
|
|
@@ -1462,14 +1448,14 @@ class EditFieldAction {
|
|
|
1462
1448
|
this.to = to;
|
|
1463
1449
|
}
|
|
1464
1450
|
undo() {
|
|
1465
|
-
const field = this.canvas.model.
|
|
1451
|
+
const field = this.canvas.model.fields.get(this.fieldId);
|
|
1466
1452
|
if (field) {
|
|
1467
1453
|
field.text = this.from;
|
|
1468
1454
|
this.canvas.updateFieldsInView(this.fieldId);
|
|
1469
1455
|
}
|
|
1470
1456
|
}
|
|
1471
1457
|
redo() {
|
|
1472
|
-
const field = this.canvas.model.
|
|
1458
|
+
const field = this.canvas.model.fields.get(this.fieldId);
|
|
1473
1459
|
if (field) {
|
|
1474
1460
|
field.text = this.to;
|
|
1475
1461
|
this.canvas.updateFieldsInView(this.fieldId);
|
|
@@ -1488,7 +1474,7 @@ class UpdateValuesAction {
|
|
|
1488
1474
|
return this.model.valueSet;
|
|
1489
1475
|
}
|
|
1490
1476
|
else {
|
|
1491
|
-
return this.model.
|
|
1477
|
+
return (this.model.nodes.get(this.id) || this.model.connections.get(this.id))?.valueSet;
|
|
1492
1478
|
}
|
|
1493
1479
|
}
|
|
1494
1480
|
undo() {
|
|
@@ -1557,30 +1543,30 @@ class RemoveAction {
|
|
|
1557
1543
|
}
|
|
1558
1544
|
undo() {
|
|
1559
1545
|
for (const node of this.nodes) {
|
|
1560
|
-
this.model.nodes.
|
|
1546
|
+
this.model.nodes.add(node);
|
|
1561
1547
|
}
|
|
1562
1548
|
for (const section of this.sections) {
|
|
1563
|
-
this.model.sections.
|
|
1549
|
+
this.model.sections.add(section);
|
|
1564
1550
|
}
|
|
1565
1551
|
for (const port of this.ports) {
|
|
1566
|
-
this.model.ports.
|
|
1552
|
+
this.model.ports.add(port);
|
|
1567
1553
|
}
|
|
1568
1554
|
for (const connection of this.connections) {
|
|
1569
|
-
this.model.connections.
|
|
1555
|
+
this.model.connections.add(connection);
|
|
1570
1556
|
}
|
|
1571
1557
|
for (const field of this.fields) {
|
|
1572
|
-
this.model.fields.
|
|
1558
|
+
this.model.fields.add(field);
|
|
1573
1559
|
}
|
|
1574
1560
|
for (const node of this.nodes) {
|
|
1575
1561
|
if (node.label) {
|
|
1576
|
-
const label = this.model.
|
|
1562
|
+
const label = this.model.fields.get(node.label._id);
|
|
1577
1563
|
if (label) {
|
|
1578
1564
|
node.label = label;
|
|
1579
1565
|
}
|
|
1580
1566
|
}
|
|
1581
1567
|
const ports = [];
|
|
1582
1568
|
for (const nodePort of node.ports) {
|
|
1583
|
-
const port = this.model.
|
|
1569
|
+
const port = this.model.ports.get(nodePort._id);
|
|
1584
1570
|
if (port) {
|
|
1585
1571
|
ports.push(port);
|
|
1586
1572
|
}
|
|
@@ -1588,7 +1574,7 @@ class RemoveAction {
|
|
|
1588
1574
|
node.ports = ports;
|
|
1589
1575
|
const sections = [];
|
|
1590
1576
|
for (const nodeSection of node.sections) {
|
|
1591
|
-
const section = this.model.
|
|
1577
|
+
const section = this.model.sections.get(nodeSection._id);
|
|
1592
1578
|
if (section) {
|
|
1593
1579
|
sections.push(section);
|
|
1594
1580
|
}
|
|
@@ -1597,20 +1583,20 @@ class RemoveAction {
|
|
|
1597
1583
|
}
|
|
1598
1584
|
for (const section of this.sections) {
|
|
1599
1585
|
if (section.node) {
|
|
1600
|
-
const node = this.model.
|
|
1586
|
+
const node = this.model.nodes.get(section.node._id);
|
|
1601
1587
|
if (node) {
|
|
1602
1588
|
section.node = node;
|
|
1603
1589
|
}
|
|
1604
1590
|
}
|
|
1605
1591
|
if (section.label) {
|
|
1606
|
-
const label = this.model.
|
|
1592
|
+
const label = this.model.fields.get(section.label._id);
|
|
1607
1593
|
if (label) {
|
|
1608
1594
|
section.label = label;
|
|
1609
1595
|
}
|
|
1610
1596
|
}
|
|
1611
1597
|
const ports = [];
|
|
1612
1598
|
for (const sectionPort of section.ports) {
|
|
1613
|
-
const port = this.model.
|
|
1599
|
+
const port = this.model.ports.get(sectionPort._id);
|
|
1614
1600
|
if (port) {
|
|
1615
1601
|
ports.push(port);
|
|
1616
1602
|
}
|
|
@@ -1619,20 +1605,21 @@ class RemoveAction {
|
|
|
1619
1605
|
}
|
|
1620
1606
|
for (const port of this.ports) {
|
|
1621
1607
|
if (port.rootElement) {
|
|
1622
|
-
const rootElement = this.model.
|
|
1608
|
+
const rootElement = this.model.nodes.get(port.rootElement._id) ||
|
|
1609
|
+
this.model.sections.get(port.rootElement._id);
|
|
1623
1610
|
if (rootElement) {
|
|
1624
1611
|
port.rootElement = rootElement;
|
|
1625
1612
|
}
|
|
1626
1613
|
}
|
|
1627
1614
|
if (port.label) {
|
|
1628
|
-
const label = this.model.
|
|
1615
|
+
const label = this.model.fields.get(port.label._id);
|
|
1629
1616
|
if (label) {
|
|
1630
1617
|
port.label = label;
|
|
1631
1618
|
}
|
|
1632
1619
|
}
|
|
1633
1620
|
const outgoingConnections = [];
|
|
1634
1621
|
for (const portOutgoingConnection of port.outgoingConnections) {
|
|
1635
|
-
const connection = this.model.
|
|
1622
|
+
const connection = this.model.connections.get(portOutgoingConnection._id);
|
|
1636
1623
|
if (connection) {
|
|
1637
1624
|
outgoingConnections.push(connection);
|
|
1638
1625
|
}
|
|
@@ -1640,7 +1627,7 @@ class RemoveAction {
|
|
|
1640
1627
|
port.outgoingConnections = outgoingConnections;
|
|
1641
1628
|
const incomingConnections = [];
|
|
1642
1629
|
for (const portIncomingConnection of port.incomingConnections) {
|
|
1643
|
-
const connection = this.model.
|
|
1630
|
+
const connection = this.model.connections.get(portIncomingConnection._id);
|
|
1644
1631
|
if (connection) {
|
|
1645
1632
|
incomingConnections.push(connection);
|
|
1646
1633
|
}
|
|
@@ -1649,13 +1636,13 @@ class RemoveAction {
|
|
|
1649
1636
|
}
|
|
1650
1637
|
for (const connection of this.connections) {
|
|
1651
1638
|
if (connection.start) {
|
|
1652
|
-
const start = this.model.
|
|
1639
|
+
const start = this.model.ports.get(connection.start._id);
|
|
1653
1640
|
if (start) {
|
|
1654
1641
|
connection.setStart(start);
|
|
1655
1642
|
}
|
|
1656
1643
|
}
|
|
1657
1644
|
if (connection.end) {
|
|
1658
|
-
const end = this.model.
|
|
1645
|
+
const end = this.model.ports.get(connection.end._id);
|
|
1659
1646
|
if (end) {
|
|
1660
1647
|
connection.setEnd(end);
|
|
1661
1648
|
}
|
|
@@ -1663,7 +1650,9 @@ class RemoveAction {
|
|
|
1663
1650
|
}
|
|
1664
1651
|
for (const field of this.fields) {
|
|
1665
1652
|
if (field.rootElement) {
|
|
1666
|
-
const rootElement = this.model.
|
|
1653
|
+
const rootElement = this.model.nodes.get(field.rootElement._id) ||
|
|
1654
|
+
this.model.sections.get(field.rootElement._id) ||
|
|
1655
|
+
this.model.ports.get(field.rootElement._id);
|
|
1667
1656
|
if (rootElement) {
|
|
1668
1657
|
field.rootElement = rootElement;
|
|
1669
1658
|
}
|
|
@@ -1680,7 +1669,7 @@ class RemoveAction {
|
|
|
1680
1669
|
this.fields = [];
|
|
1681
1670
|
// make shallow copies of the elements with their relationships
|
|
1682
1671
|
for (const nodeId of this.nodeIds) {
|
|
1683
|
-
const node = this.model.
|
|
1672
|
+
const node = this.model.nodes.get(nodeId);
|
|
1684
1673
|
if (node) {
|
|
1685
1674
|
const nodeCopy = clone(node);
|
|
1686
1675
|
if (nodeCopy.label) {
|
|
@@ -1692,7 +1681,7 @@ class RemoveAction {
|
|
|
1692
1681
|
}
|
|
1693
1682
|
}
|
|
1694
1683
|
for (const sectionId of this.sectionIds) {
|
|
1695
|
-
const section = this.model.
|
|
1684
|
+
const section = this.model.sections.get(sectionId);
|
|
1696
1685
|
if (section) {
|
|
1697
1686
|
const sectionCopy = clone(section);
|
|
1698
1687
|
if (sectionCopy.label) {
|
|
@@ -1703,7 +1692,7 @@ class RemoveAction {
|
|
|
1703
1692
|
}
|
|
1704
1693
|
}
|
|
1705
1694
|
for (const portId of this.portIds) {
|
|
1706
|
-
const port = this.model.
|
|
1695
|
+
const port = this.model.ports.get(portId);
|
|
1707
1696
|
if (port) {
|
|
1708
1697
|
const portCopy = clone(port);
|
|
1709
1698
|
if (portCopy.rootElement) {
|
|
@@ -1718,7 +1707,7 @@ class RemoveAction {
|
|
|
1718
1707
|
}
|
|
1719
1708
|
}
|
|
1720
1709
|
for (const connectionId of this.connectionIds) {
|
|
1721
|
-
const connection = this.model.
|
|
1710
|
+
const connection = this.model.connections.get(connectionId);
|
|
1722
1711
|
if (connection) {
|
|
1723
1712
|
const connectionCopy = clone(connection);
|
|
1724
1713
|
if (connectionCopy.start) {
|
|
@@ -1731,7 +1720,7 @@ class RemoveAction {
|
|
|
1731
1720
|
}
|
|
1732
1721
|
}
|
|
1733
1722
|
for (const fieldId of this.fieldIds) {
|
|
1734
|
-
const field = this.model.
|
|
1723
|
+
const field = this.model.fields.get(fieldId);
|
|
1735
1724
|
if (field) {
|
|
1736
1725
|
const fieldCopy = clone(field);
|
|
1737
1726
|
if (fieldCopy.rootElement) {
|
|
@@ -1742,34 +1731,19 @@ class RemoveAction {
|
|
|
1742
1731
|
}
|
|
1743
1732
|
// delete the elements
|
|
1744
1733
|
for (const nodeId of this.nodeIds) {
|
|
1745
|
-
|
|
1746
|
-
if (node) {
|
|
1747
|
-
this.model.deleteNode(node);
|
|
1748
|
-
}
|
|
1734
|
+
this.model.nodes.remove(nodeId);
|
|
1749
1735
|
}
|
|
1750
1736
|
for (const sectionId of this.sectionIds) {
|
|
1751
|
-
|
|
1752
|
-
if (section) {
|
|
1753
|
-
this.model.deleteSection(section);
|
|
1754
|
-
}
|
|
1737
|
+
this.model.sections.remove(sectionId);
|
|
1755
1738
|
}
|
|
1756
1739
|
for (const portId of this.portIds) {
|
|
1757
|
-
|
|
1758
|
-
if (port) {
|
|
1759
|
-
this.model.deletePort(port);
|
|
1760
|
-
}
|
|
1740
|
+
this.model.ports.remove(portId);
|
|
1761
1741
|
}
|
|
1762
1742
|
for (const connectionId of this.connectionIds) {
|
|
1763
|
-
|
|
1764
|
-
if (connection) {
|
|
1765
|
-
this.model.deleteConnection(connection);
|
|
1766
|
-
}
|
|
1743
|
+
this.model.connections.remove(connectionId);
|
|
1767
1744
|
}
|
|
1768
1745
|
for (const fieldId of this.fieldIds) {
|
|
1769
|
-
|
|
1770
|
-
if (field) {
|
|
1771
|
-
this.model.deleteField(field);
|
|
1772
|
-
}
|
|
1746
|
+
this.model.fields.remove(fieldId);
|
|
1773
1747
|
}
|
|
1774
1748
|
}
|
|
1775
1749
|
}
|
|
@@ -1781,7 +1755,7 @@ const clone = (obj) => {
|
|
|
1781
1755
|
};
|
|
1782
1756
|
|
|
1783
1757
|
/**
|
|
1784
|
-
* Represents an object which exists as part of a
|
|
1758
|
+
* Represents an object which exists as part of a specific diagram model and has a visual representation in a diagram canvas.
|
|
1785
1759
|
* @see DiagramModel
|
|
1786
1760
|
* @see DiagramCanvas
|
|
1787
1761
|
*/
|
|
@@ -1806,6 +1780,104 @@ class DiagramElement {
|
|
|
1806
1780
|
return this.model.canvas?.selectCanvasView()?.select(`g#${this.id}`);
|
|
1807
1781
|
}
|
|
1808
1782
|
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Represents a collection of diagram entities of a type that exists as part of a diagram model.
|
|
1785
|
+
* @see DiagramEntity
|
|
1786
|
+
* @see DiagramModel
|
|
1787
|
+
*/
|
|
1788
|
+
class DiagramEntitySet {
|
|
1789
|
+
constructor() {
|
|
1790
|
+
/**
|
|
1791
|
+
* The list of entities contained in this set.
|
|
1792
|
+
*/
|
|
1793
|
+
this.entities = [];
|
|
1794
|
+
/**
|
|
1795
|
+
* A mapping of entity ids to their corresponding entity in this set for quickly fetching entities based on their id.
|
|
1796
|
+
*/
|
|
1797
|
+
this.entityMap = {};
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* The number of entities of this set.
|
|
1801
|
+
*/
|
|
1802
|
+
get length() {
|
|
1803
|
+
return this.entities.length;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Gets all of the entities of this set.
|
|
1807
|
+
* @returns An array containing all of the entities of this set.
|
|
1808
|
+
*/
|
|
1809
|
+
all() {
|
|
1810
|
+
return [...this.entities];
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Adds an entity to this set if there are no entities with the same id. Has no effect if there already exists an entity with the same id as the given entity.
|
|
1814
|
+
* For creating entities with relationships with other entities, the new() method should be used instead. The add() method adds an entity but doesn't take care of setting that entity's relationships with other entities.
|
|
1815
|
+
* @param entity An entity to be added to this set.
|
|
1816
|
+
*/
|
|
1817
|
+
add(entity) {
|
|
1818
|
+
if (this.entityMap[entity.id] === undefined) {
|
|
1819
|
+
this.entityMap[entity.id] = entity;
|
|
1820
|
+
this.entities.push(entity);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Removes all the entities in this set.
|
|
1825
|
+
*/
|
|
1826
|
+
clear() {
|
|
1827
|
+
// remove each entity individually in case classes that extend this implement their own specific cleanup
|
|
1828
|
+
while (this.entities.length > 0) {
|
|
1829
|
+
this.remove(this.entities[0].id);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Checks if this set contains an entity with the given id.
|
|
1834
|
+
* @param id An id.
|
|
1835
|
+
* @returns `true` if this set contains an entity with the given id, `false` otherwise.
|
|
1836
|
+
*/
|
|
1837
|
+
contains(id) {
|
|
1838
|
+
return this.entityMap[id] !== undefined;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Gets all of the entities of this set filtered following given criteria.
|
|
1842
|
+
* @returns An array containing the entities of this set that meet the given criteria.
|
|
1843
|
+
*/
|
|
1844
|
+
filter() {
|
|
1845
|
+
return this.all();
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Gets an entity of this set matching specific criteria.
|
|
1849
|
+
* @returns An entity of this set.
|
|
1850
|
+
*/
|
|
1851
|
+
find() {
|
|
1852
|
+
return this.entities.length > 0 ? this.entities[0] : undefined;
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Gets an entity from this set.
|
|
1856
|
+
* @param id An id.
|
|
1857
|
+
* @returns An entity with the given id, or `undefined` if there are no entities with the given id.
|
|
1858
|
+
*/
|
|
1859
|
+
get(id) {
|
|
1860
|
+
return this.entityMap[id];
|
|
1861
|
+
}
|
|
1862
|
+
/**
|
|
1863
|
+
* Attempts to find and remove an entity with the given id. Has no effect if there are no entities with the given id.
|
|
1864
|
+
* @param id An id.
|
|
1865
|
+
*/
|
|
1866
|
+
remove(id) {
|
|
1867
|
+
const entity = this.get(id);
|
|
1868
|
+
if (entity !== undefined) {
|
|
1869
|
+
delete this.entityMap[id];
|
|
1870
|
+
removeIfExists(this.entities, entity);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
*[Symbol.iterator]() {
|
|
1874
|
+
let counter = 0;
|
|
1875
|
+
while (counter < this.entities.length) {
|
|
1876
|
+
yield this.entities[counter];
|
|
1877
|
+
++counter;
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1809
1881
|
|
|
1810
1882
|
class Property {
|
|
1811
1883
|
constructor(name, type, defaultValue, basic, editable, rootAttribute) {
|
|
@@ -2130,13 +2202,13 @@ class DiagramConnection extends DiagramElement {
|
|
|
2130
2202
|
}
|
|
2131
2203
|
constructor(model, type, start, end, id) {
|
|
2132
2204
|
let uniqueId;
|
|
2133
|
-
if (id !== undefined && model.
|
|
2205
|
+
if (id !== undefined && model.connections.get(id) === undefined) {
|
|
2134
2206
|
uniqueId = id;
|
|
2135
2207
|
}
|
|
2136
2208
|
else {
|
|
2137
2209
|
do {
|
|
2138
2210
|
uniqueId = `diagram-connection-${++idTicker$4}`;
|
|
2139
|
-
} while (model.
|
|
2211
|
+
} while (model.connections.get(uniqueId) !== undefined);
|
|
2140
2212
|
}
|
|
2141
2213
|
super(model, uniqueId);
|
|
2142
2214
|
this.startCoords = [0, 0];
|
|
@@ -2200,56 +2272,62 @@ class DiagramConnection extends DiagramElement {
|
|
|
2200
2272
|
}
|
|
2201
2273
|
}
|
|
2202
2274
|
}
|
|
2275
|
+
class DiagramConnectionSet extends DiagramEntitySet {
|
|
2276
|
+
constructor(model) {
|
|
2277
|
+
super();
|
|
2278
|
+
this.types = new DiagramEntitySet();
|
|
2279
|
+
this.model = model;
|
|
2280
|
+
}
|
|
2281
|
+
new(type, start, end, id) {
|
|
2282
|
+
const connection = new DiagramConnection(this.model, type, start, end, id);
|
|
2283
|
+
super.add(connection);
|
|
2284
|
+
connection.updateInView();
|
|
2285
|
+
return connection;
|
|
2286
|
+
}
|
|
2287
|
+
remove(id) {
|
|
2288
|
+
const connection = this.get(id);
|
|
2289
|
+
if (connection) {
|
|
2290
|
+
// remove from ports
|
|
2291
|
+
removeIfExists(connection.start?.outgoingConnections || [], connection);
|
|
2292
|
+
removeIfExists(connection.end?.incomingConnections || [], connection);
|
|
2293
|
+
// remove from set of connections
|
|
2294
|
+
super.remove(id);
|
|
2295
|
+
// remove from canvas
|
|
2296
|
+
connection.updateInView();
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
filter(type, threshold) {
|
|
2300
|
+
return this.entities.filter((e) => (type ? e.type.id === type : true) &&
|
|
2301
|
+
(threshold
|
|
2302
|
+
? (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
2303
|
+
threshold &&
|
|
2304
|
+
(e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
2305
|
+
threshold
|
|
2306
|
+
: true));
|
|
2307
|
+
}
|
|
2308
|
+
find(type, threshold) {
|
|
2309
|
+
return this.entities.find((e) => (type ? e.type.id === type : true) &&
|
|
2310
|
+
(threshold
|
|
2311
|
+
? (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
2312
|
+
threshold &&
|
|
2313
|
+
(e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
2314
|
+
threshold
|
|
2315
|
+
: true));
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2203
2318
|
|
|
2204
2319
|
let idTicker$3 = 0;
|
|
2205
|
-
const
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
color: '#FFFFFF',
|
|
2209
|
-
borderColor: '#000000',
|
|
2210
|
-
selectedColor: '#FFFFFF',
|
|
2211
|
-
selectedBorderColor: '#000000'
|
|
2212
|
-
};
|
|
2213
|
-
const DIAGRAM_NODE_TYPE_DEFAULTS = {
|
|
2214
|
-
name: '',
|
|
2215
|
-
defaultWidth: 0,
|
|
2216
|
-
defaultHeight: 0,
|
|
2320
|
+
const DIAGRAM_SECTION_DEFAULTS = {
|
|
2321
|
+
sectionsX: 1,
|
|
2322
|
+
sectionsY: 1,
|
|
2217
2323
|
minWidth: 0,
|
|
2218
2324
|
minHeight: 0,
|
|
2219
|
-
|
|
2220
|
-
resizableY: false,
|
|
2325
|
+
margin: 0,
|
|
2221
2326
|
label: null,
|
|
2222
2327
|
ports: [],
|
|
2223
|
-
|
|
2224
|
-
look: DIAGRAM_LOOK_DEFAULTS,
|
|
2225
|
-
isUnique: false,
|
|
2226
|
-
priority: 0,
|
|
2227
|
-
properties: []
|
|
2328
|
+
look: DIAGRAM_LOOK_DEFAULTS
|
|
2228
2329
|
};
|
|
2229
|
-
class
|
|
2230
|
-
constructor(options) {
|
|
2231
|
-
const values = {
|
|
2232
|
-
...DIAGRAM_NODE_TYPE_DEFAULTS,
|
|
2233
|
-
...options
|
|
2234
|
-
};
|
|
2235
|
-
this.id = values.id;
|
|
2236
|
-
this.name = values.name;
|
|
2237
|
-
this.defaultWidth = values.defaultWidth;
|
|
2238
|
-
this.defaultHeight = values.defaultHeight;
|
|
2239
|
-
this.minWidth = values.minWidth;
|
|
2240
|
-
this.minHeight = values.minHeight;
|
|
2241
|
-
this.resizableX = values.resizableX;
|
|
2242
|
-
this.resizableY = values.resizableY;
|
|
2243
|
-
this.label = values.label;
|
|
2244
|
-
this.ports = values.ports;
|
|
2245
|
-
this.sections = values.sections;
|
|
2246
|
-
this.look = values.look;
|
|
2247
|
-
this.isUnique = values.isUnique;
|
|
2248
|
-
this.priority = values.priority;
|
|
2249
|
-
this.propertySet = new PropertySet(options?.properties || []);
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
class DiagramNode extends DiagramElement {
|
|
2330
|
+
class DiagramSection extends DiagramElement {
|
|
2253
2331
|
get name() {
|
|
2254
2332
|
return this.label?.text || '';
|
|
2255
2333
|
}
|
|
@@ -2259,29 +2337,26 @@ class DiagramNode extends DiagramElement {
|
|
|
2259
2337
|
this.label.updateInView();
|
|
2260
2338
|
}
|
|
2261
2339
|
}
|
|
2262
|
-
constructor(model,
|
|
2340
|
+
constructor(model, node, coords, width, height, id) {
|
|
2263
2341
|
let uniqueId;
|
|
2264
|
-
if (id !== undefined && model.
|
|
2342
|
+
if (id !== undefined && model.sections.get(id) === undefined) {
|
|
2265
2343
|
uniqueId = id;
|
|
2266
2344
|
}
|
|
2267
2345
|
else {
|
|
2268
2346
|
do {
|
|
2269
|
-
uniqueId = `diagram-
|
|
2270
|
-
} while (model.
|
|
2347
|
+
uniqueId = `diagram-section-${++idTicker$3}`;
|
|
2348
|
+
} while (model.sections.get(uniqueId) !== undefined);
|
|
2271
2349
|
}
|
|
2272
2350
|
super(model, uniqueId);
|
|
2273
|
-
this.sections = [];
|
|
2274
2351
|
this.ports = [];
|
|
2275
|
-
this.
|
|
2276
|
-
this.valueSet = new ValueSet(type.propertySet, this);
|
|
2277
|
-
this.originalData = {};
|
|
2352
|
+
this.node = node;
|
|
2278
2353
|
this.coords = coords;
|
|
2279
|
-
this.width =
|
|
2280
|
-
this.height =
|
|
2354
|
+
this.width = width;
|
|
2355
|
+
this.height = height;
|
|
2281
2356
|
}
|
|
2282
2357
|
updateInView() {
|
|
2283
2358
|
if (this.model.canvas && this.model.renderToCanvas) {
|
|
2284
|
-
this.model.canvas.
|
|
2359
|
+
this.model.canvas.updateSectionsInView(this.id);
|
|
2285
2360
|
}
|
|
2286
2361
|
}
|
|
2287
2362
|
getClosestPortToPoint(coords) {
|
|
@@ -2328,36 +2403,12 @@ class DiagramNode extends DiagramElement {
|
|
|
2328
2403
|
}
|
|
2329
2404
|
return result;
|
|
2330
2405
|
}
|
|
2331
|
-
getAdjacentNodes() {
|
|
2332
|
-
const result = [];
|
|
2333
|
-
for (const port of this.ports) {
|
|
2334
|
-
for (const incomingConnection of port.incomingConnections) {
|
|
2335
|
-
const otherNode = incomingConnection.start?.getNode();
|
|
2336
|
-
if (otherNode) {
|
|
2337
|
-
result.push(otherNode);
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
for (const outgoingConnection of port.outgoingConnections) {
|
|
2341
|
-
const otherNode = outgoingConnection.end?.getNode();
|
|
2342
|
-
if (otherNode) {
|
|
2343
|
-
result.push(otherNode);
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
return result;
|
|
2348
|
-
}
|
|
2349
2406
|
move(coords) {
|
|
2350
2407
|
const coordDifferences = [
|
|
2351
2408
|
coords[0] - this.coords[0],
|
|
2352
2409
|
coords[1] - this.coords[1]
|
|
2353
2410
|
];
|
|
2354
2411
|
this.coords = coords;
|
|
2355
|
-
for (const section of this.sections) {
|
|
2356
|
-
section.move([
|
|
2357
|
-
section.coords[0] + coordDifferences[0],
|
|
2358
|
-
section.coords[1] + coordDifferences[1]
|
|
2359
|
-
]);
|
|
2360
|
-
}
|
|
2361
2412
|
for (const port of this.ports) {
|
|
2362
2413
|
port.move([
|
|
2363
2414
|
port.coords[0] + coordDifferences[0],
|
|
@@ -2382,29 +2433,49 @@ class DiagramNode extends DiagramElement {
|
|
|
2382
2433
|
case Side.Left:
|
|
2383
2434
|
newCoordsX = [oldCoordsX[0] - distance, oldCoordsX[1]];
|
|
2384
2435
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
|
|
2385
|
-
if (newCoordsX[1] - newCoordsX[0] <
|
|
2386
|
-
|
|
2436
|
+
if (newCoordsX[1] - newCoordsX[0] <
|
|
2437
|
+
(this.node?.type?.sections?.minWidth ||
|
|
2438
|
+
DIAGRAM_SECTION_DEFAULTS.minWidth)) {
|
|
2439
|
+
newCoordsX[0] =
|
|
2440
|
+
newCoordsX[1] -
|
|
2441
|
+
(this.node?.type?.sections?.minWidth ||
|
|
2442
|
+
DIAGRAM_SECTION_DEFAULTS.minWidth);
|
|
2387
2443
|
}
|
|
2388
2444
|
break;
|
|
2389
2445
|
case Side.Top:
|
|
2390
2446
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
|
|
2391
2447
|
newCoordsY = [oldCoordsY[0] - distance, oldCoordsY[1]];
|
|
2392
|
-
if (newCoordsY[1] - newCoordsY[0] <
|
|
2393
|
-
|
|
2448
|
+
if (newCoordsY[1] - newCoordsY[0] <
|
|
2449
|
+
(this.node?.type?.sections?.minHeight ||
|
|
2450
|
+
DIAGRAM_SECTION_DEFAULTS.minHeight)) {
|
|
2451
|
+
newCoordsY[0] =
|
|
2452
|
+
newCoordsY[1] -
|
|
2453
|
+
(this.node?.type?.sections?.minHeight ||
|
|
2454
|
+
DIAGRAM_SECTION_DEFAULTS.minHeight);
|
|
2394
2455
|
}
|
|
2395
2456
|
break;
|
|
2396
2457
|
case Side.Right:
|
|
2397
2458
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1] + distance];
|
|
2398
2459
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
|
|
2399
|
-
if (newCoordsX[1] - newCoordsX[0] <
|
|
2400
|
-
|
|
2460
|
+
if (newCoordsX[1] - newCoordsX[0] <
|
|
2461
|
+
(this.node?.type?.sections?.minWidth ||
|
|
2462
|
+
DIAGRAM_SECTION_DEFAULTS.minWidth)) {
|
|
2463
|
+
newCoordsX[1] =
|
|
2464
|
+
newCoordsX[0] +
|
|
2465
|
+
(this.node?.type?.sections?.minWidth ||
|
|
2466
|
+
DIAGRAM_SECTION_DEFAULTS.minWidth);
|
|
2401
2467
|
}
|
|
2402
2468
|
break;
|
|
2403
2469
|
case Side.Bottom:
|
|
2404
2470
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
|
|
2405
2471
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1] + distance];
|
|
2406
|
-
if (newCoordsY[1] - newCoordsY[0] <
|
|
2407
|
-
|
|
2472
|
+
if (newCoordsY[1] - newCoordsY[0] <
|
|
2473
|
+
(this.node?.type?.sections?.minHeight ||
|
|
2474
|
+
DIAGRAM_SECTION_DEFAULTS.minHeight)) {
|
|
2475
|
+
newCoordsY[1] =
|
|
2476
|
+
newCoordsY[0] +
|
|
2477
|
+
(this.node?.type?.sections?.minHeight ||
|
|
2478
|
+
DIAGRAM_SECTION_DEFAULTS.minHeight);
|
|
2408
2479
|
}
|
|
2409
2480
|
break;
|
|
2410
2481
|
}
|
|
@@ -2416,74 +2487,181 @@ class DiagramNode extends DiagramElement {
|
|
|
2416
2487
|
}
|
|
2417
2488
|
if (this.label) {
|
|
2418
2489
|
this.label.coords = [
|
|
2419
|
-
this.coords[0] + (this.type
|
|
2420
|
-
this.coords[1] + (this.type
|
|
2490
|
+
this.coords[0] + (this.node?.type?.sections?.label?.margin || 0),
|
|
2491
|
+
this.coords[1] + (this.node?.type?.sections?.label?.margin || 0)
|
|
2421
2492
|
];
|
|
2422
|
-
(this.label.width =
|
|
2423
|
-
|
|
2493
|
+
(this.label.width =
|
|
2494
|
+
this.width - (this.node?.type?.sections?.label?.margin || 0) * 2),
|
|
2495
|
+
(this.label.height =
|
|
2496
|
+
this.height - (this.node?.type?.sections?.label?.margin || 0) * 2);
|
|
2424
2497
|
}
|
|
2425
|
-
// we ignore this.sections, the stretching of a node with sections is handled in the stretchSections method
|
|
2426
2498
|
this.updateInView();
|
|
2427
2499
|
}
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2500
|
+
}
|
|
2501
|
+
class DiagramSectionSet extends DiagramEntitySet {
|
|
2502
|
+
constructor(model) {
|
|
2503
|
+
super();
|
|
2504
|
+
this.model = model;
|
|
2505
|
+
}
|
|
2506
|
+
new(node, coords, width, height, id, portIds, portLabelIds) {
|
|
2507
|
+
const section = new DiagramSection(this.model, node, coords, width, height, id);
|
|
2508
|
+
super.add(section);
|
|
2509
|
+
section.updateInView();
|
|
2510
|
+
// add this section to its node
|
|
2511
|
+
node.sections.push(section);
|
|
2512
|
+
node.updateInView();
|
|
2513
|
+
// add section ports
|
|
2514
|
+
if (node.type.sections?.ports && node.type.sections.ports.length > 0) {
|
|
2515
|
+
for (let i = 0; i < node.type.sections.ports.length; ++i) {
|
|
2516
|
+
const portConfig = node.type.sections.ports[i];
|
|
2517
|
+
const port = this.model.ports.new(section, [
|
|
2518
|
+
section.coords[0] + portConfig.coords[0],
|
|
2519
|
+
section.coords[1] + portConfig.coords[1]
|
|
2520
|
+
], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
|
|
2521
|
+
if (portConfig.label) {
|
|
2522
|
+
const labelConfiguration = {
|
|
2523
|
+
...DIAGRAM_FIELD_DEFAULTS,
|
|
2524
|
+
...portConfig.label
|
|
2525
|
+
};
|
|
2526
|
+
let labelCoords;
|
|
2527
|
+
switch (port.direction) {
|
|
2528
|
+
case Side.Top:
|
|
2529
|
+
case Side.Left:
|
|
2530
|
+
labelCoords = [
|
|
2531
|
+
port.coords[0] - labelConfiguration.fontSize,
|
|
2532
|
+
port.coords[1] - labelConfiguration.fontSize
|
|
2533
|
+
];
|
|
2534
|
+
break;
|
|
2535
|
+
case Side.Bottom:
|
|
2536
|
+
labelCoords = [
|
|
2537
|
+
port.coords[0] - labelConfiguration.fontSize,
|
|
2538
|
+
port.coords[1] + labelConfiguration.fontSize
|
|
2539
|
+
];
|
|
2540
|
+
break;
|
|
2541
|
+
case Side.Right:
|
|
2542
|
+
labelCoords = [
|
|
2543
|
+
port.coords[0] + labelConfiguration.fontSize,
|
|
2544
|
+
port.coords[1] - labelConfiguration.fontSize
|
|
2545
|
+
];
|
|
2546
|
+
break;
|
|
2547
|
+
default:
|
|
2548
|
+
labelCoords = port.coords;
|
|
2447
2549
|
}
|
|
2550
|
+
this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
|
|
2551
|
+
? portLabelIds[i]
|
|
2552
|
+
: undefined);
|
|
2448
2553
|
}
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
// add section label
|
|
2557
|
+
if (node.type.sections?.label) {
|
|
2558
|
+
const labelConfiguration = {
|
|
2559
|
+
...DIAGRAM_FIELD_DEFAULTS,
|
|
2560
|
+
...node.type.sections.label
|
|
2561
|
+
};
|
|
2562
|
+
this.model.fields.new(section, [
|
|
2563
|
+
section.coords[0] + labelConfiguration.margin,
|
|
2564
|
+
section.coords[1] + labelConfiguration.margin
|
|
2565
|
+
], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width - labelConfiguration.margin * 2, section.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, id);
|
|
2566
|
+
}
|
|
2567
|
+
return section;
|
|
2568
|
+
}
|
|
2569
|
+
remove(id) {
|
|
2570
|
+
const section = this.get(id);
|
|
2571
|
+
if (section) {
|
|
2572
|
+
// remove all ports
|
|
2573
|
+
while (section.ports.length > 0) {
|
|
2574
|
+
this.model.ports.remove(section.ports[0].id);
|
|
2575
|
+
}
|
|
2576
|
+
// remove label
|
|
2577
|
+
if (section.label) {
|
|
2578
|
+
this.model.fields.remove(section.label.id);
|
|
2579
|
+
}
|
|
2580
|
+
// remove from root element
|
|
2581
|
+
if (section.node) {
|
|
2582
|
+
removeIfExists(section.node.sections, section);
|
|
2583
|
+
}
|
|
2584
|
+
// remove from set of sections
|
|
2585
|
+
super.remove(id);
|
|
2586
|
+
// remove from canvas
|
|
2587
|
+
section.updateInView();
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
filter(threshold) {
|
|
2591
|
+
return this.entities.filter((e) => {
|
|
2592
|
+
if (threshold) {
|
|
2593
|
+
const node = e.node;
|
|
2594
|
+
if (node) {
|
|
2595
|
+
return node.type.priority >= threshold;
|
|
2458
2596
|
}
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2597
|
+
return false;
|
|
2598
|
+
}
|
|
2599
|
+
return true;
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
find(threshold) {
|
|
2603
|
+
return this.entities.find((e) => {
|
|
2604
|
+
if (threshold) {
|
|
2605
|
+
const node = e.node;
|
|
2606
|
+
if (node) {
|
|
2607
|
+
return node.type.priority >= threshold;
|
|
2468
2608
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2609
|
+
return false;
|
|
2610
|
+
}
|
|
2611
|
+
return true;
|
|
2612
|
+
});
|
|
2472
2613
|
}
|
|
2473
2614
|
}
|
|
2474
2615
|
|
|
2475
2616
|
let idTicker$2 = 0;
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2478
|
-
|
|
2617
|
+
const DIAGRAM_LOOK_DEFAULTS = {
|
|
2618
|
+
lookType: 'shaped-look',
|
|
2619
|
+
shape: ClosedShape.Rectangle,
|
|
2620
|
+
color: '#FFFFFF',
|
|
2621
|
+
borderColor: '#000000',
|
|
2622
|
+
selectedColor: '#FFFFFF',
|
|
2623
|
+
selectedBorderColor: '#000000'
|
|
2624
|
+
};
|
|
2625
|
+
const DIAGRAM_NODE_TYPE_DEFAULTS = {
|
|
2626
|
+
name: '',
|
|
2627
|
+
defaultWidth: 0,
|
|
2628
|
+
defaultHeight: 0,
|
|
2479
2629
|
minWidth: 0,
|
|
2480
2630
|
minHeight: 0,
|
|
2481
|
-
|
|
2631
|
+
resizableX: false,
|
|
2632
|
+
resizableY: false,
|
|
2482
2633
|
label: null,
|
|
2483
2634
|
ports: [],
|
|
2484
|
-
|
|
2635
|
+
sections: null,
|
|
2636
|
+
look: DIAGRAM_LOOK_DEFAULTS,
|
|
2637
|
+
isUnique: false,
|
|
2638
|
+
priority: 0,
|
|
2639
|
+
properties: []
|
|
2485
2640
|
};
|
|
2486
|
-
class
|
|
2641
|
+
class DiagramNodeType {
|
|
2642
|
+
constructor(options) {
|
|
2643
|
+
const values = {
|
|
2644
|
+
...DIAGRAM_NODE_TYPE_DEFAULTS,
|
|
2645
|
+
...options
|
|
2646
|
+
};
|
|
2647
|
+
this.id = values.id;
|
|
2648
|
+
this.name = values.name;
|
|
2649
|
+
this.defaultWidth = values.defaultWidth;
|
|
2650
|
+
this.defaultHeight = values.defaultHeight;
|
|
2651
|
+
this.minWidth = values.minWidth;
|
|
2652
|
+
this.minHeight = values.minHeight;
|
|
2653
|
+
this.resizableX = values.resizableX;
|
|
2654
|
+
this.resizableY = values.resizableY;
|
|
2655
|
+
this.label = values.label;
|
|
2656
|
+
this.ports = values.ports;
|
|
2657
|
+
this.sections = values.sections;
|
|
2658
|
+
this.look = values.look;
|
|
2659
|
+
this.isUnique = values.isUnique;
|
|
2660
|
+
this.priority = values.priority;
|
|
2661
|
+
this.propertySet = new PropertySet(options?.properties || []);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
class DiagramNode extends DiagramElement {
|
|
2487
2665
|
get name() {
|
|
2488
2666
|
return this.label?.text || '';
|
|
2489
2667
|
}
|
|
@@ -2493,26 +2671,29 @@ class DiagramSection extends DiagramElement {
|
|
|
2493
2671
|
this.label.updateInView();
|
|
2494
2672
|
}
|
|
2495
2673
|
}
|
|
2496
|
-
constructor(model,
|
|
2674
|
+
constructor(model, type, coords = [0, 0], id) {
|
|
2497
2675
|
let uniqueId;
|
|
2498
|
-
if (id !== undefined && model.
|
|
2676
|
+
if (id !== undefined && model.nodes.get(id) === undefined) {
|
|
2499
2677
|
uniqueId = id;
|
|
2500
2678
|
}
|
|
2501
2679
|
else {
|
|
2502
2680
|
do {
|
|
2503
|
-
uniqueId = `diagram-
|
|
2504
|
-
} while (model.
|
|
2681
|
+
uniqueId = `diagram-node-${++idTicker$2}`;
|
|
2682
|
+
} while (model.nodes.get(uniqueId) !== undefined);
|
|
2505
2683
|
}
|
|
2506
2684
|
super(model, uniqueId);
|
|
2685
|
+
this.sections = [];
|
|
2507
2686
|
this.ports = [];
|
|
2508
|
-
this.
|
|
2687
|
+
this.type = type;
|
|
2688
|
+
this.valueSet = new ValueSet(type.propertySet, this);
|
|
2689
|
+
this.originalData = {};
|
|
2509
2690
|
this.coords = coords;
|
|
2510
|
-
this.width =
|
|
2511
|
-
this.height =
|
|
2691
|
+
this.width = type.defaultWidth;
|
|
2692
|
+
this.height = type.defaultHeight;
|
|
2512
2693
|
}
|
|
2513
2694
|
updateInView() {
|
|
2514
2695
|
if (this.model.canvas && this.model.renderToCanvas) {
|
|
2515
|
-
this.model.canvas.
|
|
2696
|
+
this.model.canvas.updateNodesInView(this.id);
|
|
2516
2697
|
}
|
|
2517
2698
|
}
|
|
2518
2699
|
getClosestPortToPoint(coords) {
|
|
@@ -2559,12 +2740,36 @@ class DiagramSection extends DiagramElement {
|
|
|
2559
2740
|
}
|
|
2560
2741
|
return result;
|
|
2561
2742
|
}
|
|
2743
|
+
getAdjacentNodes() {
|
|
2744
|
+
const result = [];
|
|
2745
|
+
for (const port of this.ports) {
|
|
2746
|
+
for (const incomingConnection of port.incomingConnections) {
|
|
2747
|
+
const otherNode = incomingConnection.start?.getNode();
|
|
2748
|
+
if (otherNode) {
|
|
2749
|
+
result.push(otherNode);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
for (const outgoingConnection of port.outgoingConnections) {
|
|
2753
|
+
const otherNode = outgoingConnection.end?.getNode();
|
|
2754
|
+
if (otherNode) {
|
|
2755
|
+
result.push(otherNode);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
return result;
|
|
2760
|
+
}
|
|
2562
2761
|
move(coords) {
|
|
2563
2762
|
const coordDifferences = [
|
|
2564
2763
|
coords[0] - this.coords[0],
|
|
2565
2764
|
coords[1] - this.coords[1]
|
|
2566
2765
|
];
|
|
2567
2766
|
this.coords = coords;
|
|
2767
|
+
for (const section of this.sections) {
|
|
2768
|
+
section.move([
|
|
2769
|
+
section.coords[0] + coordDifferences[0],
|
|
2770
|
+
section.coords[1] + coordDifferences[1]
|
|
2771
|
+
]);
|
|
2772
|
+
}
|
|
2568
2773
|
for (const port of this.ports) {
|
|
2569
2774
|
port.move([
|
|
2570
2775
|
port.coords[0] + coordDifferences[0],
|
|
@@ -2589,49 +2794,29 @@ class DiagramSection extends DiagramElement {
|
|
|
2589
2794
|
case Side.Left:
|
|
2590
2795
|
newCoordsX = [oldCoordsX[0] - distance, oldCoordsX[1]];
|
|
2591
2796
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
|
|
2592
|
-
if (newCoordsX[1] - newCoordsX[0] <
|
|
2593
|
-
|
|
2594
|
-
DIAGRAM_SECTION_DEFAULTS.minWidth)) {
|
|
2595
|
-
newCoordsX[0] =
|
|
2596
|
-
newCoordsX[1] -
|
|
2597
|
-
(this.node?.type?.sections?.minWidth ||
|
|
2598
|
-
DIAGRAM_SECTION_DEFAULTS.minWidth);
|
|
2797
|
+
if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
|
|
2798
|
+
newCoordsX[0] = newCoordsX[1] - this.type.minWidth;
|
|
2599
2799
|
}
|
|
2600
2800
|
break;
|
|
2601
2801
|
case Side.Top:
|
|
2602
2802
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
|
|
2603
2803
|
newCoordsY = [oldCoordsY[0] - distance, oldCoordsY[1]];
|
|
2604
|
-
if (newCoordsY[1] - newCoordsY[0] <
|
|
2605
|
-
|
|
2606
|
-
DIAGRAM_SECTION_DEFAULTS.minHeight)) {
|
|
2607
|
-
newCoordsY[0] =
|
|
2608
|
-
newCoordsY[1] -
|
|
2609
|
-
(this.node?.type?.sections?.minHeight ||
|
|
2610
|
-
DIAGRAM_SECTION_DEFAULTS.minHeight);
|
|
2804
|
+
if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
|
|
2805
|
+
newCoordsY[0] = newCoordsY[1] - this.type.minHeight;
|
|
2611
2806
|
}
|
|
2612
2807
|
break;
|
|
2613
2808
|
case Side.Right:
|
|
2614
2809
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1] + distance];
|
|
2615
2810
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
|
|
2616
|
-
if (newCoordsX[1] - newCoordsX[0] <
|
|
2617
|
-
|
|
2618
|
-
DIAGRAM_SECTION_DEFAULTS.minWidth)) {
|
|
2619
|
-
newCoordsX[1] =
|
|
2620
|
-
newCoordsX[0] +
|
|
2621
|
-
(this.node?.type?.sections?.minWidth ||
|
|
2622
|
-
DIAGRAM_SECTION_DEFAULTS.minWidth);
|
|
2811
|
+
if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
|
|
2812
|
+
newCoordsX[1] = newCoordsX[0] + this.type.minWidth;
|
|
2623
2813
|
}
|
|
2624
2814
|
break;
|
|
2625
2815
|
case Side.Bottom:
|
|
2626
2816
|
newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
|
|
2627
2817
|
newCoordsY = [oldCoordsY[0], oldCoordsY[1] + distance];
|
|
2628
|
-
if (newCoordsY[1] - newCoordsY[0] <
|
|
2629
|
-
|
|
2630
|
-
DIAGRAM_SECTION_DEFAULTS.minHeight)) {
|
|
2631
|
-
newCoordsY[1] =
|
|
2632
|
-
newCoordsY[0] +
|
|
2633
|
-
(this.node?.type?.sections?.minHeight ||
|
|
2634
|
-
DIAGRAM_SECTION_DEFAULTS.minHeight);
|
|
2818
|
+
if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
|
|
2819
|
+
newCoordsY[1] = newCoordsY[0] + this.type.minHeight;
|
|
2635
2820
|
}
|
|
2636
2821
|
break;
|
|
2637
2822
|
}
|
|
@@ -2643,15 +2828,186 @@ class DiagramSection extends DiagramElement {
|
|
|
2643
2828
|
}
|
|
2644
2829
|
if (this.label) {
|
|
2645
2830
|
this.label.coords = [
|
|
2646
|
-
this.coords[0] + (this.
|
|
2647
|
-
this.coords[1] + (this.
|
|
2831
|
+
this.coords[0] + (this.type.label?.margin || 0),
|
|
2832
|
+
this.coords[1] + (this.type.label?.margin || 0)
|
|
2648
2833
|
];
|
|
2649
|
-
(this.label.width =
|
|
2650
|
-
this.
|
|
2651
|
-
|
|
2652
|
-
|
|
2834
|
+
(this.label.width = this.width - (this.type.label?.margin || 0) * 2),
|
|
2835
|
+
(this.label.height = this.height - (this.type.label?.margin || 0) * 2);
|
|
2836
|
+
}
|
|
2837
|
+
// we ignore this.sections, the stretching of a node with sections is handled in the stretchSections method
|
|
2838
|
+
this.updateInView();
|
|
2839
|
+
}
|
|
2840
|
+
stretchSections(direction, distance, point) {
|
|
2841
|
+
switch (direction) {
|
|
2842
|
+
case Side.Bottom:
|
|
2843
|
+
for (const section of this.sections) {
|
|
2844
|
+
if (section.coords[1] === point[1]) {
|
|
2845
|
+
section.stretch(direction, distance);
|
|
2846
|
+
}
|
|
2847
|
+
else if (section.coords[1] > point[1]) {
|
|
2848
|
+
section.move([section.coords[0], section.coords[1] + distance]);
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
break;
|
|
2852
|
+
case Side.Right:
|
|
2853
|
+
for (const section of this.sections) {
|
|
2854
|
+
if (section.coords[0] === point[0]) {
|
|
2855
|
+
section.stretch(direction, distance);
|
|
2856
|
+
}
|
|
2857
|
+
else if (section.coords[0] > point[0]) {
|
|
2858
|
+
section.move([section.coords[0] + distance, section.coords[1]]);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
break;
|
|
2862
|
+
case Side.Top:
|
|
2863
|
+
for (const section of this.sections) {
|
|
2864
|
+
if (section.coords[1] === point[1]) {
|
|
2865
|
+
section.stretch(direction, distance);
|
|
2866
|
+
}
|
|
2867
|
+
else if (section.coords[1] < point[1]) {
|
|
2868
|
+
section.move([section.coords[0], section.coords[1] - distance]);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
break;
|
|
2872
|
+
case Side.Left:
|
|
2873
|
+
for (const section of this.sections) {
|
|
2874
|
+
if (section.coords[0] === point[0]) {
|
|
2875
|
+
section.stretch(direction, distance);
|
|
2876
|
+
}
|
|
2877
|
+
else if (section.coords[0] < point[0]) {
|
|
2878
|
+
section.move([section.coords[0] - distance, section.coords[1]]);
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
break;
|
|
2882
|
+
}
|
|
2883
|
+
this.stretch(direction, distance);
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
class DiagramNodeSet extends DiagramEntitySet {
|
|
2887
|
+
constructor(model) {
|
|
2888
|
+
super();
|
|
2889
|
+
this.types = new DiagramEntitySet();
|
|
2890
|
+
this.model = model;
|
|
2891
|
+
}
|
|
2892
|
+
new(type, coords, id, sectionIds, sectionPortIds, sectionPortLabelIds, portIds, portLabelIds, labelId) {
|
|
2893
|
+
const node = new DiagramNode(this.model, type, coords, id);
|
|
2894
|
+
super.add(node);
|
|
2895
|
+
node.updateInView();
|
|
2896
|
+
// add node sections
|
|
2897
|
+
if (type.sections !== null &&
|
|
2898
|
+
(type.sections.sectionsX || 0) > 0 &&
|
|
2899
|
+
(type.sections.sectionsY || 0) > 0) {
|
|
2900
|
+
const sectionConfiguration = {
|
|
2901
|
+
...DIAGRAM_SECTION_DEFAULTS,
|
|
2902
|
+
...type.sections
|
|
2903
|
+
};
|
|
2904
|
+
const sectionsX = sectionConfiguration.sectionsX;
|
|
2905
|
+
const sectionsY = sectionConfiguration.sectionsY;
|
|
2906
|
+
const margin = sectionConfiguration.margin;
|
|
2907
|
+
const widthPerSection = (node.width - margin * (sectionsX + 1)) / sectionsX;
|
|
2908
|
+
const heightPerSection = (node.height - margin * (sectionsY + 1)) / sectionsY;
|
|
2909
|
+
let sectionCount = 0;
|
|
2910
|
+
for (let j = 0; j < sectionsY; ++j) {
|
|
2911
|
+
for (let i = 0; i < sectionsX; ++i) {
|
|
2912
|
+
const coords = [
|
|
2913
|
+
node.coords[0] + margin + i * (widthPerSection + margin),
|
|
2914
|
+
node.coords[1] + margin + j * (heightPerSection + margin)
|
|
2915
|
+
];
|
|
2916
|
+
this.model.sections.new(node, coords, widthPerSection, heightPerSection, sectionIds && sectionIds.length > sectionCount
|
|
2917
|
+
? sectionIds[sectionCount]
|
|
2918
|
+
: undefined, sectionPortIds && sectionPortIds.length > sectionCount
|
|
2919
|
+
? sectionPortIds[sectionCount]
|
|
2920
|
+
: undefined, sectionPortLabelIds && sectionPortLabelIds.length > sectionCount
|
|
2921
|
+
? sectionPortLabelIds[sectionCount]
|
|
2922
|
+
: undefined);
|
|
2923
|
+
++sectionCount;
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
// add node ports
|
|
2928
|
+
if (type.ports.length > 0) {
|
|
2929
|
+
for (let i = 0; i < type.ports.length; ++i) {
|
|
2930
|
+
const portConfig = type.ports[i];
|
|
2931
|
+
const port = this.model.ports.new(node, [
|
|
2932
|
+
node.coords[0] + portConfig.coords[0],
|
|
2933
|
+
node.coords[1] + portConfig.coords[1]
|
|
2934
|
+
], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
|
|
2935
|
+
if (portConfig.label) {
|
|
2936
|
+
const labelConfiguration = {
|
|
2937
|
+
...DIAGRAM_FIELD_DEFAULTS,
|
|
2938
|
+
...portConfig.label
|
|
2939
|
+
};
|
|
2940
|
+
let labelCoords;
|
|
2941
|
+
switch (port.direction) {
|
|
2942
|
+
case Side.Top:
|
|
2943
|
+
case Side.Left:
|
|
2944
|
+
labelCoords = [
|
|
2945
|
+
port.coords[0] - labelConfiguration.fontSize,
|
|
2946
|
+
port.coords[1] - labelConfiguration.fontSize
|
|
2947
|
+
];
|
|
2948
|
+
break;
|
|
2949
|
+
case Side.Bottom:
|
|
2950
|
+
labelCoords = [
|
|
2951
|
+
port.coords[0] - labelConfiguration.fontSize,
|
|
2952
|
+
port.coords[1] + labelConfiguration.fontSize
|
|
2953
|
+
];
|
|
2954
|
+
break;
|
|
2955
|
+
case Side.Right:
|
|
2956
|
+
labelCoords = [
|
|
2957
|
+
port.coords[0] + labelConfiguration.fontSize,
|
|
2958
|
+
port.coords[1] - labelConfiguration.fontSize
|
|
2959
|
+
];
|
|
2960
|
+
break;
|
|
2961
|
+
default:
|
|
2962
|
+
labelCoords = port.coords;
|
|
2963
|
+
}
|
|
2964
|
+
this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
|
|
2965
|
+
? portLabelIds[i]
|
|
2966
|
+
: undefined);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2653
2969
|
}
|
|
2654
|
-
|
|
2970
|
+
// add node label
|
|
2971
|
+
if (type.label) {
|
|
2972
|
+
const labelConfiguration = {
|
|
2973
|
+
...DIAGRAM_FIELD_DEFAULTS,
|
|
2974
|
+
...type.label
|
|
2975
|
+
};
|
|
2976
|
+
this.model.fields.new(node, [
|
|
2977
|
+
node.coords[0] + labelConfiguration.margin,
|
|
2978
|
+
node.coords[1] + labelConfiguration.margin
|
|
2979
|
+
], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width - labelConfiguration.margin * 2, node.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelId);
|
|
2980
|
+
}
|
|
2981
|
+
return node;
|
|
2982
|
+
}
|
|
2983
|
+
remove(id) {
|
|
2984
|
+
const node = this.get(id);
|
|
2985
|
+
if (node) {
|
|
2986
|
+
// remove all sections
|
|
2987
|
+
while (node.sections.length > 0) {
|
|
2988
|
+
this.model.sections.remove(node.sections[0].id);
|
|
2989
|
+
}
|
|
2990
|
+
// remove all ports
|
|
2991
|
+
while (node.ports.length > 0) {
|
|
2992
|
+
this.model.ports.remove(node.ports[0].id);
|
|
2993
|
+
}
|
|
2994
|
+
// remove label
|
|
2995
|
+
if (node.label) {
|
|
2996
|
+
this.model.fields.remove(node.label.id);
|
|
2997
|
+
}
|
|
2998
|
+
// remove from set of nodes
|
|
2999
|
+
super.remove(id);
|
|
3000
|
+
// remove from canvas
|
|
3001
|
+
node.updateInView();
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
filter(type, threshold) {
|
|
3005
|
+
return this.entities.filter((e) => (type ? e.type.id === type : true) &&
|
|
3006
|
+
(threshold ? e.type.priority >= threshold : true));
|
|
3007
|
+
}
|
|
3008
|
+
find(type, threshold) {
|
|
3009
|
+
return this.entities.find((e) => (type ? e.type.id === type : true) &&
|
|
3010
|
+
(threshold ? e.type.priority >= threshold : true));
|
|
2655
3011
|
}
|
|
2656
3012
|
}
|
|
2657
3013
|
|
|
@@ -2664,13 +3020,13 @@ const DIAGRAM_PORT_DEFAULTS = {
|
|
|
2664
3020
|
class DiagramPort extends DiagramElement {
|
|
2665
3021
|
constructor(model, rootElement, coords, direction, id) {
|
|
2666
3022
|
let uniqueId;
|
|
2667
|
-
if (id !== undefined && model.
|
|
3023
|
+
if (id !== undefined && model.ports.get(id) === undefined) {
|
|
2668
3024
|
uniqueId = id;
|
|
2669
3025
|
}
|
|
2670
3026
|
else {
|
|
2671
3027
|
do {
|
|
2672
3028
|
uniqueId = `diagram-port-${++idTicker$1}`;
|
|
2673
|
-
} while (model.
|
|
3029
|
+
} while (model.ports.get(uniqueId) !== undefined);
|
|
2674
3030
|
}
|
|
2675
3031
|
super(model, uniqueId);
|
|
2676
3032
|
this.outgoingConnections = [];
|
|
@@ -2723,6 +3079,71 @@ class DiagramPort extends DiagramElement {
|
|
|
2723
3079
|
return distanceBetweenPoints(this.coords, coords);
|
|
2724
3080
|
}
|
|
2725
3081
|
}
|
|
3082
|
+
class DiagramPortSet extends DiagramEntitySet {
|
|
3083
|
+
constructor(model) {
|
|
3084
|
+
super();
|
|
3085
|
+
this.model = model;
|
|
3086
|
+
}
|
|
3087
|
+
new(rootElement, coords, direction, id) {
|
|
3088
|
+
const port = new DiagramPort(this.model, rootElement, coords, direction, id);
|
|
3089
|
+
super.add(port);
|
|
3090
|
+
port.updateInView();
|
|
3091
|
+
// add this port to its root element
|
|
3092
|
+
if (rootElement !== undefined) {
|
|
3093
|
+
rootElement.ports.push(port);
|
|
3094
|
+
}
|
|
3095
|
+
return port;
|
|
3096
|
+
}
|
|
3097
|
+
remove(id) {
|
|
3098
|
+
const port = this.get(id);
|
|
3099
|
+
if (port) {
|
|
3100
|
+
// remove all connections
|
|
3101
|
+
while (port.outgoingConnections.length > 0) {
|
|
3102
|
+
this.model.connections.remove(port.outgoingConnections[0].id);
|
|
3103
|
+
}
|
|
3104
|
+
while (port.incomingConnections.length > 0) {
|
|
3105
|
+
this.model.connections.remove(port.incomingConnections[0].id);
|
|
3106
|
+
}
|
|
3107
|
+
// remove label
|
|
3108
|
+
if (port.label) {
|
|
3109
|
+
this.model.fields.remove(port.label.id);
|
|
3110
|
+
}
|
|
3111
|
+
// remove from root element
|
|
3112
|
+
if (port.rootElement instanceof DiagramNode ||
|
|
3113
|
+
port.rootElement instanceof DiagramSection) {
|
|
3114
|
+
removeIfExists(port.rootElement.ports, port);
|
|
3115
|
+
}
|
|
3116
|
+
// remove from set of ports
|
|
3117
|
+
super.remove(id);
|
|
3118
|
+
// remove from canvas
|
|
3119
|
+
port.updateInView();
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
filter(threshold) {
|
|
3123
|
+
return this.entities.filter((e) => {
|
|
3124
|
+
if (threshold) {
|
|
3125
|
+
const node = e.getNode();
|
|
3126
|
+
if (node) {
|
|
3127
|
+
return node !== undefined && node.type.priority >= threshold;
|
|
3128
|
+
}
|
|
3129
|
+
return false;
|
|
3130
|
+
}
|
|
3131
|
+
return true;
|
|
3132
|
+
});
|
|
3133
|
+
}
|
|
3134
|
+
find(threshold) {
|
|
3135
|
+
return this.entities.find((e) => {
|
|
3136
|
+
if (threshold) {
|
|
3137
|
+
const node = e.getNode();
|
|
3138
|
+
if (node) {
|
|
3139
|
+
return node !== undefined && node.type.priority >= threshold;
|
|
3140
|
+
}
|
|
3141
|
+
return false;
|
|
3142
|
+
}
|
|
3143
|
+
return true;
|
|
3144
|
+
});
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
2726
3147
|
|
|
2727
3148
|
let idTicker = 0;
|
|
2728
3149
|
const DIAGRAM_FIELD_DEFAULTS = {
|
|
@@ -2749,13 +3170,13 @@ class DiagramField extends DiagramElement {
|
|
|
2749
3170
|
}
|
|
2750
3171
|
constructor(model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id) {
|
|
2751
3172
|
let uniqueId;
|
|
2752
|
-
if (id !== undefined && model.
|
|
3173
|
+
if (id !== undefined && model.fields.get(id) === undefined) {
|
|
2753
3174
|
uniqueId = id;
|
|
2754
3175
|
}
|
|
2755
3176
|
else {
|
|
2756
3177
|
do {
|
|
2757
3178
|
uniqueId = `diagram-field-${++idTicker}`;
|
|
2758
|
-
} while (model.
|
|
3179
|
+
} while (model.fields.get(uniqueId) !== undefined);
|
|
2759
3180
|
}
|
|
2760
3181
|
super(model, uniqueId);
|
|
2761
3182
|
this.rootElement = rootElement;
|
|
@@ -2794,6 +3215,57 @@ class DiagramField extends DiagramElement {
|
|
|
2794
3215
|
return undefined;
|
|
2795
3216
|
}
|
|
2796
3217
|
}
|
|
3218
|
+
class DiagramFieldSet extends DiagramEntitySet {
|
|
3219
|
+
constructor(model) {
|
|
3220
|
+
super();
|
|
3221
|
+
this.model = model;
|
|
3222
|
+
}
|
|
3223
|
+
new(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, text, editable, id) {
|
|
3224
|
+
const field = new DiagramField(this.model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id);
|
|
3225
|
+
super.add(field);
|
|
3226
|
+
field.updateInView();
|
|
3227
|
+
// add this field to its root element
|
|
3228
|
+
if (rootElement !== undefined) {
|
|
3229
|
+
rootElement.label = field;
|
|
3230
|
+
}
|
|
3231
|
+
return field;
|
|
3232
|
+
}
|
|
3233
|
+
remove(id) {
|
|
3234
|
+
const field = this.get(id);
|
|
3235
|
+
if (field) {
|
|
3236
|
+
// remove from root element
|
|
3237
|
+
if (field.rootElement instanceof DiagramNode ||
|
|
3238
|
+
field.rootElement instanceof DiagramSection ||
|
|
3239
|
+
field.rootElement instanceof DiagramPort) {
|
|
3240
|
+
if (field.rootElement.label === field) {
|
|
3241
|
+
field.rootElement.label = undefined;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
// remove from set of fields
|
|
3245
|
+
super.remove(id);
|
|
3246
|
+
// remove from canvas
|
|
3247
|
+
field.updateInView();
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
filter(threshold) {
|
|
3251
|
+
return this.entities.filter((e) => {
|
|
3252
|
+
if (threshold) {
|
|
3253
|
+
const node = e.getClosestNode();
|
|
3254
|
+
return node !== undefined && node.type.priority >= threshold;
|
|
3255
|
+
}
|
|
3256
|
+
return true;
|
|
3257
|
+
});
|
|
3258
|
+
}
|
|
3259
|
+
find(threshold) {
|
|
3260
|
+
return this.entities.find((e) => {
|
|
3261
|
+
if (threshold) {
|
|
3262
|
+
const node = e.getClosestNode();
|
|
3263
|
+
return node !== undefined && node.type.priority >= threshold;
|
|
3264
|
+
}
|
|
3265
|
+
return true;
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
2797
3269
|
|
|
2798
3270
|
class DiagramModel {
|
|
2799
3271
|
// canvas attribute accesors
|
|
@@ -2808,13 +3280,11 @@ class DiagramModel {
|
|
|
2808
3280
|
}
|
|
2809
3281
|
constructor(canvas, id, name, description, type, properties = []) {
|
|
2810
3282
|
this.renderToCanvas = true;
|
|
2811
|
-
this.
|
|
2812
|
-
this.
|
|
2813
|
-
this.
|
|
2814
|
-
this.
|
|
2815
|
-
this.
|
|
2816
|
-
this.connections = [];
|
|
2817
|
-
this.fields = [];
|
|
3283
|
+
this.nodes = new DiagramNodeSet(this);
|
|
3284
|
+
this.sections = new DiagramSectionSet(this);
|
|
3285
|
+
this.ports = new DiagramPortSet(this);
|
|
3286
|
+
this.connections = new DiagramConnectionSet(this);
|
|
3287
|
+
this.fields = new DiagramFieldSet(this);
|
|
2818
3288
|
this.canvas = canvas;
|
|
2819
3289
|
this.id = id;
|
|
2820
3290
|
this.name = name;
|
|
@@ -2838,390 +3308,29 @@ class DiagramModel {
|
|
|
2838
3308
|
this.id = undefined;
|
|
2839
3309
|
this.name = '';
|
|
2840
3310
|
this.description = undefined;
|
|
2841
|
-
this.nodes = [];
|
|
2842
|
-
this.ports = [];
|
|
2843
|
-
this.connections = [];
|
|
2844
|
-
this.fields = [];
|
|
2845
3311
|
this.createdAt = new Date();
|
|
2846
3312
|
this.updatedAt = new Date();
|
|
3313
|
+
this.nodes.clear();
|
|
3314
|
+
this.sections.clear();
|
|
3315
|
+
this.ports.clear();
|
|
3316
|
+
this.connections.clear();
|
|
3317
|
+
this.fields.clear();
|
|
2847
3318
|
this.valueSet.resetValues();
|
|
2848
3319
|
if (this.renderToCanvas) {
|
|
2849
3320
|
this.canvas?.cancelAllUserActions();
|
|
2850
3321
|
this.canvas?.updateModelInView();
|
|
2851
3322
|
}
|
|
2852
3323
|
}
|
|
2853
|
-
getElement(id) {
|
|
2854
|
-
return (this.getNode(id) ||
|
|
2855
|
-
this.getSection(id) ||
|
|
2856
|
-
this.getPort(id) ||
|
|
2857
|
-
this.getConnection(id) ||
|
|
2858
|
-
this.getField(id));
|
|
2859
|
-
}
|
|
2860
|
-
deleteElement(element) {
|
|
2861
|
-
if (element instanceof DiagramNode) {
|
|
2862
|
-
this.deleteNode(element);
|
|
2863
|
-
}
|
|
2864
|
-
else if (element instanceof DiagramSection) {
|
|
2865
|
-
this.deleteSection(element);
|
|
2866
|
-
}
|
|
2867
|
-
else if (element instanceof DiagramPort) {
|
|
2868
|
-
this.deletePort(element);
|
|
2869
|
-
}
|
|
2870
|
-
else if (element instanceof DiagramConnection) {
|
|
2871
|
-
this.deleteConnection(element);
|
|
2872
|
-
}
|
|
2873
|
-
else if (element instanceof DiagramField) {
|
|
2874
|
-
this.deleteField(element);
|
|
2875
|
-
}
|
|
2876
|
-
}
|
|
2877
|
-
getNodeType(name) {
|
|
2878
|
-
return this.nodeTypes.find((e) => e.id === name);
|
|
2879
|
-
}
|
|
2880
|
-
getConnectionType(name) {
|
|
2881
|
-
return this.connectionTypes.find((e) => e.id === name);
|
|
2882
|
-
}
|
|
2883
|
-
getNode(id) {
|
|
2884
|
-
return this.nodes.find((e) => e.id === id);
|
|
2885
|
-
}
|
|
2886
|
-
getNodes(threshold) {
|
|
2887
|
-
if (threshold === undefined) {
|
|
2888
|
-
return this.nodes;
|
|
2889
|
-
}
|
|
2890
|
-
else {
|
|
2891
|
-
return this.nodes.filter((e) => e.type.priority >= threshold);
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
getNodesOfType(type) {
|
|
2895
|
-
return this.nodes.filter((e) => e.type.id === type);
|
|
2896
|
-
}
|
|
2897
|
-
addNode(type, coords, id, sectionIds, sectionPortIds, sectionPortLabelIds, portIds, portLabelIds, labelId) {
|
|
2898
|
-
const newNode = new DiagramNode(this, type, coords, id);
|
|
2899
|
-
this.nodes.push(newNode);
|
|
2900
|
-
newNode.updateInView();
|
|
2901
|
-
// add node sections
|
|
2902
|
-
if (type.sections !== null &&
|
|
2903
|
-
(type.sections.sectionsX || 0) > 0 &&
|
|
2904
|
-
(type.sections.sectionsY || 0) > 0) {
|
|
2905
|
-
const sectionConfiguration = {
|
|
2906
|
-
...DIAGRAM_SECTION_DEFAULTS,
|
|
2907
|
-
...type.sections
|
|
2908
|
-
};
|
|
2909
|
-
const sectionsX = sectionConfiguration.sectionsX;
|
|
2910
|
-
const sectionsY = sectionConfiguration.sectionsY;
|
|
2911
|
-
const margin = sectionConfiguration.margin;
|
|
2912
|
-
const widthPerSection = (newNode.width - margin * (sectionsX + 1)) / sectionsX;
|
|
2913
|
-
const heightPerSection = (newNode.height - margin * (sectionsY + 1)) / sectionsY;
|
|
2914
|
-
let sectionCount = 0;
|
|
2915
|
-
for (let j = 0; j < sectionsY; ++j) {
|
|
2916
|
-
for (let i = 0; i < sectionsX; ++i) {
|
|
2917
|
-
const coords = [
|
|
2918
|
-
newNode.coords[0] + margin + i * (widthPerSection + margin),
|
|
2919
|
-
newNode.coords[1] + margin + j * (heightPerSection + margin)
|
|
2920
|
-
];
|
|
2921
|
-
this.addSection(newNode, coords, widthPerSection, heightPerSection, sectionIds && sectionIds.length > sectionCount
|
|
2922
|
-
? sectionIds[sectionCount]
|
|
2923
|
-
: undefined, sectionPortIds && sectionPortIds.length > sectionCount
|
|
2924
|
-
? sectionPortIds[sectionCount]
|
|
2925
|
-
: undefined, sectionPortLabelIds && sectionPortLabelIds.length > sectionCount
|
|
2926
|
-
? sectionPortLabelIds[sectionCount]
|
|
2927
|
-
: undefined);
|
|
2928
|
-
++sectionCount;
|
|
2929
|
-
}
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
// add node ports
|
|
2933
|
-
if (type.ports.length > 0) {
|
|
2934
|
-
for (let i = 0; i < type.ports.length; ++i) {
|
|
2935
|
-
const portConfig = type.ports[i];
|
|
2936
|
-
const newPort = this.addPort(newNode, [
|
|
2937
|
-
newNode.coords[0] + portConfig.coords[0],
|
|
2938
|
-
newNode.coords[1] + portConfig.coords[1]
|
|
2939
|
-
], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
|
|
2940
|
-
if (portConfig.label) {
|
|
2941
|
-
const labelConfiguration = {
|
|
2942
|
-
...DIAGRAM_FIELD_DEFAULTS,
|
|
2943
|
-
...portConfig.label
|
|
2944
|
-
};
|
|
2945
|
-
let labelCoords;
|
|
2946
|
-
switch (newPort.direction) {
|
|
2947
|
-
case Side.Top:
|
|
2948
|
-
case Side.Left:
|
|
2949
|
-
labelCoords = [
|
|
2950
|
-
newPort.coords[0] - labelConfiguration.fontSize,
|
|
2951
|
-
newPort.coords[1] - labelConfiguration.fontSize
|
|
2952
|
-
];
|
|
2953
|
-
break;
|
|
2954
|
-
case Side.Bottom:
|
|
2955
|
-
labelCoords = [
|
|
2956
|
-
newPort.coords[0] - labelConfiguration.fontSize,
|
|
2957
|
-
newPort.coords[1] + labelConfiguration.fontSize
|
|
2958
|
-
];
|
|
2959
|
-
break;
|
|
2960
|
-
case Side.Right:
|
|
2961
|
-
labelCoords = [
|
|
2962
|
-
newPort.coords[0] + labelConfiguration.fontSize,
|
|
2963
|
-
newPort.coords[1] - labelConfiguration.fontSize
|
|
2964
|
-
];
|
|
2965
|
-
break;
|
|
2966
|
-
default:
|
|
2967
|
-
labelCoords = newPort.coords;
|
|
2968
|
-
}
|
|
2969
|
-
const newField = this.addField(newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
|
|
2970
|
-
? portLabelIds[i]
|
|
2971
|
-
: undefined);
|
|
2972
|
-
newPort.label = newField;
|
|
2973
|
-
}
|
|
2974
|
-
}
|
|
2975
|
-
}
|
|
2976
|
-
// add node label
|
|
2977
|
-
if (type.label) {
|
|
2978
|
-
const labelConfiguration = {
|
|
2979
|
-
...DIAGRAM_FIELD_DEFAULTS,
|
|
2980
|
-
...type.label
|
|
2981
|
-
};
|
|
2982
|
-
const newField = this.addField(newNode, [
|
|
2983
|
-
newNode.coords[0] + labelConfiguration.margin,
|
|
2984
|
-
newNode.coords[1] + labelConfiguration.margin
|
|
2985
|
-
], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, newNode.width - labelConfiguration.margin * 2, newNode.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelId);
|
|
2986
|
-
newNode.label = newField;
|
|
2987
|
-
}
|
|
2988
|
-
return newNode;
|
|
2989
|
-
}
|
|
2990
|
-
deleteNode(node) {
|
|
2991
|
-
// remove all ports
|
|
2992
|
-
while (node.sections.length > 0) {
|
|
2993
|
-
this.deleteSection(node.sections[0]);
|
|
2994
|
-
}
|
|
2995
|
-
while (node.ports.length > 0) {
|
|
2996
|
-
this.deletePort(node.ports[0]);
|
|
2997
|
-
}
|
|
2998
|
-
if (node.label) {
|
|
2999
|
-
this.deleteField(node.label);
|
|
3000
|
-
}
|
|
3001
|
-
// remove from list of nodes
|
|
3002
|
-
removeIfExists(this.nodes, node);
|
|
3003
|
-
node.updateInView();
|
|
3004
|
-
}
|
|
3005
|
-
hasNodeOfType(type) {
|
|
3006
|
-
return this.nodes.find((e) => e.type.id === type) !== undefined;
|
|
3007
|
-
}
|
|
3008
|
-
getSection(id) {
|
|
3009
|
-
return this.sections.find((e) => e.id === id);
|
|
3010
|
-
}
|
|
3011
|
-
getSections(threshold) {
|
|
3012
|
-
if (threshold === undefined) {
|
|
3013
|
-
return this.sections;
|
|
3014
|
-
}
|
|
3015
|
-
else {
|
|
3016
|
-
return this.sections.filter((e) => (e.node?.type?.priority || Number.NEGATIVE_INFINITY) >= threshold);
|
|
3017
|
-
}
|
|
3018
|
-
}
|
|
3019
|
-
addSection(node, coords, width, height, id, portIds, portLabelIds) {
|
|
3020
|
-
const newSection = new DiagramSection(this, node, coords, width, height, id);
|
|
3021
|
-
this.sections.push(newSection);
|
|
3022
|
-
newSection.updateInView();
|
|
3023
|
-
// add to node
|
|
3024
|
-
node.sections.push(newSection);
|
|
3025
|
-
node.updateInView();
|
|
3026
|
-
// add section ports
|
|
3027
|
-
if (node.type.sections?.ports && node.type.sections.ports.length > 0) {
|
|
3028
|
-
for (let i = 0; i < node.type.sections.ports.length; ++i) {
|
|
3029
|
-
const portConfig = node.type.sections.ports[i];
|
|
3030
|
-
const newPort = this.addPort(newSection, [
|
|
3031
|
-
newSection.coords[0] + portConfig.coords[0],
|
|
3032
|
-
newSection.coords[1] + portConfig.coords[1]
|
|
3033
|
-
], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
|
|
3034
|
-
if (portConfig.label) {
|
|
3035
|
-
const labelConfiguration = {
|
|
3036
|
-
...DIAGRAM_FIELD_DEFAULTS,
|
|
3037
|
-
...portConfig.label
|
|
3038
|
-
};
|
|
3039
|
-
let labelCoords;
|
|
3040
|
-
switch (newPort.direction) {
|
|
3041
|
-
case Side.Top:
|
|
3042
|
-
case Side.Left:
|
|
3043
|
-
labelCoords = [
|
|
3044
|
-
newPort.coords[0] - labelConfiguration.fontSize,
|
|
3045
|
-
newPort.coords[1] - labelConfiguration.fontSize
|
|
3046
|
-
];
|
|
3047
|
-
break;
|
|
3048
|
-
case Side.Bottom:
|
|
3049
|
-
labelCoords = [
|
|
3050
|
-
newPort.coords[0] - labelConfiguration.fontSize,
|
|
3051
|
-
newPort.coords[1] + labelConfiguration.fontSize
|
|
3052
|
-
];
|
|
3053
|
-
break;
|
|
3054
|
-
case Side.Right:
|
|
3055
|
-
labelCoords = [
|
|
3056
|
-
newPort.coords[0] + labelConfiguration.fontSize,
|
|
3057
|
-
newPort.coords[1] - labelConfiguration.fontSize
|
|
3058
|
-
];
|
|
3059
|
-
break;
|
|
3060
|
-
default:
|
|
3061
|
-
labelCoords = newPort.coords;
|
|
3062
|
-
}
|
|
3063
|
-
const newField = this.addField(newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
|
|
3064
|
-
? portLabelIds[i]
|
|
3065
|
-
: undefined);
|
|
3066
|
-
newPort.label = newField;
|
|
3067
|
-
}
|
|
3068
|
-
}
|
|
3069
|
-
}
|
|
3070
|
-
// add section label
|
|
3071
|
-
if (node.type.sections?.label) {
|
|
3072
|
-
const labelConfiguration = {
|
|
3073
|
-
...DIAGRAM_FIELD_DEFAULTS,
|
|
3074
|
-
...node.type.sections.label
|
|
3075
|
-
};
|
|
3076
|
-
const newField = this.addField(newSection, [
|
|
3077
|
-
newSection.coords[0] + labelConfiguration.margin,
|
|
3078
|
-
newSection.coords[1] + labelConfiguration.margin
|
|
3079
|
-
], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, newSection.width - labelConfiguration.margin * 2, newSection.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, id);
|
|
3080
|
-
newSection.label = newField;
|
|
3081
|
-
}
|
|
3082
|
-
return newSection;
|
|
3083
|
-
}
|
|
3084
|
-
deleteSection(section) {
|
|
3085
|
-
// remove all ports
|
|
3086
|
-
while (section.ports.length > 0) {
|
|
3087
|
-
this.deletePort(section.ports[0]);
|
|
3088
|
-
}
|
|
3089
|
-
if (section.label) {
|
|
3090
|
-
this.deleteField(section.label);
|
|
3091
|
-
}
|
|
3092
|
-
// remove from list of sections
|
|
3093
|
-
if (section.node) {
|
|
3094
|
-
removeIfExists(section.node?.sections, section);
|
|
3095
|
-
}
|
|
3096
|
-
removeIfExists(this.sections, section);
|
|
3097
|
-
section.updateInView();
|
|
3098
|
-
}
|
|
3099
|
-
getPort(id) {
|
|
3100
|
-
return this.ports.find((e) => e.id === id);
|
|
3101
|
-
}
|
|
3102
|
-
getPorts(threshold) {
|
|
3103
|
-
if (threshold === undefined) {
|
|
3104
|
-
return this.ports;
|
|
3105
|
-
}
|
|
3106
|
-
else {
|
|
3107
|
-
return this.ports.filter((e) => (e.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >= threshold);
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
addPort(rootElement, coords, direction, id) {
|
|
3111
|
-
const newPort = new DiagramPort(this, rootElement, coords, direction, id);
|
|
3112
|
-
this.ports.push(newPort);
|
|
3113
|
-
if (rootElement instanceof DiagramNode) {
|
|
3114
|
-
rootElement.ports.push(newPort);
|
|
3115
|
-
}
|
|
3116
|
-
else if (rootElement instanceof DiagramSection) {
|
|
3117
|
-
rootElement.ports.push(newPort);
|
|
3118
|
-
}
|
|
3119
|
-
newPort.updateInView();
|
|
3120
|
-
return newPort;
|
|
3121
|
-
}
|
|
3122
|
-
deletePort(port) {
|
|
3123
|
-
// remove all connections
|
|
3124
|
-
while (port.outgoingConnections.length > 0) {
|
|
3125
|
-
this.deleteConnection(port.outgoingConnections[0]);
|
|
3126
|
-
}
|
|
3127
|
-
while (port.incomingConnections.length > 0) {
|
|
3128
|
-
this.deleteConnection(port.incomingConnections[0]);
|
|
3129
|
-
}
|
|
3130
|
-
// remove label
|
|
3131
|
-
if (port.label) {
|
|
3132
|
-
this.deleteField(port.label);
|
|
3133
|
-
}
|
|
3134
|
-
// remove from lists of ports
|
|
3135
|
-
if (port.rootElement instanceof DiagramNode) {
|
|
3136
|
-
removeIfExists(port.rootElement.ports, port);
|
|
3137
|
-
}
|
|
3138
|
-
else if (port.rootElement instanceof DiagramSection) {
|
|
3139
|
-
removeIfExists(port.rootElement.ports, port);
|
|
3140
|
-
}
|
|
3141
|
-
removeIfExists(this.ports, port);
|
|
3142
|
-
// remove from canvas
|
|
3143
|
-
port.updateInView();
|
|
3144
|
-
}
|
|
3145
|
-
getConnection(id) {
|
|
3146
|
-
return this.connections.find((e) => e.id === id);
|
|
3147
|
-
}
|
|
3148
|
-
getConnections(threshold) {
|
|
3149
|
-
if (threshold === undefined) {
|
|
3150
|
-
return this.connections;
|
|
3151
|
-
}
|
|
3152
|
-
else {
|
|
3153
|
-
return this.connections.filter((e) => (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
3154
|
-
threshold &&
|
|
3155
|
-
(e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
|
|
3156
|
-
threshold);
|
|
3157
|
-
}
|
|
3158
|
-
}
|
|
3159
|
-
getConnectionsOfType(type) {
|
|
3160
|
-
return this.connections.filter((e) => e.type.id === type);
|
|
3161
|
-
}
|
|
3162
|
-
addConnection(type, start, end, id) {
|
|
3163
|
-
const newConnection = new DiagramConnection(this, type, start, end, id);
|
|
3164
|
-
this.connections.push(newConnection);
|
|
3165
|
-
newConnection.updateInView();
|
|
3166
|
-
return newConnection;
|
|
3167
|
-
}
|
|
3168
|
-
deleteConnection(connection) {
|
|
3169
|
-
// remove port labels
|
|
3170
|
-
if (connection.start?.label) {
|
|
3171
|
-
this.deleteField(connection.start.label);
|
|
3172
|
-
}
|
|
3173
|
-
if (connection.end?.label) {
|
|
3174
|
-
this.deleteField(connection.end.label);
|
|
3175
|
-
}
|
|
3176
|
-
// remove from lists of connections
|
|
3177
|
-
removeIfExists(connection.start?.outgoingConnections || [], connection);
|
|
3178
|
-
removeIfExists(connection.end?.incomingConnections || [], connection);
|
|
3179
|
-
removeIfExists(this.connections, connection);
|
|
3180
|
-
// remove from canvas
|
|
3181
|
-
connection.updateInView();
|
|
3182
|
-
}
|
|
3183
|
-
getField(id) {
|
|
3184
|
-
return this.fields.find((e) => e.id === id);
|
|
3185
|
-
}
|
|
3186
|
-
getFields(threshold) {
|
|
3187
|
-
if (threshold === undefined) {
|
|
3188
|
-
return this.fields;
|
|
3189
|
-
}
|
|
3190
|
-
else {
|
|
3191
|
-
return this.fields.filter((e) => {
|
|
3192
|
-
const node = e.getClosestNode();
|
|
3193
|
-
return node !== undefined && node.type.priority >= threshold;
|
|
3194
|
-
});
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
addField(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, text, editable, id) {
|
|
3198
|
-
const newField = new DiagramField(this, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id);
|
|
3199
|
-
this.fields.push(newField);
|
|
3200
|
-
newField.updateInView();
|
|
3201
|
-
return newField;
|
|
3202
|
-
}
|
|
3203
|
-
deleteField(field) {
|
|
3204
|
-
// remove from lists of fields
|
|
3205
|
-
removeIfExists(this.fields, field);
|
|
3206
|
-
if (field.rootElement instanceof DiagramNode) {
|
|
3207
|
-
if (field.rootElement.label === field) {
|
|
3208
|
-
field.rootElement.label = undefined;
|
|
3209
|
-
}
|
|
3210
|
-
}
|
|
3211
|
-
else if (field.rootElement instanceof DiagramPort) {
|
|
3212
|
-
if (field.rootElement.label === field) {
|
|
3213
|
-
field.rootElement.label = undefined;
|
|
3214
|
-
}
|
|
3215
|
-
}
|
|
3216
|
-
// remove from canvas
|
|
3217
|
-
field.updateInView();
|
|
3218
|
-
}
|
|
3219
3324
|
}
|
|
3220
3325
|
|
|
3221
3326
|
/**
|
|
3222
3327
|
* Thickness of the invisible path around a connection used to make it easier to click on, in pixels.
|
|
3223
3328
|
*/
|
|
3224
3329
|
const CONNECTION_PATH_BOX_THICKNESS = 12;
|
|
3330
|
+
/**
|
|
3331
|
+
* Thickness of the resizer line used to resize nodes and sections on drag, in pixels.
|
|
3332
|
+
*/
|
|
3333
|
+
const RESIZER_THICKNESS = 6;
|
|
3225
3334
|
/**
|
|
3226
3335
|
* Text to display as the title of the property editor when editing this diagram's properties.
|
|
3227
3336
|
* @see PropertyEditorComponent
|
|
@@ -3264,7 +3373,7 @@ class DiagramCanvas {
|
|
|
3264
3373
|
...config.nodeTypeDefaults,
|
|
3265
3374
|
...nodeTypeConfig
|
|
3266
3375
|
});
|
|
3267
|
-
this.model.
|
|
3376
|
+
this.model.nodes.types.add(nodeType);
|
|
3268
3377
|
}
|
|
3269
3378
|
}
|
|
3270
3379
|
// load connection types
|
|
@@ -3274,11 +3383,11 @@ class DiagramCanvas {
|
|
|
3274
3383
|
...config.connectionTypeDefaults,
|
|
3275
3384
|
...connectionTypeConfig
|
|
3276
3385
|
});
|
|
3277
|
-
this.model.
|
|
3386
|
+
this.model.connections.types.add(connectionType);
|
|
3278
3387
|
}
|
|
3279
3388
|
this.connectionType =
|
|
3280
3389
|
config.defaultConnection !== undefined
|
|
3281
|
-
? this.model.
|
|
3390
|
+
? this.model.connections.types.get(config.defaultConnection)
|
|
3282
3391
|
: undefined;
|
|
3283
3392
|
}
|
|
3284
3393
|
}
|
|
@@ -3295,11 +3404,9 @@ class DiagramCanvas {
|
|
|
3295
3404
|
this.diagramRoot = d3.select(appendTo).append('div').node();
|
|
3296
3405
|
d3.select(this.diagramRoot)
|
|
3297
3406
|
.attr('tabindex', 0) // make element focusable
|
|
3298
|
-
.style('position', 'absolute')
|
|
3299
3407
|
.style('width', '100%')
|
|
3300
3408
|
.style('height', '100%')
|
|
3301
3409
|
.append('svg')
|
|
3302
|
-
.style('position', 'absolute')
|
|
3303
3410
|
.style('width', '100%')
|
|
3304
3411
|
.style('height', '100%');
|
|
3305
3412
|
d3.select(this.diagramRoot)
|
|
@@ -3456,13 +3563,13 @@ class DiagramCanvas {
|
|
|
3456
3563
|
// if there are no nodes, we have nothing to do here
|
|
3457
3564
|
if (this.model.nodes.length > 0) {
|
|
3458
3565
|
const canvasViewBoundingBox = this.selectCanvasView().select('rect').node().getBBox();
|
|
3459
|
-
const minimumX = Math.min(...this.model.nodes.map((n) => n.coords[0]));
|
|
3460
|
-
const maximumX = Math.max(...this.model.nodes.map((n) => n.coords[0] + n.width));
|
|
3566
|
+
const minimumX = Math.min(...this.model.nodes.all().map((n) => n.coords[0]));
|
|
3567
|
+
const maximumX = Math.max(...this.model.nodes.all().map((n) => n.coords[0] + n.width));
|
|
3461
3568
|
const averageX = (minimumX + maximumX) / 2;
|
|
3462
3569
|
const rangeX = maximumX - minimumX;
|
|
3463
3570
|
const windowRangeX = canvasViewBoundingBox.width;
|
|
3464
|
-
const minimumY = Math.min(...this.model.nodes.map((n) => n.coords[1]));
|
|
3465
|
-
const maximumY = Math.max(...this.model.nodes.map((n) => n.coords[1] + n.height));
|
|
3571
|
+
const minimumY = Math.min(...this.model.nodes.all().map((n) => n.coords[1]));
|
|
3572
|
+
const maximumY = Math.max(...this.model.nodes.all().map((n) => n.coords[1] + n.height));
|
|
3466
3573
|
const averageY = (minimumY + maximumY) / 2;
|
|
3467
3574
|
const rangeY = maximumY - minimumY;
|
|
3468
3575
|
const windowRangeY = canvasViewBoundingBox.height;
|
|
@@ -3524,7 +3631,7 @@ class DiagramCanvas {
|
|
|
3524
3631
|
updateNodesInView(...ids) {
|
|
3525
3632
|
let updateSelection = this.selectCanvas()
|
|
3526
3633
|
.selectAll('g.diagram-node')
|
|
3527
|
-
.data(this.model.
|
|
3634
|
+
.data(this.model.nodes.filter(undefined, this.priorityThreshold), (d) => d.id);
|
|
3528
3635
|
const exitSelection = updateSelection.exit();
|
|
3529
3636
|
const enterSelection = updateSelection
|
|
3530
3637
|
.enter()
|
|
@@ -3643,7 +3750,7 @@ class DiagramCanvas {
|
|
|
3643
3750
|
.append('line')
|
|
3644
3751
|
.attr('class', 'left-resizer')
|
|
3645
3752
|
.attr('stroke', 'transparent')
|
|
3646
|
-
.attr('stroke-width',
|
|
3753
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
3647
3754
|
.on(Events.MouseOver, (event, d) => {
|
|
3648
3755
|
if (d.type.resizableX) {
|
|
3649
3756
|
d3.select('body').style('cursor', 'ew-resize');
|
|
@@ -3686,7 +3793,7 @@ class DiagramCanvas {
|
|
|
3686
3793
|
.append('line')
|
|
3687
3794
|
.attr('class', 'top-resizer')
|
|
3688
3795
|
.attr('stroke', 'transparent')
|
|
3689
|
-
.attr('stroke-width',
|
|
3796
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
3690
3797
|
.on(Events.MouseOver, (event, d) => {
|
|
3691
3798
|
if (d.type.resizableY) {
|
|
3692
3799
|
d3.select('body').style('cursor', 'ns-resize');
|
|
@@ -3729,7 +3836,7 @@ class DiagramCanvas {
|
|
|
3729
3836
|
.append('line')
|
|
3730
3837
|
.attr('class', 'right-resizer')
|
|
3731
3838
|
.attr('stroke', 'transparent')
|
|
3732
|
-
.attr('stroke-width',
|
|
3839
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
3733
3840
|
.on(Events.MouseOver, (event, d) => {
|
|
3734
3841
|
if (d.type.resizableX) {
|
|
3735
3842
|
d3.select('body').style('cursor', 'ew-resize');
|
|
@@ -3772,7 +3879,7 @@ class DiagramCanvas {
|
|
|
3772
3879
|
.append('line')
|
|
3773
3880
|
.attr('class', 'bottom-resizer')
|
|
3774
3881
|
.attr('stroke', 'transparent')
|
|
3775
|
-
.attr('stroke-width',
|
|
3882
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
3776
3883
|
.on(Events.MouseOver, (event, d) => {
|
|
3777
3884
|
if (d.type.resizableY) {
|
|
3778
3885
|
d3.select('body').style('cursor', 'ns-resize');
|
|
@@ -3945,8 +4052,8 @@ class DiagramCanvas {
|
|
|
3945
4052
|
mergeSelection
|
|
3946
4053
|
.filter('.resizable-x')
|
|
3947
4054
|
.select('line.left-resizer')
|
|
3948
|
-
.attr('x1',
|
|
3949
|
-
.attr('x2',
|
|
4055
|
+
.attr('x1', RESIZER_THICKNESS / 2)
|
|
4056
|
+
.attr('x2', RESIZER_THICKNESS / 2)
|
|
3950
4057
|
.attr('y1', 0)
|
|
3951
4058
|
.attr('y2', (d) => d.height);
|
|
3952
4059
|
mergeSelection
|
|
@@ -3954,13 +4061,13 @@ class DiagramCanvas {
|
|
|
3954
4061
|
.select('line.top-resizer')
|
|
3955
4062
|
.attr('x1', 0)
|
|
3956
4063
|
.attr('x2', (d) => d.width)
|
|
3957
|
-
.attr('y1',
|
|
3958
|
-
.attr('y2',
|
|
4064
|
+
.attr('y1', RESIZER_THICKNESS / 2)
|
|
4065
|
+
.attr('y2', RESIZER_THICKNESS / 2);
|
|
3959
4066
|
mergeSelection
|
|
3960
4067
|
.filter('.resizable-x')
|
|
3961
4068
|
.select('line.right-resizer')
|
|
3962
|
-
.attr('x1', (d) => d.width)
|
|
3963
|
-
.attr('x2', (d) => d.width)
|
|
4069
|
+
.attr('x1', (d) => d.width - RESIZER_THICKNESS / 2)
|
|
4070
|
+
.attr('x2', (d) => d.width - RESIZER_THICKNESS / 2)
|
|
3964
4071
|
.attr('y1', 0)
|
|
3965
4072
|
.attr('y2', (d) => d.height);
|
|
3966
4073
|
mergeSelection
|
|
@@ -3968,13 +4075,13 @@ class DiagramCanvas {
|
|
|
3968
4075
|
.select('line.bottom-resizer')
|
|
3969
4076
|
.attr('x1', 0)
|
|
3970
4077
|
.attr('x2', (d) => d.width)
|
|
3971
|
-
.attr('y1', (d) => d.height)
|
|
3972
|
-
.attr('y2', (d) => d.height);
|
|
4078
|
+
.attr('y1', (d) => d.height - RESIZER_THICKNESS / 2)
|
|
4079
|
+
.attr('y2', (d) => d.height - RESIZER_THICKNESS / 2);
|
|
3973
4080
|
}
|
|
3974
4081
|
updateSectionsInView(...ids) {
|
|
3975
4082
|
let updateSelection = this.selectCanvas()
|
|
3976
4083
|
.selectAll('g.diagram-section')
|
|
3977
|
-
.data(this.model.
|
|
4084
|
+
.data(this.model.sections.filter(this.priorityThreshold), (d) => d.id);
|
|
3978
4085
|
const exitSelection = updateSelection.exit();
|
|
3979
4086
|
const enterSelection = updateSelection
|
|
3980
4087
|
.enter()
|
|
@@ -4096,7 +4203,7 @@ class DiagramCanvas {
|
|
|
4096
4203
|
.append('line')
|
|
4097
4204
|
.attr('class', 'left-resizer')
|
|
4098
4205
|
.attr('stroke', 'transparent')
|
|
4099
|
-
.attr('stroke-width',
|
|
4206
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
4100
4207
|
.on(Events.MouseOver, (event, d) => {
|
|
4101
4208
|
if (d.node?.type?.resizableX) {
|
|
4102
4209
|
d3.select('body').style('cursor', 'ew-resize');
|
|
@@ -4139,7 +4246,7 @@ class DiagramCanvas {
|
|
|
4139
4246
|
.append('line')
|
|
4140
4247
|
.attr('class', 'top-resizer')
|
|
4141
4248
|
.attr('stroke', 'transparent')
|
|
4142
|
-
.attr('stroke-width',
|
|
4249
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
4143
4250
|
.on(Events.MouseOver, (event, d) => {
|
|
4144
4251
|
if (d.node?.type?.resizableY) {
|
|
4145
4252
|
d3.select('body').style('cursor', 'ns-resize');
|
|
@@ -4182,7 +4289,7 @@ class DiagramCanvas {
|
|
|
4182
4289
|
.append('line')
|
|
4183
4290
|
.attr('class', 'right-resizer')
|
|
4184
4291
|
.attr('stroke', 'transparent')
|
|
4185
|
-
.attr('stroke-width',
|
|
4292
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
4186
4293
|
.on(Events.MouseOver, (event, d) => {
|
|
4187
4294
|
if (d.node?.type?.resizableX) {
|
|
4188
4295
|
d3.select('body').style('cursor', 'ew-resize');
|
|
@@ -4225,7 +4332,7 @@ class DiagramCanvas {
|
|
|
4225
4332
|
.append('line')
|
|
4226
4333
|
.attr('class', 'bottom-resizer')
|
|
4227
4334
|
.attr('stroke', 'transparent')
|
|
4228
|
-
.attr('stroke-width',
|
|
4335
|
+
.attr('stroke-width', `${RESIZER_THICKNESS}px`)
|
|
4229
4336
|
.on(Events.MouseOver, (event, d) => {
|
|
4230
4337
|
if (d.node?.type?.resizableY) {
|
|
4231
4338
|
d3.select('body').style('cursor', 'ns-resize');
|
|
@@ -4427,8 +4534,8 @@ class DiagramCanvas {
|
|
|
4427
4534
|
mergeSelection
|
|
4428
4535
|
.filter('.resizable-x')
|
|
4429
4536
|
.select('line.left-resizer')
|
|
4430
|
-
.attr('x1',
|
|
4431
|
-
.attr('x2',
|
|
4537
|
+
.attr('x1', RESIZER_THICKNESS / 2)
|
|
4538
|
+
.attr('x2', RESIZER_THICKNESS / 2)
|
|
4432
4539
|
.attr('y1', 0)
|
|
4433
4540
|
.attr('y2', (d) => d.height);
|
|
4434
4541
|
mergeSelection
|
|
@@ -4436,13 +4543,13 @@ class DiagramCanvas {
|
|
|
4436
4543
|
.select('line.top-resizer')
|
|
4437
4544
|
.attr('x1', 0)
|
|
4438
4545
|
.attr('x2', (d) => d.width)
|
|
4439
|
-
.attr('y1',
|
|
4440
|
-
.attr('y2',
|
|
4546
|
+
.attr('y1', RESIZER_THICKNESS / 2)
|
|
4547
|
+
.attr('y2', RESIZER_THICKNESS / 2);
|
|
4441
4548
|
mergeSelection
|
|
4442
4549
|
.filter('.resizable-x')
|
|
4443
4550
|
.select('line.right-resizer')
|
|
4444
|
-
.attr('x1', (d) => d.width)
|
|
4445
|
-
.attr('x2', (d) => d.width)
|
|
4551
|
+
.attr('x1', (d) => d.width - RESIZER_THICKNESS / 2)
|
|
4552
|
+
.attr('x2', (d) => d.width - RESIZER_THICKNESS / 2)
|
|
4446
4553
|
.attr('y1', 0)
|
|
4447
4554
|
.attr('y2', (d) => d.height);
|
|
4448
4555
|
mergeSelection
|
|
@@ -4450,13 +4557,13 @@ class DiagramCanvas {
|
|
|
4450
4557
|
.select('line.bottom-resizer')
|
|
4451
4558
|
.attr('x1', 0)
|
|
4452
4559
|
.attr('x2', (d) => d.width)
|
|
4453
|
-
.attr('y1', (d) => d.height)
|
|
4454
|
-
.attr('y2', (d) => d.height);
|
|
4560
|
+
.attr('y1', (d) => d.height - RESIZER_THICKNESS / 2)
|
|
4561
|
+
.attr('y2', (d) => d.height - RESIZER_THICKNESS / 2);
|
|
4455
4562
|
}
|
|
4456
4563
|
updatePortsInView(...ids) {
|
|
4457
4564
|
let updateSelection = this.selectCanvas()
|
|
4458
4565
|
.selectAll('g.diagram-port')
|
|
4459
|
-
.data(this.model.
|
|
4566
|
+
.data(this.model.ports.filter(this.priorityThreshold), (d) => d.id);
|
|
4460
4567
|
const exitSelection = updateSelection.exit();
|
|
4461
4568
|
const enterSelection = updateSelection
|
|
4462
4569
|
.enter()
|
|
@@ -4547,7 +4654,7 @@ class DiagramCanvas {
|
|
|
4547
4654
|
}
|
|
4548
4655
|
updateConnectionsInView(...ids) {
|
|
4549
4656
|
const connectionList = [
|
|
4550
|
-
...this.model.
|
|
4657
|
+
...this.model.connections.filter(undefined, this.priorityThreshold)
|
|
4551
4658
|
];
|
|
4552
4659
|
if (this.unfinishedConnection) {
|
|
4553
4660
|
connectionList.push(this.unfinishedConnection);
|
|
@@ -4643,7 +4750,7 @@ class DiagramCanvas {
|
|
|
4643
4750
|
updateFieldsInView(...ids) {
|
|
4644
4751
|
let updateSelection = this.selectCanvas()
|
|
4645
4752
|
.selectAll('foreignObject.diagram-field')
|
|
4646
|
-
.data(this.model.
|
|
4753
|
+
.data(this.model.fields.filter(this.priorityThreshold), (d) => d.id);
|
|
4647
4754
|
const exitSelection = updateSelection.exit();
|
|
4648
4755
|
const enterSelection = updateSelection
|
|
4649
4756
|
.enter()
|
|
@@ -4979,9 +5086,13 @@ class DiagramCanvas {
|
|
|
4979
5086
|
}
|
|
4980
5087
|
else {
|
|
4981
5088
|
if (this.guessConnectionType) {
|
|
4982
|
-
let differentConnectionType = this.model.
|
|
5089
|
+
let differentConnectionType = this.model.connections.types
|
|
5090
|
+
.all()
|
|
5091
|
+
.find((t) => t.canStartFromType(port.getNode()?.type?.id || ''));
|
|
4983
5092
|
if (differentConnectionType === undefined) {
|
|
4984
|
-
differentConnectionType = this.model.
|
|
5093
|
+
differentConnectionType = this.model.connections.types
|
|
5094
|
+
.all()
|
|
5095
|
+
.find((t) => t.canFinishOnType(port.getNode()?.type?.id || ''));
|
|
4985
5096
|
}
|
|
4986
5097
|
if (differentConnectionType !== undefined) {
|
|
4987
5098
|
this.unfinishedConnection = new DiagramConnection(this.model, differentConnectionType, port, undefined, 'diagram-connection-unfinished');
|
|
@@ -5018,10 +5129,15 @@ class DiagramCanvas {
|
|
|
5018
5129
|
}
|
|
5019
5130
|
else {
|
|
5020
5131
|
if (this.guessConnectionType) {
|
|
5021
|
-
let differentConnectionType = this.model.
|
|
5132
|
+
let differentConnectionType = this.model.connections.types
|
|
5133
|
+
.all()
|
|
5134
|
+
.find((t) => t.canStartFromType(this.unfinishedConnection?.start?.getNode()?.type?.id || '') && t.canFinishOnType(port.getNode()?.type?.id || ''));
|
|
5022
5135
|
let invertConnection = false;
|
|
5023
5136
|
if (differentConnectionType === undefined) {
|
|
5024
|
-
differentConnectionType = this.model.
|
|
5137
|
+
differentConnectionType = this.model.connections.types
|
|
5138
|
+
.all()
|
|
5139
|
+
.find((t) => t.canFinishOnType(this.unfinishedConnection?.start?.getNode()?.type?.id ||
|
|
5140
|
+
'') && t.canStartFromType(port.getNode()?.type?.id || ''));
|
|
5025
5141
|
invertConnection = true;
|
|
5026
5142
|
}
|
|
5027
5143
|
if (differentConnectionType !== undefined) {
|
|
@@ -5415,7 +5531,8 @@ class ErrorsComponent {
|
|
|
5415
5531
|
}
|
|
5416
5532
|
showError(error) {
|
|
5417
5533
|
if (error.elementId && error.propertyNames) {
|
|
5418
|
-
this.canvas.setPropertyEditorSelection(this.canvas.model.
|
|
5534
|
+
this.canvas.setPropertyEditorSelection(this.canvas.model.nodes.get(error.elementId) ||
|
|
5535
|
+
this.canvas.model.connections.get(error.elementId));
|
|
5419
5536
|
this.canvas.parentComponent.propertyEditor?.highlightProperty(...error.propertyNames);
|
|
5420
5537
|
}
|
|
5421
5538
|
else if (!error.elementId && error.propertyNames) {
|
|
@@ -5510,7 +5627,7 @@ class PaletteComponent {
|
|
|
5510
5627
|
}
|
|
5511
5628
|
appendTemplate(template, classes) {
|
|
5512
5629
|
if (template.templateType === 'node') {
|
|
5513
|
-
const nodeType = this.canvas.model.
|
|
5630
|
+
const nodeType = this.canvas.model.nodes.types.get(template.type);
|
|
5514
5631
|
if (nodeType) {
|
|
5515
5632
|
this.appendNodeTemplate(nodeType, template, classes);
|
|
5516
5633
|
}
|
|
@@ -5520,7 +5637,7 @@ class PaletteComponent {
|
|
|
5520
5637
|
}
|
|
5521
5638
|
else if (template.templateType === 'connection') {
|
|
5522
5639
|
{
|
|
5523
|
-
const connectionType = this.canvas.model.
|
|
5640
|
+
const connectionType = this.canvas.model.connections.types.get(template.type);
|
|
5524
5641
|
if (connectionType) {
|
|
5525
5642
|
this.appendConnectionTemplate(connectionType, template, classes);
|
|
5526
5643
|
}
|
|
@@ -5578,7 +5695,8 @@ class PaletteComponent {
|
|
|
5578
5695
|
.style('top', 0)
|
|
5579
5696
|
.style('z-index', 'auto');
|
|
5580
5697
|
// try to place node
|
|
5581
|
-
if (type.isUnique &&
|
|
5698
|
+
if (type.isUnique &&
|
|
5699
|
+
this.canvas.model.nodes.find(type.id) !== undefined) {
|
|
5582
5700
|
// can't place, it's unique and that node is already in the model
|
|
5583
5701
|
return;
|
|
5584
5702
|
}
|
|
@@ -6163,11 +6281,11 @@ class DiagramComponent {
|
|
|
6163
6281
|
this.configurationService.init(this.config);
|
|
6164
6282
|
}
|
|
6165
6283
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6166
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DiagramComponent, isStandalone: true, selector: "daga-diagram", inputs: { config: "config" }, providers: [CanvasProviderService, DagaConfigurationService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{position:
|
|
6284
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DiagramComponent, isStandalone: true, selector: "daga-diagram", inputs: { config: "config" }, providers: [CanvasProviderService, DagaConfigurationService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{position:relative;display:block;min-width:40rem;min-height:20rem;width:100%;height:100%}\n"] }); }
|
|
6167
6285
|
}
|
|
6168
6286
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramComponent, decorators: [{
|
|
6169
6287
|
type: Component,
|
|
6170
|
-
args: [{ standalone: true, selector: 'daga-diagram', template: `<ng-content></ng-content>`, providers: [CanvasProviderService, DagaConfigurationService], styles: [":host{position:
|
|
6288
|
+
args: [{ standalone: true, selector: 'daga-diagram', template: `<ng-content></ng-content>`, providers: [CanvasProviderService, DagaConfigurationService], styles: [":host{position:relative;display:block;min-width:40rem;min-height:20rem;width:100%;height:100%}\n"] }]
|
|
6171
6289
|
}], ctorParameters: () => [{ type: DagaConfigurationService }, { type: CanvasProviderService }], propDecorators: { config: [{
|
|
6172
6290
|
type: Input
|
|
6173
6291
|
}] } });
|
|
@@ -6315,10 +6433,10 @@ class DagaImporter {
|
|
|
6315
6433
|
model.createdAt = new Date(data.createdAt);
|
|
6316
6434
|
model.updatedAt = new Date(data.updatedAt);
|
|
6317
6435
|
for (const node of data.nodes || []) {
|
|
6318
|
-
const newNodeType = model.
|
|
6436
|
+
const newNodeType = model.nodes.types.get(node.type);
|
|
6319
6437
|
if (newNodeType) {
|
|
6320
6438
|
const newNode = new DiagramNode(model, newNodeType, node.coords, node.id);
|
|
6321
|
-
model.nodes.
|
|
6439
|
+
model.nodes.add(newNode);
|
|
6322
6440
|
newNode.width = node.width;
|
|
6323
6441
|
newNode.height = node.height;
|
|
6324
6442
|
if (node.data) {
|
|
@@ -6337,13 +6455,13 @@ class DagaImporter {
|
|
|
6337
6455
|
], newNode.width - labelConfiguration.margin * 2, newNode.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
|
|
6338
6456
|
newField.text = node.label;
|
|
6339
6457
|
newNode.label = newField;
|
|
6340
|
-
model.fields.
|
|
6458
|
+
model.fields.add(newField);
|
|
6341
6459
|
}
|
|
6342
6460
|
}
|
|
6343
6461
|
for (const section of node.sections || []) {
|
|
6344
6462
|
const newSection = new DiagramSection(model, newNode, section.coords, section.width, section.height, section.id);
|
|
6345
6463
|
newNode.sections?.push(newSection);
|
|
6346
|
-
model.sections.
|
|
6464
|
+
model.sections.add(newSection);
|
|
6347
6465
|
if (section.label) {
|
|
6348
6466
|
// add section label
|
|
6349
6467
|
if (newNodeType.sections?.label) {
|
|
@@ -6357,14 +6475,14 @@ class DagaImporter {
|
|
|
6357
6475
|
], newSection.width - labelConfiguration.margin * 2, newSection.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
|
|
6358
6476
|
newField.text = section.label;
|
|
6359
6477
|
newSection.label = newField;
|
|
6360
|
-
model.fields.
|
|
6478
|
+
model.fields.add(newField);
|
|
6361
6479
|
}
|
|
6362
6480
|
}
|
|
6363
6481
|
let portCounter = 0;
|
|
6364
6482
|
for (const port of section.ports || []) {
|
|
6365
6483
|
const newPort = new DiagramPort(model, newSection, port.coords, port.direction, port.id);
|
|
6366
6484
|
newSection.ports.push(newPort);
|
|
6367
|
-
model.ports.
|
|
6485
|
+
model.ports.add(newPort);
|
|
6368
6486
|
if (port.label) {
|
|
6369
6487
|
// add port label
|
|
6370
6488
|
if (newNodeType.ports.length > portCounter &&
|
|
@@ -6400,7 +6518,7 @@ class DagaImporter {
|
|
|
6400
6518
|
const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
|
|
6401
6519
|
newField.text = port.label;
|
|
6402
6520
|
newPort.label = newField;
|
|
6403
|
-
model.fields.
|
|
6521
|
+
model.fields.add(newField);
|
|
6404
6522
|
}
|
|
6405
6523
|
++portCounter;
|
|
6406
6524
|
}
|
|
@@ -6410,7 +6528,7 @@ class DagaImporter {
|
|
|
6410
6528
|
for (const port of node.ports || []) {
|
|
6411
6529
|
const newPort = new DiagramPort(model, newNode, port.coords, port.direction, port.id);
|
|
6412
6530
|
newNode.ports.push(newPort);
|
|
6413
|
-
model.ports.
|
|
6531
|
+
model.ports.add(newPort);
|
|
6414
6532
|
if (port.label) {
|
|
6415
6533
|
// add port label
|
|
6416
6534
|
if (newNodeType.ports.length > portCounter &&
|
|
@@ -6446,7 +6564,7 @@ class DagaImporter {
|
|
|
6446
6564
|
const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
|
|
6447
6565
|
newField.text = port.label;
|
|
6448
6566
|
newPort.label = newField;
|
|
6449
|
-
model.fields.
|
|
6567
|
+
model.fields.add(newField);
|
|
6450
6568
|
}
|
|
6451
6569
|
++portCounter;
|
|
6452
6570
|
}
|
|
@@ -6454,10 +6572,10 @@ class DagaImporter {
|
|
|
6454
6572
|
}
|
|
6455
6573
|
}
|
|
6456
6574
|
for (const connection of data.connections || []) {
|
|
6457
|
-
const newConnectionType = model.
|
|
6575
|
+
const newConnectionType = model.connections.types.get(connection.type);
|
|
6458
6576
|
if (newConnectionType) {
|
|
6459
|
-
const newConnection = new DiagramConnection(model, newConnectionType, connection.start ? model.
|
|
6460
|
-
model.connections.
|
|
6577
|
+
const newConnection = new DiagramConnection(model, newConnectionType, connection.start ? model.ports.get(connection.start) : undefined, connection.end ? model.ports.get(connection.end) : undefined, connection.id);
|
|
6578
|
+
model.connections.add(newConnection);
|
|
6461
6579
|
newConnection.startLabel = connection.startLabel;
|
|
6462
6580
|
newConnection.middleLabel = connection.middleLabel;
|
|
6463
6581
|
newConnection.endLabel = connection.endLabel;
|