@metadev/daga 4.0.2 → 4.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 +14 -0
- package/index.cjs.js +227 -23
- package/index.esm.js +227 -23
- package/package.json +1 -1
- package/src/lib/diagram/canvas/diagram-canvas.d.ts +2 -1
- package/src/lib/diagram/collab/collab-action.d.ts +31 -1
- package/src/lib/diagram/config/diagram-config.d.ts +1 -1
- package/src/lib/diagram/diagram-action.d.ts +23 -0
- package/src/lib/diagram/layout/adjacency-layout.d.ts +2 -0
- package/src/lib/diagram/layout/breadth-adjacency-layout.d.ts +2 -0
- package/src/lib/diagram/layout/breadth-layout.d.ts +2 -0
- package/src/lib/diagram/layout/force-layout.d.ts +2 -0
- package/src/lib/diagram/layout/horizontal-layout.d.ts +2 -0
- package/src/lib/diagram/layout/priority-layout.d.ts +2 -0
- package/src/lib/diagram/layout/tree-layout.d.ts +2 -0
- package/src/lib/diagram/layout/vertical-layout.d.ts +2 -0
- package/src/lib/diagram/model/diagram-node.d.ts +20 -0
- package/src/lib/interfaces/canvas.d.ts +8 -1
package/Changelog.md
CHANGED
|
@@ -6,6 +6,20 @@ List of releases and changes.
|
|
|
6
6
|
|
|
7
7
|
## Next release Joyeuse
|
|
8
8
|
|
|
9
|
+
## v. 4.1.0
|
|
10
|
+
|
|
11
|
+
- Add methods for adding and removing rows and columns of sections in a node.
|
|
12
|
+
- Allow toggling gapSize in layout algorithms [#279](https://github.com/metadevpro/daga/pull/279)
|
|
13
|
+
- Raise ports after raising sections inside nodes so that sections don't hide ports [#280](https://github.com/metadevpro/daga/pull/280)
|
|
14
|
+
- Add `fieldRootFitsInView()` method to canvas [#281](https://github.com/metadevpro/daga/pull/281)
|
|
15
|
+
- Add `shrink` parameter to canvas method `fitFieldRootInView()` to toggle whether nodes and sections should be shrunk as part of the fitting process [#282](https://github.com/metadevpro/daga/pull/282)
|
|
16
|
+
- Set root vlaue of property to default value when resetting values [#284](https://github.com/metadevpro/daga/pull/284)
|
|
17
|
+
|
|
18
|
+
## v. 4.0.3
|
|
19
|
+
|
|
20
|
+
- Allow angular 20.
|
|
21
|
+
- Fix bug with connections breaking when they have an id which is not a valid CSS selector [#277](https://github.com/metadevpro/daga/pull/277)
|
|
22
|
+
|
|
9
23
|
## v. 4.0.2
|
|
10
24
|
|
|
11
25
|
- Add grid style [#261](https://github.com/metadevpro/daga/pull/261)
|
package/index.cjs.js
CHANGED
|
@@ -1691,10 +1691,8 @@ class ValueSet {
|
|
|
1691
1691
|
this.values[key] = structuredClone(property.defaultValue);
|
|
1692
1692
|
}
|
|
1693
1693
|
if (rootAttribute !== undefined && rootAttribute !== null) {
|
|
1694
|
-
if (property.defaultValue !== undefined && !equals(this.
|
|
1694
|
+
if (property.defaultValue !== undefined && !equals(this.getRootElementValue(rootAttribute), property.defaultValue)) {
|
|
1695
1695
|
this.setRootElementValue(rootAttribute, this.values[key]);
|
|
1696
|
-
} else {
|
|
1697
|
-
this.values[key] = this.getRootElementValue(rootAttribute);
|
|
1698
1696
|
}
|
|
1699
1697
|
}
|
|
1700
1698
|
if (property.basic) {
|
|
@@ -3160,15 +3158,15 @@ class DiagramNode extends DiagramElement {
|
|
|
3160
3158
|
raise() {
|
|
3161
3159
|
var _a;
|
|
3162
3160
|
(_a = this.select()) === null || _a === undefined ? undefined : _a.raise();
|
|
3161
|
+
for (const section of this.sections) {
|
|
3162
|
+
section.raise();
|
|
3163
|
+
}
|
|
3163
3164
|
if (this.label) {
|
|
3164
3165
|
this.label.raise();
|
|
3165
3166
|
}
|
|
3166
3167
|
for (const port of this.ports) {
|
|
3167
3168
|
port.raise();
|
|
3168
3169
|
}
|
|
3169
|
-
for (const section of this.sections) {
|
|
3170
|
-
section.raise();
|
|
3171
|
-
}
|
|
3172
3170
|
for (const decorator of this.decorators) {
|
|
3173
3171
|
decorator.raise();
|
|
3174
3172
|
}
|
|
@@ -3602,6 +3600,106 @@ class DiagramNode extends DiagramElement {
|
|
|
3602
3600
|
this.getConnections().forEach(c => c.tighten());
|
|
3603
3601
|
this.updateInView();
|
|
3604
3602
|
}
|
|
3603
|
+
/**
|
|
3604
|
+
* Removes all sections with the given index along the x axis.
|
|
3605
|
+
* @public
|
|
3606
|
+
*/
|
|
3607
|
+
removeSectionColumn(columnIndex) {
|
|
3608
|
+
var _a;
|
|
3609
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3610
|
+
let columnWidth = 0;
|
|
3611
|
+
const sections = [...this.sections];
|
|
3612
|
+
for (const section of sections) {
|
|
3613
|
+
if (section.indexYInNode === columnIndex) {
|
|
3614
|
+
columnWidth = Math.max(columnWidth, section.width);
|
|
3615
|
+
this.model.sections.remove(section.id);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
for (const section of sections) {
|
|
3619
|
+
if (section.indexYInNode > columnIndex) {
|
|
3620
|
+
--section.indexYInNode;
|
|
3621
|
+
section.move([section.coords[0] - columnWidth - margin, section.coords[1]]);
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
this.stretch(exports.Side.Right, -margin - columnWidth);
|
|
3625
|
+
}
|
|
3626
|
+
/**
|
|
3627
|
+
* Removes all sections with the given index along the y axis.
|
|
3628
|
+
* @public
|
|
3629
|
+
*/
|
|
3630
|
+
removeSectionRow(rowIndex) {
|
|
3631
|
+
var _a;
|
|
3632
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3633
|
+
let rowHeight = 0;
|
|
3634
|
+
const sections = [...this.sections];
|
|
3635
|
+
for (const section of sections) {
|
|
3636
|
+
if (section.indexXInNode === rowIndex) {
|
|
3637
|
+
rowHeight = Math.max(rowHeight, section.height);
|
|
3638
|
+
this.model.sections.remove(section.id);
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
for (const section of sections) {
|
|
3642
|
+
if (section.indexYInNode > rowIndex) {
|
|
3643
|
+
--section.indexXInNode;
|
|
3644
|
+
section.move([section.coords[0], section.coords[1] - rowHeight - margin]);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
this.stretch(exports.Side.Bottom, -margin - rowHeight);
|
|
3648
|
+
}
|
|
3649
|
+
/**
|
|
3650
|
+
* Creates a copy of all sections with the given index along the x axis.
|
|
3651
|
+
* @public
|
|
3652
|
+
*/
|
|
3653
|
+
copySectionColumn(columnIndex) {
|
|
3654
|
+
var _a;
|
|
3655
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3656
|
+
let columnWidth = 0;
|
|
3657
|
+
const sections = [...this.sections];
|
|
3658
|
+
for (const section of sections) {
|
|
3659
|
+
if (section.indexXInNode === columnIndex) {
|
|
3660
|
+
columnWidth = Math.max(columnWidth, section.width);
|
|
3661
|
+
let newSectionIdIndexX = section.indexXInNode + 1;
|
|
3662
|
+
while (this.model.sections.get(`${section.id}_copy_${newSectionIdIndexX}_${section.indexYInNode}`, true) !== undefined) {
|
|
3663
|
+
++newSectionIdIndexX;
|
|
3664
|
+
}
|
|
3665
|
+
this.model.sections.new(this, section.indexXInNode + 1, section.indexYInNode, [section.coords[0] + section.width + margin, section.coords[1]], section.width, section.height, `${section.id}_copy_${newSectionIdIndexX}_${section.indexYInNode}`);
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
for (const section of sections) {
|
|
3669
|
+
if (section.indexXInNode > columnIndex) {
|
|
3670
|
+
++section.indexXInNode;
|
|
3671
|
+
section.move([section.coords[0] + columnWidth + margin, section.coords[1]]);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
this.stretch(exports.Side.Right, margin + columnWidth);
|
|
3675
|
+
}
|
|
3676
|
+
/**
|
|
3677
|
+
* Creates a copy of all sections with the given index along the y axis.
|
|
3678
|
+
* @public
|
|
3679
|
+
*/
|
|
3680
|
+
copySectionRow(rowIndex) {
|
|
3681
|
+
var _a;
|
|
3682
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3683
|
+
let rowHeight = 0;
|
|
3684
|
+
const sections = [...this.sections];
|
|
3685
|
+
for (const section of sections) {
|
|
3686
|
+
if (section.indexYInNode === rowIndex) {
|
|
3687
|
+
rowHeight = Math.max(rowHeight, section.height);
|
|
3688
|
+
let newSectionIdIndexY = section.indexYInNode + 1;
|
|
3689
|
+
while (this.model.sections.get(`${section.id}_copy_${section.indexXInNode}_${newSectionIdIndexY}`, true) !== undefined) {
|
|
3690
|
+
++newSectionIdIndexY;
|
|
3691
|
+
}
|
|
3692
|
+
this.model.sections.new(this, section.indexXInNode, section.indexYInNode + 1, [section.coords[0], section.coords[1] + section.height + margin], section.width, section.height, `${section.id}_copy_${section.indexXInNode}_${newSectionIdIndexY}`);
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
for (const section of sections) {
|
|
3696
|
+
if (section.indexYInNode > rowIndex) {
|
|
3697
|
+
++section.indexYInNode;
|
|
3698
|
+
section.move([section.coords[0], section.coords[1] + rowHeight + margin]);
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
this.stretch(exports.Side.Bottom, margin + rowHeight);
|
|
3702
|
+
}
|
|
3605
3703
|
}
|
|
3606
3704
|
class DiagramNodeSet extends DiagramElementSet {
|
|
3607
3705
|
/**
|
|
@@ -4439,6 +4537,54 @@ class AddNodeCollabAction {
|
|
|
4439
4537
|
return new AddNodeCollabAction(canvas, serialized.id, serialized.typeId, serialized.coords, serialized.parentId, serialized.label, serialized.values);
|
|
4440
4538
|
}
|
|
4441
4539
|
}
|
|
4540
|
+
/**
|
|
4541
|
+
* Collaborative action which consists of adding or removing sections in a node.
|
|
4542
|
+
* @private
|
|
4543
|
+
* @see AddNodeAction
|
|
4544
|
+
*/
|
|
4545
|
+
class AddSectionCollabAction {
|
|
4546
|
+
constructor(canvas, nodeId, copyColumnIndex, copyRowIndex, removeColumnIndex, removeRowIndex, timestamp) {
|
|
4547
|
+
this.canvas = canvas;
|
|
4548
|
+
this.nodeId = nodeId;
|
|
4549
|
+
this.copyColumnIndex = copyColumnIndex;
|
|
4550
|
+
this.copyRowIndex = copyRowIndex;
|
|
4551
|
+
this.removeColumnIndex = removeColumnIndex;
|
|
4552
|
+
this.removeRowIndex = removeRowIndex;
|
|
4553
|
+
this.timestamp = timestamp;
|
|
4554
|
+
}
|
|
4555
|
+
do() {
|
|
4556
|
+
const node = this.canvas.model.nodes.get(this.nodeId);
|
|
4557
|
+
if (node && timestampWins(this.timestamp, node.geometryTimestamp)) {
|
|
4558
|
+
if (this.copyColumnIndex !== undefined) {
|
|
4559
|
+
node.copySectionColumn(this.copyColumnIndex);
|
|
4560
|
+
}
|
|
4561
|
+
if (this.copyRowIndex !== undefined) {
|
|
4562
|
+
node.copySectionRow(this.copyRowIndex);
|
|
4563
|
+
}
|
|
4564
|
+
if (this.removeColumnIndex !== undefined) {
|
|
4565
|
+
node.removeSectionColumn(this.removeColumnIndex);
|
|
4566
|
+
}
|
|
4567
|
+
if (this.removeRowIndex !== undefined) {
|
|
4568
|
+
node.removeSectionRow(this.removeRowIndex);
|
|
4569
|
+
}
|
|
4570
|
+
node.geometryTimestamp = this.timestamp;
|
|
4571
|
+
}
|
|
4572
|
+
}
|
|
4573
|
+
serialize() {
|
|
4574
|
+
return {
|
|
4575
|
+
type: 'addSection',
|
|
4576
|
+
nodeId: this.nodeId,
|
|
4577
|
+
copyColumnIndex: this.copyColumnIndex,
|
|
4578
|
+
copyRowIndex: this.copyRowIndex,
|
|
4579
|
+
removeColumnIndex: this.removeColumnIndex,
|
|
4580
|
+
removeRowIndex: this.removeRowIndex,
|
|
4581
|
+
timestamp: this.timestamp
|
|
4582
|
+
};
|
|
4583
|
+
}
|
|
4584
|
+
static deserialize(canvas, serialized) {
|
|
4585
|
+
return new AddSectionCollabAction(canvas, serialized.nodeId, serialized.copyColumnIndex, serialized.copyRowIndex, serialized.removeColumnIndex, serialized.removeRowIndex, serialized.timestamp);
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4442
4588
|
/**
|
|
4443
4589
|
* Collaborative which consists of applying a layout to the diagram which can change the location of several nodes.
|
|
4444
4590
|
* @private
|
|
@@ -4855,6 +5001,12 @@ class CollabEngine {
|
|
|
4855
5001
|
action.do();
|
|
4856
5002
|
break;
|
|
4857
5003
|
}
|
|
5004
|
+
case 'addSection':
|
|
5005
|
+
{
|
|
5006
|
+
const action = AddSectionCollabAction.deserialize(this.canvas, message);
|
|
5007
|
+
action.do();
|
|
5008
|
+
break;
|
|
5009
|
+
}
|
|
4858
5010
|
case 'applyLayout':
|
|
4859
5011
|
{
|
|
4860
5012
|
const action = ApplyLayoutCollabAction.deserialize(this.canvas, message);
|
|
@@ -5017,6 +5169,12 @@ exports.DiagramActions = void 0;
|
|
|
5017
5169
|
* @see AddNodeAction
|
|
5018
5170
|
*/
|
|
5019
5171
|
DiagramActions["AddNode"] = "add-node";
|
|
5172
|
+
/**
|
|
5173
|
+
* Action that corresponds to the addition or removal of sections in a node.
|
|
5174
|
+
* @public
|
|
5175
|
+
* @see AddSectionAction
|
|
5176
|
+
*/
|
|
5177
|
+
DiagramActions["AddSectionAction"] = "add-section";
|
|
5020
5178
|
/**
|
|
5021
5179
|
* Action that corresponds to applying a layout which changes the location of several nodes.
|
|
5022
5180
|
* @public
|
|
@@ -7991,7 +8149,7 @@ class DiagramCanvas {
|
|
|
7991
8149
|
}
|
|
7992
8150
|
updateConnectionLabelsInView(connection) {
|
|
7993
8151
|
var _a, _b, _c;
|
|
7994
|
-
const connectionSelection = this.selectCanvasView().select(`
|
|
8152
|
+
const connectionSelection = this.selectCanvasView().select(`[id='${escapeSelector(connection.id)}']`);
|
|
7995
8153
|
const pathSelection = connectionSelection.select('path');
|
|
7996
8154
|
const pathNode = pathSelection.node();
|
|
7997
8155
|
const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), connection.type.label);
|
|
@@ -8033,7 +8191,7 @@ class DiagramCanvas {
|
|
|
8033
8191
|
}
|
|
8034
8192
|
}
|
|
8035
8193
|
updateConnectionMarkersInView(connection) {
|
|
8036
|
-
const connectionSelection = this.selectCanvasView().select(`
|
|
8194
|
+
const connectionSelection = this.selectCanvasView().select(`[id='${escapeSelector(connection.id)}']`);
|
|
8037
8195
|
const startMarkerSelection = connectionSelection.select('marker.diagram-connection-start-marker');
|
|
8038
8196
|
const endMarkerSelection = connectionSelection.select('marker.diagram-connection-end-marker');
|
|
8039
8197
|
if (connection.startMarkerLook !== null) {
|
|
@@ -8047,13 +8205,27 @@ class DiagramCanvas {
|
|
|
8047
8205
|
endMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', 0).attr('markerHeight', 0);
|
|
8048
8206
|
}
|
|
8049
8207
|
}
|
|
8050
|
-
|
|
8208
|
+
fieldRootFitsInView(id) {
|
|
8209
|
+
var _a, _b, _c, _d;
|
|
8210
|
+
const field = this.model.fields.get(id);
|
|
8211
|
+
if (!field) {
|
|
8212
|
+
return false;
|
|
8213
|
+
}
|
|
8214
|
+
if (field.rootElement instanceof DiagramNode || field.rootElement instanceof DiagramSection) {
|
|
8215
|
+
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8216
|
+
const stretchX = fieldDimensions[0] + getLeftMargin((_a = field.rootElement.type) === null || _a === undefined ? undefined : _a.label) + getRightMargin((_b = field.rootElement.type) === null || _b === undefined ? undefined : _b.label) - field.rootElement.width;
|
|
8217
|
+
const stretchY = fieldDimensions[1] + getTopMargin((_c = field.rootElement.type) === null || _c === undefined ? undefined : _c.label) + getBottomMargin((_d = field.rootElement.type) === null || _d === undefined ? undefined : _d.label) - field.rootElement.height;
|
|
8218
|
+
return stretchX <= 0 && stretchY <= 0;
|
|
8219
|
+
}
|
|
8220
|
+
return true;
|
|
8221
|
+
}
|
|
8222
|
+
fitFieldRootInView(id, shrink) {
|
|
8051
8223
|
var _a, _b, _c;
|
|
8052
8224
|
const field = this.model.fields.get(id);
|
|
8053
8225
|
if (!field) {
|
|
8054
8226
|
return;
|
|
8055
8227
|
}
|
|
8056
|
-
if (field.rootElement instanceof DiagramNode
|
|
8228
|
+
if (field.rootElement instanceof DiagramNode) {
|
|
8057
8229
|
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8058
8230
|
let stretchX = fieldDimensions[0] + getLeftMargin(field.rootElement.type.label) + getRightMargin(field.rootElement.type.label) - field.rootElement.width;
|
|
8059
8231
|
let stretchY = fieldDimensions[1] + getTopMargin(field.rootElement.type.label) + getBottomMargin(field.rootElement.type.label) - field.rootElement.height;
|
|
@@ -8068,10 +8240,14 @@ class DiagramCanvas {
|
|
|
8068
8240
|
if (field.rootElement.height + stretchY < field.rootElement.type.minHeight) {
|
|
8069
8241
|
stretchY = field.rootElement.type.minHeight - field.rootElement.height;
|
|
8070
8242
|
}
|
|
8071
|
-
|
|
8072
|
-
|
|
8243
|
+
if (shrink !== false || stretchX > 0) {
|
|
8244
|
+
field.rootElement.stretch(exports.Side.Right, stretchX);
|
|
8245
|
+
}
|
|
8246
|
+
if (shrink !== false || stretchY > 0) {
|
|
8247
|
+
field.rootElement.stretch(exports.Side.Bottom, stretchY);
|
|
8248
|
+
}
|
|
8073
8249
|
}
|
|
8074
|
-
if (field.rootElement instanceof DiagramSection
|
|
8250
|
+
if (field.rootElement instanceof DiagramSection) {
|
|
8075
8251
|
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8076
8252
|
let minimumFieldWidth = fieldDimensions[0];
|
|
8077
8253
|
let minimumFieldHeight = fieldDimensions[1];
|
|
@@ -8104,8 +8280,12 @@ class DiagramCanvas {
|
|
|
8104
8280
|
if (field.rootElement.height + stretchY < (field.rootElement.getMinHeight() || 0)) {
|
|
8105
8281
|
stretchY = (field.rootElement.getMinHeight() || 0) - field.rootElement.height;
|
|
8106
8282
|
}
|
|
8107
|
-
(
|
|
8108
|
-
|
|
8283
|
+
if (shrink !== false || stretchX > 0) {
|
|
8284
|
+
(_b = field.rootElement.node) === null || _b === undefined ? undefined : _b.stretchSections(exports.Side.Right, stretchX, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
|
|
8285
|
+
}
|
|
8286
|
+
if (shrink !== false || stretchY > 0) {
|
|
8287
|
+
(_c = field.rootElement.node) === null || _c === undefined ? undefined : _c.stretchSections(exports.Side.Bottom, stretchY, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
|
|
8288
|
+
}
|
|
8109
8289
|
}
|
|
8110
8290
|
}
|
|
8111
8291
|
fitNodeInView(id) {
|
|
@@ -8794,6 +8974,9 @@ class Grid {
|
|
|
8794
8974
|
* @public
|
|
8795
8975
|
*/
|
|
8796
8976
|
class AdjacencyLayout {
|
|
8977
|
+
constructor(gapSize) {
|
|
8978
|
+
this.gapSize = gapSize;
|
|
8979
|
+
}
|
|
8797
8980
|
apply(model) {
|
|
8798
8981
|
var _a;
|
|
8799
8982
|
if (model.nodes.length === 0) {
|
|
@@ -8809,7 +8992,7 @@ class AdjacencyLayout {
|
|
|
8809
8992
|
// place nodes according to arrangement
|
|
8810
8993
|
const maximumWidth = Math.max(...model.nodes.map(n => n.width));
|
|
8811
8994
|
const maximumHeight = Math.max(...model.nodes.map(n => n.height));
|
|
8812
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8995
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8813
8996
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
8814
8997
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
8815
8998
|
const node = nodeArrangement.get([x, y]);
|
|
@@ -8837,6 +9020,9 @@ const arrangeNode = (node, nodeArrangement, coords, nodesToBeArranged) => {
|
|
|
8837
9020
|
* @public
|
|
8838
9021
|
*/
|
|
8839
9022
|
class BreadthAdjacencyLayout {
|
|
9023
|
+
constructor(gapSize) {
|
|
9024
|
+
this.gapSize = gapSize;
|
|
9025
|
+
}
|
|
8840
9026
|
apply(model) {
|
|
8841
9027
|
var _a;
|
|
8842
9028
|
if (model.nodes.length === 0) {
|
|
@@ -8874,7 +9060,7 @@ class BreadthAdjacencyLayout {
|
|
|
8874
9060
|
// place nodes according to arrangement
|
|
8875
9061
|
const maximumWidth = Math.max(...model.nodes.map(n => n.width));
|
|
8876
9062
|
const maximumHeight = Math.max(...model.nodes.map(n => n.height));
|
|
8877
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9063
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8878
9064
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
8879
9065
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
8880
9066
|
const node = nodeArrangement.get([x, y]);
|
|
@@ -8892,13 +9078,16 @@ class BreadthAdjacencyLayout {
|
|
|
8892
9078
|
* @public
|
|
8893
9079
|
*/
|
|
8894
9080
|
class BreadthLayout {
|
|
9081
|
+
constructor(gapSize) {
|
|
9082
|
+
this.gapSize = gapSize;
|
|
9083
|
+
}
|
|
8895
9084
|
apply(model) {
|
|
8896
9085
|
var _a;
|
|
8897
9086
|
if (model.nodes.length === 0) {
|
|
8898
9087
|
// nothing to arrange...
|
|
8899
9088
|
return model;
|
|
8900
9089
|
}
|
|
8901
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9090
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8902
9091
|
let nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
8903
9092
|
// Arrange nodes by a breadth first search
|
|
8904
9093
|
const firstNode = nodesToBeArranged[0];
|
|
@@ -8954,6 +9143,9 @@ class BreadthLayout {
|
|
|
8954
9143
|
* @public
|
|
8955
9144
|
*/
|
|
8956
9145
|
class ForceLayout {
|
|
9146
|
+
constructor(gapSize) {
|
|
9147
|
+
this.gapSize = gapSize;
|
|
9148
|
+
}
|
|
8957
9149
|
apply(model) {
|
|
8958
9150
|
var _a;
|
|
8959
9151
|
if (model.nodes.length === 0) {
|
|
@@ -8962,7 +9154,7 @@ class ForceLayout {
|
|
|
8962
9154
|
}
|
|
8963
9155
|
// as a starting point, we apply a simple layout
|
|
8964
9156
|
new BreadthLayout().apply(model);
|
|
8965
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9157
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8966
9158
|
const coolingFactor = 0.99;
|
|
8967
9159
|
const minimumTemperature = 1;
|
|
8968
9160
|
const attractionFactor = 0.1;
|
|
@@ -9049,13 +9241,16 @@ class ForceLayout {
|
|
|
9049
9241
|
* @public
|
|
9050
9242
|
*/
|
|
9051
9243
|
class HorizontalLayout {
|
|
9244
|
+
constructor(gapSize) {
|
|
9245
|
+
this.gapSize = gapSize;
|
|
9246
|
+
}
|
|
9052
9247
|
apply(model) {
|
|
9053
9248
|
var _a;
|
|
9054
9249
|
if (model.nodes.length === 0) {
|
|
9055
9250
|
// nothing to arrange...
|
|
9056
9251
|
return model;
|
|
9057
9252
|
}
|
|
9058
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9253
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9059
9254
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9060
9255
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
9061
9256
|
let widthAccumulator = 0;
|
|
@@ -9072,6 +9267,9 @@ class HorizontalLayout {
|
|
|
9072
9267
|
* @public
|
|
9073
9268
|
*/
|
|
9074
9269
|
class PriorityLayout {
|
|
9270
|
+
constructor(gapSize) {
|
|
9271
|
+
this.gapSize = gapSize;
|
|
9272
|
+
}
|
|
9075
9273
|
apply(model) {
|
|
9076
9274
|
var _a;
|
|
9077
9275
|
if (model.nodes.length === 0) {
|
|
@@ -9085,7 +9283,7 @@ class PriorityLayout {
|
|
|
9085
9283
|
new BreadthLayout().apply(model);
|
|
9086
9284
|
return model;
|
|
9087
9285
|
}
|
|
9088
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9286
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9089
9287
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9090
9288
|
const nodeArrangement = [];
|
|
9091
9289
|
const nodesWithMaximumPriorityToBeArranged = model.nodes.filter(n => !n.parent).filter(n => n.getPriority() >= maximumPriority);
|
|
@@ -9179,6 +9377,9 @@ class PriorityLayout {
|
|
|
9179
9377
|
* @public
|
|
9180
9378
|
*/
|
|
9181
9379
|
class TreeLayout {
|
|
9380
|
+
constructor(gapSize) {
|
|
9381
|
+
this.gapSize = gapSize;
|
|
9382
|
+
}
|
|
9182
9383
|
apply(model) {
|
|
9183
9384
|
var _a;
|
|
9184
9385
|
if (model.nodes.length === 0) {
|
|
@@ -9192,7 +9393,7 @@ class TreeLayout {
|
|
|
9192
9393
|
new BreadthLayout().apply(model);
|
|
9193
9394
|
return model;
|
|
9194
9395
|
}
|
|
9195
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9396
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9196
9397
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent).sort((n1, n2) => n2.getPriority() - n1.getPriority());
|
|
9197
9398
|
const branches = [];
|
|
9198
9399
|
while (nodesToBeArranged.length > 0) {
|
|
@@ -9277,13 +9478,16 @@ class Branch {
|
|
|
9277
9478
|
* @public
|
|
9278
9479
|
*/
|
|
9279
9480
|
class VerticalLayout {
|
|
9481
|
+
constructor(gapSize) {
|
|
9482
|
+
this.gapSize = gapSize;
|
|
9483
|
+
}
|
|
9280
9484
|
apply(model) {
|
|
9281
9485
|
var _a;
|
|
9282
9486
|
if (model.nodes.length === 0) {
|
|
9283
9487
|
// nothing to arrange...
|
|
9284
9488
|
return model;
|
|
9285
9489
|
}
|
|
9286
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9490
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9287
9491
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9288
9492
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
9289
9493
|
let heightAccumulator = 0;
|
package/index.esm.js
CHANGED
|
@@ -1670,10 +1670,8 @@ class ValueSet {
|
|
|
1670
1670
|
this.values[key] = structuredClone(property.defaultValue);
|
|
1671
1671
|
}
|
|
1672
1672
|
if (rootAttribute !== undefined && rootAttribute !== null) {
|
|
1673
|
-
if (property.defaultValue !== undefined && !equals(this.
|
|
1673
|
+
if (property.defaultValue !== undefined && !equals(this.getRootElementValue(rootAttribute), property.defaultValue)) {
|
|
1674
1674
|
this.setRootElementValue(rootAttribute, this.values[key]);
|
|
1675
|
-
} else {
|
|
1676
|
-
this.values[key] = this.getRootElementValue(rootAttribute);
|
|
1677
1675
|
}
|
|
1678
1676
|
}
|
|
1679
1677
|
if (property.basic) {
|
|
@@ -3139,15 +3137,15 @@ class DiagramNode extends DiagramElement {
|
|
|
3139
3137
|
raise() {
|
|
3140
3138
|
var _a;
|
|
3141
3139
|
(_a = this.select()) === null || _a === undefined ? undefined : _a.raise();
|
|
3140
|
+
for (const section of this.sections) {
|
|
3141
|
+
section.raise();
|
|
3142
|
+
}
|
|
3142
3143
|
if (this.label) {
|
|
3143
3144
|
this.label.raise();
|
|
3144
3145
|
}
|
|
3145
3146
|
for (const port of this.ports) {
|
|
3146
3147
|
port.raise();
|
|
3147
3148
|
}
|
|
3148
|
-
for (const section of this.sections) {
|
|
3149
|
-
section.raise();
|
|
3150
|
-
}
|
|
3151
3149
|
for (const decorator of this.decorators) {
|
|
3152
3150
|
decorator.raise();
|
|
3153
3151
|
}
|
|
@@ -3581,6 +3579,106 @@ class DiagramNode extends DiagramElement {
|
|
|
3581
3579
|
this.getConnections().forEach(c => c.tighten());
|
|
3582
3580
|
this.updateInView();
|
|
3583
3581
|
}
|
|
3582
|
+
/**
|
|
3583
|
+
* Removes all sections with the given index along the x axis.
|
|
3584
|
+
* @public
|
|
3585
|
+
*/
|
|
3586
|
+
removeSectionColumn(columnIndex) {
|
|
3587
|
+
var _a;
|
|
3588
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3589
|
+
let columnWidth = 0;
|
|
3590
|
+
const sections = [...this.sections];
|
|
3591
|
+
for (const section of sections) {
|
|
3592
|
+
if (section.indexYInNode === columnIndex) {
|
|
3593
|
+
columnWidth = Math.max(columnWidth, section.width);
|
|
3594
|
+
this.model.sections.remove(section.id);
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
for (const section of sections) {
|
|
3598
|
+
if (section.indexYInNode > columnIndex) {
|
|
3599
|
+
--section.indexYInNode;
|
|
3600
|
+
section.move([section.coords[0] - columnWidth - margin, section.coords[1]]);
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
this.stretch(Side.Right, -margin - columnWidth);
|
|
3604
|
+
}
|
|
3605
|
+
/**
|
|
3606
|
+
* Removes all sections with the given index along the y axis.
|
|
3607
|
+
* @public
|
|
3608
|
+
*/
|
|
3609
|
+
removeSectionRow(rowIndex) {
|
|
3610
|
+
var _a;
|
|
3611
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3612
|
+
let rowHeight = 0;
|
|
3613
|
+
const sections = [...this.sections];
|
|
3614
|
+
for (const section of sections) {
|
|
3615
|
+
if (section.indexXInNode === rowIndex) {
|
|
3616
|
+
rowHeight = Math.max(rowHeight, section.height);
|
|
3617
|
+
this.model.sections.remove(section.id);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
for (const section of sections) {
|
|
3621
|
+
if (section.indexYInNode > rowIndex) {
|
|
3622
|
+
--section.indexXInNode;
|
|
3623
|
+
section.move([section.coords[0], section.coords[1] - rowHeight - margin]);
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
this.stretch(Side.Bottom, -margin - rowHeight);
|
|
3627
|
+
}
|
|
3628
|
+
/**
|
|
3629
|
+
* Creates a copy of all sections with the given index along the x axis.
|
|
3630
|
+
* @public
|
|
3631
|
+
*/
|
|
3632
|
+
copySectionColumn(columnIndex) {
|
|
3633
|
+
var _a;
|
|
3634
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3635
|
+
let columnWidth = 0;
|
|
3636
|
+
const sections = [...this.sections];
|
|
3637
|
+
for (const section of sections) {
|
|
3638
|
+
if (section.indexXInNode === columnIndex) {
|
|
3639
|
+
columnWidth = Math.max(columnWidth, section.width);
|
|
3640
|
+
let newSectionIdIndexX = section.indexXInNode + 1;
|
|
3641
|
+
while (this.model.sections.get(`${section.id}_copy_${newSectionIdIndexX}_${section.indexYInNode}`, true) !== undefined) {
|
|
3642
|
+
++newSectionIdIndexX;
|
|
3643
|
+
}
|
|
3644
|
+
this.model.sections.new(this, section.indexXInNode + 1, section.indexYInNode, [section.coords[0] + section.width + margin, section.coords[1]], section.width, section.height, `${section.id}_copy_${newSectionIdIndexX}_${section.indexYInNode}`);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
for (const section of sections) {
|
|
3648
|
+
if (section.indexXInNode > columnIndex) {
|
|
3649
|
+
++section.indexXInNode;
|
|
3650
|
+
section.move([section.coords[0] + columnWidth + margin, section.coords[1]]);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
this.stretch(Side.Right, margin + columnWidth);
|
|
3654
|
+
}
|
|
3655
|
+
/**
|
|
3656
|
+
* Creates a copy of all sections with the given index along the y axis.
|
|
3657
|
+
* @public
|
|
3658
|
+
*/
|
|
3659
|
+
copySectionRow(rowIndex) {
|
|
3660
|
+
var _a;
|
|
3661
|
+
const margin = ((_a = this.type.sectionGrid) === null || _a === undefined ? undefined : _a.margin) || 0;
|
|
3662
|
+
let rowHeight = 0;
|
|
3663
|
+
const sections = [...this.sections];
|
|
3664
|
+
for (const section of sections) {
|
|
3665
|
+
if (section.indexYInNode === rowIndex) {
|
|
3666
|
+
rowHeight = Math.max(rowHeight, section.height);
|
|
3667
|
+
let newSectionIdIndexY = section.indexYInNode + 1;
|
|
3668
|
+
while (this.model.sections.get(`${section.id}_copy_${section.indexXInNode}_${newSectionIdIndexY}`, true) !== undefined) {
|
|
3669
|
+
++newSectionIdIndexY;
|
|
3670
|
+
}
|
|
3671
|
+
this.model.sections.new(this, section.indexXInNode, section.indexYInNode + 1, [section.coords[0], section.coords[1] + section.height + margin], section.width, section.height, `${section.id}_copy_${section.indexXInNode}_${newSectionIdIndexY}`);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
for (const section of sections) {
|
|
3675
|
+
if (section.indexYInNode > rowIndex) {
|
|
3676
|
+
++section.indexYInNode;
|
|
3677
|
+
section.move([section.coords[0], section.coords[1] + rowHeight + margin]);
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
this.stretch(Side.Bottom, margin + rowHeight);
|
|
3681
|
+
}
|
|
3584
3682
|
}
|
|
3585
3683
|
class DiagramNodeSet extends DiagramElementSet {
|
|
3586
3684
|
/**
|
|
@@ -4418,6 +4516,54 @@ class AddNodeCollabAction {
|
|
|
4418
4516
|
return new AddNodeCollabAction(canvas, serialized.id, serialized.typeId, serialized.coords, serialized.parentId, serialized.label, serialized.values);
|
|
4419
4517
|
}
|
|
4420
4518
|
}
|
|
4519
|
+
/**
|
|
4520
|
+
* Collaborative action which consists of adding or removing sections in a node.
|
|
4521
|
+
* @private
|
|
4522
|
+
* @see AddNodeAction
|
|
4523
|
+
*/
|
|
4524
|
+
class AddSectionCollabAction {
|
|
4525
|
+
constructor(canvas, nodeId, copyColumnIndex, copyRowIndex, removeColumnIndex, removeRowIndex, timestamp) {
|
|
4526
|
+
this.canvas = canvas;
|
|
4527
|
+
this.nodeId = nodeId;
|
|
4528
|
+
this.copyColumnIndex = copyColumnIndex;
|
|
4529
|
+
this.copyRowIndex = copyRowIndex;
|
|
4530
|
+
this.removeColumnIndex = removeColumnIndex;
|
|
4531
|
+
this.removeRowIndex = removeRowIndex;
|
|
4532
|
+
this.timestamp = timestamp;
|
|
4533
|
+
}
|
|
4534
|
+
do() {
|
|
4535
|
+
const node = this.canvas.model.nodes.get(this.nodeId);
|
|
4536
|
+
if (node && timestampWins(this.timestamp, node.geometryTimestamp)) {
|
|
4537
|
+
if (this.copyColumnIndex !== undefined) {
|
|
4538
|
+
node.copySectionColumn(this.copyColumnIndex);
|
|
4539
|
+
}
|
|
4540
|
+
if (this.copyRowIndex !== undefined) {
|
|
4541
|
+
node.copySectionRow(this.copyRowIndex);
|
|
4542
|
+
}
|
|
4543
|
+
if (this.removeColumnIndex !== undefined) {
|
|
4544
|
+
node.removeSectionColumn(this.removeColumnIndex);
|
|
4545
|
+
}
|
|
4546
|
+
if (this.removeRowIndex !== undefined) {
|
|
4547
|
+
node.removeSectionRow(this.removeRowIndex);
|
|
4548
|
+
}
|
|
4549
|
+
node.geometryTimestamp = this.timestamp;
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
serialize() {
|
|
4553
|
+
return {
|
|
4554
|
+
type: 'addSection',
|
|
4555
|
+
nodeId: this.nodeId,
|
|
4556
|
+
copyColumnIndex: this.copyColumnIndex,
|
|
4557
|
+
copyRowIndex: this.copyRowIndex,
|
|
4558
|
+
removeColumnIndex: this.removeColumnIndex,
|
|
4559
|
+
removeRowIndex: this.removeRowIndex,
|
|
4560
|
+
timestamp: this.timestamp
|
|
4561
|
+
};
|
|
4562
|
+
}
|
|
4563
|
+
static deserialize(canvas, serialized) {
|
|
4564
|
+
return new AddSectionCollabAction(canvas, serialized.nodeId, serialized.copyColumnIndex, serialized.copyRowIndex, serialized.removeColumnIndex, serialized.removeRowIndex, serialized.timestamp);
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4421
4567
|
/**
|
|
4422
4568
|
* Collaborative which consists of applying a layout to the diagram which can change the location of several nodes.
|
|
4423
4569
|
* @private
|
|
@@ -4834,6 +4980,12 @@ class CollabEngine {
|
|
|
4834
4980
|
action.do();
|
|
4835
4981
|
break;
|
|
4836
4982
|
}
|
|
4983
|
+
case 'addSection':
|
|
4984
|
+
{
|
|
4985
|
+
const action = AddSectionCollabAction.deserialize(this.canvas, message);
|
|
4986
|
+
action.do();
|
|
4987
|
+
break;
|
|
4988
|
+
}
|
|
4837
4989
|
case 'applyLayout':
|
|
4838
4990
|
{
|
|
4839
4991
|
const action = ApplyLayoutCollabAction.deserialize(this.canvas, message);
|
|
@@ -4996,6 +5148,12 @@ var DiagramActions;
|
|
|
4996
5148
|
* @see AddNodeAction
|
|
4997
5149
|
*/
|
|
4998
5150
|
DiagramActions["AddNode"] = "add-node";
|
|
5151
|
+
/**
|
|
5152
|
+
* Action that corresponds to the addition or removal of sections in a node.
|
|
5153
|
+
* @public
|
|
5154
|
+
* @see AddSectionAction
|
|
5155
|
+
*/
|
|
5156
|
+
DiagramActions["AddSectionAction"] = "add-section";
|
|
4999
5157
|
/**
|
|
5000
5158
|
* Action that corresponds to applying a layout which changes the location of several nodes.
|
|
5001
5159
|
* @public
|
|
@@ -7970,7 +8128,7 @@ class DiagramCanvas {
|
|
|
7970
8128
|
}
|
|
7971
8129
|
updateConnectionLabelsInView(connection) {
|
|
7972
8130
|
var _a, _b, _c;
|
|
7973
|
-
const connectionSelection = this.selectCanvasView().select(`
|
|
8131
|
+
const connectionSelection = this.selectCanvasView().select(`[id='${escapeSelector(connection.id)}']`);
|
|
7974
8132
|
const pathSelection = connectionSelection.select('path');
|
|
7975
8133
|
const pathNode = pathSelection.node();
|
|
7976
8134
|
const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), connection.type.label);
|
|
@@ -8012,7 +8170,7 @@ class DiagramCanvas {
|
|
|
8012
8170
|
}
|
|
8013
8171
|
}
|
|
8014
8172
|
updateConnectionMarkersInView(connection) {
|
|
8015
|
-
const connectionSelection = this.selectCanvasView().select(`
|
|
8173
|
+
const connectionSelection = this.selectCanvasView().select(`[id='${escapeSelector(connection.id)}']`);
|
|
8016
8174
|
const startMarkerSelection = connectionSelection.select('marker.diagram-connection-start-marker');
|
|
8017
8175
|
const endMarkerSelection = connectionSelection.select('marker.diagram-connection-end-marker');
|
|
8018
8176
|
if (connection.startMarkerLook !== null) {
|
|
@@ -8026,13 +8184,27 @@ class DiagramCanvas {
|
|
|
8026
8184
|
endMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', 0).attr('markerHeight', 0);
|
|
8027
8185
|
}
|
|
8028
8186
|
}
|
|
8029
|
-
|
|
8187
|
+
fieldRootFitsInView(id) {
|
|
8188
|
+
var _a, _b, _c, _d;
|
|
8189
|
+
const field = this.model.fields.get(id);
|
|
8190
|
+
if (!field) {
|
|
8191
|
+
return false;
|
|
8192
|
+
}
|
|
8193
|
+
if (field.rootElement instanceof DiagramNode || field.rootElement instanceof DiagramSection) {
|
|
8194
|
+
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8195
|
+
const stretchX = fieldDimensions[0] + getLeftMargin((_a = field.rootElement.type) === null || _a === undefined ? undefined : _a.label) + getRightMargin((_b = field.rootElement.type) === null || _b === undefined ? undefined : _b.label) - field.rootElement.width;
|
|
8196
|
+
const stretchY = fieldDimensions[1] + getTopMargin((_c = field.rootElement.type) === null || _c === undefined ? undefined : _c.label) + getBottomMargin((_d = field.rootElement.type) === null || _d === undefined ? undefined : _d.label) - field.rootElement.height;
|
|
8197
|
+
return stretchX <= 0 && stretchY <= 0;
|
|
8198
|
+
}
|
|
8199
|
+
return true;
|
|
8200
|
+
}
|
|
8201
|
+
fitFieldRootInView(id, shrink) {
|
|
8030
8202
|
var _a, _b, _c;
|
|
8031
8203
|
const field = this.model.fields.get(id);
|
|
8032
8204
|
if (!field) {
|
|
8033
8205
|
return;
|
|
8034
8206
|
}
|
|
8035
|
-
if (field.rootElement instanceof DiagramNode
|
|
8207
|
+
if (field.rootElement instanceof DiagramNode) {
|
|
8036
8208
|
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8037
8209
|
let stretchX = fieldDimensions[0] + getLeftMargin(field.rootElement.type.label) + getRightMargin(field.rootElement.type.label) - field.rootElement.width;
|
|
8038
8210
|
let stretchY = fieldDimensions[1] + getTopMargin(field.rootElement.type.label) + getBottomMargin(field.rootElement.type.label) - field.rootElement.height;
|
|
@@ -8047,10 +8219,14 @@ class DiagramCanvas {
|
|
|
8047
8219
|
if (field.rootElement.height + stretchY < field.rootElement.type.minHeight) {
|
|
8048
8220
|
stretchY = field.rootElement.type.minHeight - field.rootElement.height;
|
|
8049
8221
|
}
|
|
8050
|
-
|
|
8051
|
-
|
|
8222
|
+
if (shrink !== false || stretchX > 0) {
|
|
8223
|
+
field.rootElement.stretch(Side.Right, stretchX);
|
|
8224
|
+
}
|
|
8225
|
+
if (shrink !== false || stretchY > 0) {
|
|
8226
|
+
field.rootElement.stretch(Side.Bottom, stretchY);
|
|
8227
|
+
}
|
|
8052
8228
|
}
|
|
8053
|
-
if (field.rootElement instanceof DiagramSection
|
|
8229
|
+
if (field.rootElement instanceof DiagramSection) {
|
|
8054
8230
|
const fieldDimensions = this.minimumSizeOfField(field);
|
|
8055
8231
|
let minimumFieldWidth = fieldDimensions[0];
|
|
8056
8232
|
let minimumFieldHeight = fieldDimensions[1];
|
|
@@ -8083,8 +8259,12 @@ class DiagramCanvas {
|
|
|
8083
8259
|
if (field.rootElement.height + stretchY < (field.rootElement.getMinHeight() || 0)) {
|
|
8084
8260
|
stretchY = (field.rootElement.getMinHeight() || 0) - field.rootElement.height;
|
|
8085
8261
|
}
|
|
8086
|
-
(
|
|
8087
|
-
|
|
8262
|
+
if (shrink !== false || stretchX > 0) {
|
|
8263
|
+
(_b = field.rootElement.node) === null || _b === undefined ? undefined : _b.stretchSections(Side.Right, stretchX, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
|
|
8264
|
+
}
|
|
8265
|
+
if (shrink !== false || stretchY > 0) {
|
|
8266
|
+
(_c = field.rootElement.node) === null || _c === undefined ? undefined : _c.stretchSections(Side.Bottom, stretchY, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
|
|
8267
|
+
}
|
|
8088
8268
|
}
|
|
8089
8269
|
}
|
|
8090
8270
|
fitNodeInView(id) {
|
|
@@ -8773,6 +8953,9 @@ class Grid {
|
|
|
8773
8953
|
* @public
|
|
8774
8954
|
*/
|
|
8775
8955
|
class AdjacencyLayout {
|
|
8956
|
+
constructor(gapSize) {
|
|
8957
|
+
this.gapSize = gapSize;
|
|
8958
|
+
}
|
|
8776
8959
|
apply(model) {
|
|
8777
8960
|
var _a;
|
|
8778
8961
|
if (model.nodes.length === 0) {
|
|
@@ -8788,7 +8971,7 @@ class AdjacencyLayout {
|
|
|
8788
8971
|
// place nodes according to arrangement
|
|
8789
8972
|
const maximumWidth = Math.max(...model.nodes.map(n => n.width));
|
|
8790
8973
|
const maximumHeight = Math.max(...model.nodes.map(n => n.height));
|
|
8791
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8974
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8792
8975
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
8793
8976
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
8794
8977
|
const node = nodeArrangement.get([x, y]);
|
|
@@ -8816,6 +8999,9 @@ const arrangeNode = (node, nodeArrangement, coords, nodesToBeArranged) => {
|
|
|
8816
8999
|
* @public
|
|
8817
9000
|
*/
|
|
8818
9001
|
class BreadthAdjacencyLayout {
|
|
9002
|
+
constructor(gapSize) {
|
|
9003
|
+
this.gapSize = gapSize;
|
|
9004
|
+
}
|
|
8819
9005
|
apply(model) {
|
|
8820
9006
|
var _a;
|
|
8821
9007
|
if (model.nodes.length === 0) {
|
|
@@ -8853,7 +9039,7 @@ class BreadthAdjacencyLayout {
|
|
|
8853
9039
|
// place nodes according to arrangement
|
|
8854
9040
|
const maximumWidth = Math.max(...model.nodes.map(n => n.width));
|
|
8855
9041
|
const maximumHeight = Math.max(...model.nodes.map(n => n.height));
|
|
8856
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9042
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8857
9043
|
for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
|
|
8858
9044
|
for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
|
|
8859
9045
|
const node = nodeArrangement.get([x, y]);
|
|
@@ -8871,13 +9057,16 @@ class BreadthAdjacencyLayout {
|
|
|
8871
9057
|
* @public
|
|
8872
9058
|
*/
|
|
8873
9059
|
class BreadthLayout {
|
|
9060
|
+
constructor(gapSize) {
|
|
9061
|
+
this.gapSize = gapSize;
|
|
9062
|
+
}
|
|
8874
9063
|
apply(model) {
|
|
8875
9064
|
var _a;
|
|
8876
9065
|
if (model.nodes.length === 0) {
|
|
8877
9066
|
// nothing to arrange...
|
|
8878
9067
|
return model;
|
|
8879
9068
|
}
|
|
8880
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9069
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8881
9070
|
let nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
8882
9071
|
// Arrange nodes by a breadth first search
|
|
8883
9072
|
const firstNode = nodesToBeArranged[0];
|
|
@@ -8933,6 +9122,9 @@ class BreadthLayout {
|
|
|
8933
9122
|
* @public
|
|
8934
9123
|
*/
|
|
8935
9124
|
class ForceLayout {
|
|
9125
|
+
constructor(gapSize) {
|
|
9126
|
+
this.gapSize = gapSize;
|
|
9127
|
+
}
|
|
8936
9128
|
apply(model) {
|
|
8937
9129
|
var _a;
|
|
8938
9130
|
if (model.nodes.length === 0) {
|
|
@@ -8941,7 +9133,7 @@ class ForceLayout {
|
|
|
8941
9133
|
}
|
|
8942
9134
|
// as a starting point, we apply a simple layout
|
|
8943
9135
|
new BreadthLayout().apply(model);
|
|
8944
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9136
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
8945
9137
|
const coolingFactor = 0.99;
|
|
8946
9138
|
const minimumTemperature = 1;
|
|
8947
9139
|
const attractionFactor = 0.1;
|
|
@@ -9028,13 +9220,16 @@ class ForceLayout {
|
|
|
9028
9220
|
* @public
|
|
9029
9221
|
*/
|
|
9030
9222
|
class HorizontalLayout {
|
|
9223
|
+
constructor(gapSize) {
|
|
9224
|
+
this.gapSize = gapSize;
|
|
9225
|
+
}
|
|
9031
9226
|
apply(model) {
|
|
9032
9227
|
var _a;
|
|
9033
9228
|
if (model.nodes.length === 0) {
|
|
9034
9229
|
// nothing to arrange...
|
|
9035
9230
|
return model;
|
|
9036
9231
|
}
|
|
9037
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9232
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9038
9233
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9039
9234
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
9040
9235
|
let widthAccumulator = 0;
|
|
@@ -9051,6 +9246,9 @@ class HorizontalLayout {
|
|
|
9051
9246
|
* @public
|
|
9052
9247
|
*/
|
|
9053
9248
|
class PriorityLayout {
|
|
9249
|
+
constructor(gapSize) {
|
|
9250
|
+
this.gapSize = gapSize;
|
|
9251
|
+
}
|
|
9054
9252
|
apply(model) {
|
|
9055
9253
|
var _a;
|
|
9056
9254
|
if (model.nodes.length === 0) {
|
|
@@ -9064,7 +9262,7 @@ class PriorityLayout {
|
|
|
9064
9262
|
new BreadthLayout().apply(model);
|
|
9065
9263
|
return model;
|
|
9066
9264
|
}
|
|
9067
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9265
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9068
9266
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9069
9267
|
const nodeArrangement = [];
|
|
9070
9268
|
const nodesWithMaximumPriorityToBeArranged = model.nodes.filter(n => !n.parent).filter(n => n.getPriority() >= maximumPriority);
|
|
@@ -9158,6 +9356,9 @@ class PriorityLayout {
|
|
|
9158
9356
|
* @public
|
|
9159
9357
|
*/
|
|
9160
9358
|
class TreeLayout {
|
|
9359
|
+
constructor(gapSize) {
|
|
9360
|
+
this.gapSize = gapSize;
|
|
9361
|
+
}
|
|
9161
9362
|
apply(model) {
|
|
9162
9363
|
var _a;
|
|
9163
9364
|
if (model.nodes.length === 0) {
|
|
@@ -9171,7 +9372,7 @@ class TreeLayout {
|
|
|
9171
9372
|
new BreadthLayout().apply(model);
|
|
9172
9373
|
return model;
|
|
9173
9374
|
}
|
|
9174
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9375
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9175
9376
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent).sort((n1, n2) => n2.getPriority() - n1.getPriority());
|
|
9176
9377
|
const branches = [];
|
|
9177
9378
|
while (nodesToBeArranged.length > 0) {
|
|
@@ -9256,13 +9457,16 @@ class Branch {
|
|
|
9256
9457
|
* @public
|
|
9257
9458
|
*/
|
|
9258
9459
|
class VerticalLayout {
|
|
9460
|
+
constructor(gapSize) {
|
|
9461
|
+
this.gapSize = gapSize;
|
|
9462
|
+
}
|
|
9259
9463
|
apply(model) {
|
|
9260
9464
|
var _a;
|
|
9261
9465
|
if (model.nodes.length === 0) {
|
|
9262
9466
|
// nothing to arrange...
|
|
9263
9467
|
return model;
|
|
9264
9468
|
}
|
|
9265
|
-
const gapSize = (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9469
|
+
const gapSize = this.gapSize !== undefined ? this.gapSize : (((_a = model.canvas) === null || _a === undefined ? undefined : _a.gridSize) || 0) * 2;
|
|
9266
9470
|
const nodesToBeArranged = model.nodes.filter(n => !n.parent);
|
|
9267
9471
|
nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
|
|
9268
9472
|
let heightAccumulator = 0;
|
package/package.json
CHANGED
|
@@ -116,7 +116,8 @@ export declare class DiagramCanvas implements Canvas {
|
|
|
116
116
|
updateDecoratorsInView(...ids: string[]): void;
|
|
117
117
|
private updateConnectionLabelsInView;
|
|
118
118
|
private updateConnectionMarkersInView;
|
|
119
|
-
|
|
119
|
+
fieldRootFitsInView(id: string): boolean;
|
|
120
|
+
fitFieldRootInView(id: string, shrink?: boolean): void;
|
|
120
121
|
fitNodeInView(id: string): void;
|
|
121
122
|
selectRoot(): d3.Selection<HTMLDivElement, unknown, null, unknown>;
|
|
122
123
|
selectSVGElement(): d3.Selection<SVGElement, unknown, null, unknown>;
|
|
@@ -32,7 +32,7 @@ export interface CollabAction {
|
|
|
32
32
|
/**
|
|
33
33
|
* @private
|
|
34
34
|
*/
|
|
35
|
-
export type CollabActionSerialized = AddNodeSerialized | ApplyLayoutSerialized | MoveSerialized | SetGeometrySerialized | SetParentSerialized | AddConnectionSerialized | EditFieldSerialized | UpdateValuesSerialized | SetSelfRemovedSerialized | PasteSerialized;
|
|
35
|
+
export type CollabActionSerialized = AddNodeSerialized | AddSectionSerialized | ApplyLayoutSerialized | MoveSerialized | SetGeometrySerialized | SetParentSerialized | AddConnectionSerialized | EditFieldSerialized | UpdateValuesSerialized | SetSelfRemovedSerialized | PasteSerialized;
|
|
36
36
|
/**
|
|
37
37
|
* @private
|
|
38
38
|
*/
|
|
@@ -69,6 +69,36 @@ export declare class AddNodeCollabAction implements CollabAction {
|
|
|
69
69
|
serialize(): AddNodeSerialized;
|
|
70
70
|
static deserialize(canvas: Canvas, serialized: AddNodeSerialized): AddNodeCollabAction;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
export type AddSectionSerialized = {
|
|
76
|
+
type: 'addSection';
|
|
77
|
+
nodeId: string;
|
|
78
|
+
copyColumnIndex: number | undefined;
|
|
79
|
+
copyRowIndex: number | undefined;
|
|
80
|
+
removeColumnIndex: number | undefined;
|
|
81
|
+
removeRowIndex: number | undefined;
|
|
82
|
+
timestamp: CollabTimestamp;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Collaborative action which consists of adding or removing sections in a node.
|
|
86
|
+
* @private
|
|
87
|
+
* @see AddNodeAction
|
|
88
|
+
*/
|
|
89
|
+
export declare class AddSectionCollabAction implements CollabAction {
|
|
90
|
+
readonly canvas: Canvas;
|
|
91
|
+
readonly nodeId: string;
|
|
92
|
+
readonly copyColumnIndex: number | undefined;
|
|
93
|
+
readonly copyRowIndex: number | undefined;
|
|
94
|
+
readonly removeColumnIndex: number | undefined;
|
|
95
|
+
readonly removeRowIndex: number | undefined;
|
|
96
|
+
readonly timestamp: CollabTimestamp;
|
|
97
|
+
constructor(canvas: Canvas, nodeId: string, copyColumnIndex: number | undefined, copyRowIndex: number | undefined, removeColumnIndex: number | undefined, removeRowIndex: number | undefined, timestamp: CollabTimestamp);
|
|
98
|
+
do(): void;
|
|
99
|
+
serialize(): AddSectionSerialized;
|
|
100
|
+
static deserialize(canvas: Canvas, serialized: AddSectionSerialized): AddSectionCollabAction;
|
|
101
|
+
}
|
|
72
102
|
/**
|
|
73
103
|
* @private
|
|
74
104
|
*/
|
|
@@ -3,8 +3,8 @@ import { HorizontalAlign, Side, VerticalAlign } from '../../util/svg-util';
|
|
|
3
3
|
import { DiagramActions } from '../diagram-action';
|
|
4
4
|
import { Property } from '../property/property';
|
|
5
5
|
import { CanvasConfig } from './diagram-canvas-config';
|
|
6
|
-
import { ConnectionLookConfig, ImageLookConfig, MarkerImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from './diagram-look-config';
|
|
7
6
|
import { ComponentsConfig } from './diagram-components-config';
|
|
7
|
+
import { ConnectionLookConfig, ImageLookConfig, MarkerImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from './diagram-look-config';
|
|
8
8
|
/**
|
|
9
9
|
* The configuration for a diagram.
|
|
10
10
|
* @public
|
|
@@ -102,6 +102,12 @@ export declare enum DiagramActions {
|
|
|
102
102
|
* @see AddNodeAction
|
|
103
103
|
*/
|
|
104
104
|
AddNode = "add-node",
|
|
105
|
+
/**
|
|
106
|
+
* Action that corresponds to the addition or removal of sections in a node.
|
|
107
|
+
* @public
|
|
108
|
+
* @see AddSectionAction
|
|
109
|
+
*/
|
|
110
|
+
AddSectionAction = "add-section",
|
|
105
111
|
/**
|
|
106
112
|
* Action that corresponds to applying a layout which changes the location of several nodes.
|
|
107
113
|
* @public
|
|
@@ -192,6 +198,23 @@ export declare class AddNodeAction implements DiagramAction {
|
|
|
192
198
|
undo(): boolean;
|
|
193
199
|
redo(): boolean;
|
|
194
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Action which consists of adding or removing sections in a node.
|
|
203
|
+
* @private
|
|
204
|
+
* @see DiagramSection
|
|
205
|
+
*/
|
|
206
|
+
export declare class AddSectionAction implements DiagramAction {
|
|
207
|
+
readonly canvas: Canvas;
|
|
208
|
+
nodeId: string;
|
|
209
|
+
copyColumnIndex: number | undefined;
|
|
210
|
+
copyRowIndex: number | undefined;
|
|
211
|
+
removeColumnIndex: number | undefined;
|
|
212
|
+
removeRowIndex: number | undefined;
|
|
213
|
+
constructor(canvas: Canvas, nodeId: string, copyColumnIndex: number | undefined, copyRowIndex: number | undefined, removeColumnIndex: number | undefined, removeRowIndex: number | undefined);
|
|
214
|
+
do(): boolean;
|
|
215
|
+
undo(): boolean;
|
|
216
|
+
redo(): boolean;
|
|
217
|
+
}
|
|
195
218
|
/**
|
|
196
219
|
* Action which consists of applying a layout to the diagram which can change the location of several nodes.
|
|
197
220
|
* @private
|
|
@@ -276,6 +276,26 @@ export declare class DiagramNode extends DiagramElement implements LabeledElemen
|
|
|
276
276
|
* @public
|
|
277
277
|
*/
|
|
278
278
|
setGeometry(geometry: DiagramNodeGeometry): void;
|
|
279
|
+
/**
|
|
280
|
+
* Removes all sections with the given index along the x axis.
|
|
281
|
+
* @public
|
|
282
|
+
*/
|
|
283
|
+
removeSectionColumn(columnIndex: number): void;
|
|
284
|
+
/**
|
|
285
|
+
* Removes all sections with the given index along the y axis.
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
removeSectionRow(rowIndex: number): void;
|
|
289
|
+
/**
|
|
290
|
+
* Creates a copy of all sections with the given index along the x axis.
|
|
291
|
+
* @public
|
|
292
|
+
*/
|
|
293
|
+
copySectionColumn(columnIndex: number): void;
|
|
294
|
+
/**
|
|
295
|
+
* Creates a copy of all sections with the given index along the y axis.
|
|
296
|
+
* @public
|
|
297
|
+
*/
|
|
298
|
+
copySectionRow(rowIndex: number): void;
|
|
279
299
|
}
|
|
280
300
|
export declare class DiagramNodeSet extends DiagramElementSet<DiagramNode> {
|
|
281
301
|
private model;
|
|
@@ -284,11 +284,18 @@ export interface Canvas {
|
|
|
284
284
|
* @public
|
|
285
285
|
*/
|
|
286
286
|
updateDecoratorsInView(...ids: string[]): void;
|
|
287
|
+
/**
|
|
288
|
+
* Checks whether the root of a diagram field encompasses the totality of the field.
|
|
289
|
+
* @param id The id of a diagram field
|
|
290
|
+
* @returns `true` if the root of a diagram field encompasses the totality of the field, `false` otherwise.
|
|
291
|
+
*/
|
|
292
|
+
fieldRootFitsInView(id: string): boolean;
|
|
287
293
|
/**
|
|
288
294
|
* Fit the root of a diagram field to encompass the totality of the field.
|
|
289
295
|
* @param id The id of a diagram field
|
|
296
|
+
* @param shrink Whether the root of the diagram field should shrink if there is excess space; `true` by default
|
|
290
297
|
*/
|
|
291
|
-
fitFieldRootInView(id: string): void;
|
|
298
|
+
fitFieldRootInView(id: string, shrink?: boolean): void;
|
|
292
299
|
/**
|
|
293
300
|
* Fit a node to encompass the totality of its sections.
|
|
294
301
|
* @param id The id of a node
|