@metadev/daga 1.5.4 → 1.5.6

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.
@@ -655,60 +655,6 @@ const addIfNotExists = (arr, obj) => {
655
655
  return arr;
656
656
  };
657
657
 
658
- /**
659
- * Default priority value for diagram elements.
660
- * @private
661
- */
662
- const DEFAULT_PRIORITY = 0;
663
- /**
664
- * Represents an object which exists as part of a specific diagram model and has a visual representation in a diagram canvas.
665
- * @public
666
- * @see DiagramModel
667
- * @see DiagramCanvas
668
- */
669
- class DiagramElement {
670
- get id() {
671
- return this._id;
672
- }
673
- constructor(model, id) {
674
- /**
675
- * Whether this diagram element is currently highlighted by the user.
676
- * @private
677
- */
678
- this.highlighted = false;
679
- /**
680
- * Whether this diagram element is currently selected by the user.
681
- * @private
682
- */
683
- this.selected = false;
684
- /**
685
- * Whether this diagram element has itself been explicitly removed.
686
- *
687
- * Override the `removed` getter so that it returns true if and only if:
688
- * - `selfRemoved` is true, or
689
- * - `removed` is true for any of this element's dependencies.
690
- *
691
- * For example, a DiagramConnection is removed if either of its ports are removed,
692
- * even if the connection's own `selfRemoved` field is false.
693
- * @private
694
- */
695
- this.selfRemoved = false;
696
- /**
697
- * Collaborative timestamp for selfRemoved.
698
- * @private
699
- */
700
- this.selfRemovedTimestamp = null;
701
- this.model = model;
702
- this._id = id;
703
- }
704
- /**
705
- * Obtain the selection of this element.
706
- * @private
707
- */
708
- select() {
709
- return this.model.canvas?.selectCanvasView()?.select(`g#${this.id}`);
710
- }
711
- }
712
658
  /**
713
659
  * Represents a collection of diagram entities of a type that exists as part of a diagram model.
714
660
  * @public
@@ -729,11 +675,11 @@ class DiagramEntitySet {
729
675
  this.entityMap = {};
730
676
  }
731
677
  /**
732
- * The number of entities of this set.
678
+ * The number of entities in this set.
733
679
  * @public
734
680
  */
735
681
  get length() {
736
- return this.entities.length;
682
+ return this.size();
737
683
  }
738
684
  /**
739
685
  * Gets all of the entities of this set.
@@ -774,6 +720,14 @@ class DiagramEntitySet {
774
720
  contains(id) {
775
721
  return this.entityMap[id] !== undefined;
776
722
  }
723
+ /**
724
+ * Counts the number of entities of this set following the given criteria.
725
+ * @public
726
+ * @returns The number of entities of this set following the given criteria.
727
+ */
728
+ count(predicate) {
729
+ return this.entities.filter(predicate).length;
730
+ }
777
731
  /**
778
732
  * Gets all of the entities of this set filtered following given criteria.
779
733
  * @public
@@ -799,6 +753,14 @@ class DiagramEntitySet {
799
753
  get(id) {
800
754
  return this.entityMap[id];
801
755
  }
756
+ /**
757
+ * Gets all of the entities of this set mapped to the result of the given function applied to them.
758
+ * @public
759
+ * @returns An array containing the entities of this set that meet the given criteria.
760
+ */
761
+ map(callback) {
762
+ return this.entities.map(callback);
763
+ }
802
764
  /**
803
765
  * Attempts to find and remove an entity with the given id. Has no effect if there are no entities with the given id.
804
766
  * @public
@@ -811,15 +773,159 @@ class DiagramEntitySet {
811
773
  removeIfExists(this.entities, entity);
812
774
  }
813
775
  }
776
+ /**
777
+ * Gets the number of entities in this set.
778
+ * @public
779
+ */
780
+ size() {
781
+ return this.entities.length;
782
+ }
814
783
  /**
815
784
  * Iterator to iterate over the entities of this set.
816
785
  * @public
817
786
  */
818
787
  *[Symbol.iterator]() {
819
- let counter = 0;
820
- while (counter < this.entities.length) {
821
- yield this.entities[counter];
822
- ++counter;
788
+ for (const entity of this.entities) {
789
+ yield entity;
790
+ }
791
+ }
792
+ }
793
+
794
+ /**
795
+ * Default priority value for diagram elements.
796
+ * @private
797
+ */
798
+ const DEFAULT_PRIORITY = 0;
799
+ /**
800
+ * Represents an object which exists as part of a specific diagram model and has a visual representation in a diagram canvas.
801
+ * @public
802
+ * @see DiagramModel
803
+ * @see DiagramCanvas
804
+ */
805
+ class DiagramElement {
806
+ get id() {
807
+ return this._id;
808
+ }
809
+ constructor(model, id) {
810
+ /**
811
+ * Whether this diagram element is currently highlighted by the user.
812
+ * @private
813
+ */
814
+ this.highlighted = false;
815
+ /**
816
+ * Whether this diagram element is currently selected by the user.
817
+ * @private
818
+ */
819
+ this.selected = false;
820
+ /**
821
+ * Whether this diagram element has itself been explicitly removed.
822
+ *
823
+ * Override the `removed` getter so that it returns true if and only if:
824
+ * - `selfRemoved` is true, or
825
+ * - `removed` is true for any of this element's dependencies.
826
+ *
827
+ * For example, a DiagramConnection is removed if either of its ports are removed,
828
+ * even if the connection's own `selfRemoved` field is false.
829
+ * @private
830
+ */
831
+ this.selfRemoved = false;
832
+ /**
833
+ * Collaborative timestamp for selfRemoved.
834
+ * @private
835
+ */
836
+ this.selfRemovedTimestamp = null;
837
+ this.model = model;
838
+ this._id = id;
839
+ }
840
+ /**
841
+ * Obtain the selection of this element.
842
+ * @private
843
+ */
844
+ select() {
845
+ return this.model.canvas?.selectCanvasView()?.select(`g#${this.id}`);
846
+ }
847
+ }
848
+ class DiagramElementSet extends DiagramEntitySet {
849
+ all(includeRemoved = false) {
850
+ if (includeRemoved) {
851
+ return super.all();
852
+ }
853
+ else {
854
+ return super.filter((e) => !e.removed);
855
+ }
856
+ }
857
+ contains(id, includeRemoved = false) {
858
+ if (includeRemoved) {
859
+ return super.contains(id);
860
+ }
861
+ else {
862
+ return super.contains(id) && !this.entityMap[id].removed;
863
+ }
864
+ }
865
+ count(predicate, includeRemoved = false) {
866
+ if (includeRemoved) {
867
+ return super.count(predicate);
868
+ }
869
+ else {
870
+ return super.count((e, i, a) => predicate(e, i, a) && !e.removed);
871
+ }
872
+ }
873
+ filter(predicate, includeRemoved = false) {
874
+ if (includeRemoved) {
875
+ return super.filter(predicate);
876
+ }
877
+ else {
878
+ return super.filter((e, i, a) => predicate(e, i, a) && !e.removed);
879
+ }
880
+ }
881
+ find(predicate, includeRemoved = false) {
882
+ if (includeRemoved) {
883
+ return super.find(predicate);
884
+ }
885
+ else {
886
+ return super.find((e, i, a) => predicate(e, i, a) && !e.removed);
887
+ }
888
+ }
889
+ get(id, includeRemoved = false) {
890
+ if (includeRemoved) {
891
+ return super.get(id);
892
+ }
893
+ else {
894
+ return super.contains(id) && !this.entityMap[id].removed
895
+ ? super.get(id)
896
+ : undefined;
897
+ }
898
+ }
899
+ map(callback, includeRemoved = false) {
900
+ if (includeRemoved) {
901
+ return super.map(callback);
902
+ }
903
+ else {
904
+ return super.filter((e) => !e.removed).map(callback);
905
+ }
906
+ }
907
+ /**
908
+ * Gets the number of entities in this set.
909
+ * @public
910
+ */
911
+ size(includeRemoved = false) {
912
+ if (includeRemoved) {
913
+ return super.size();
914
+ }
915
+ else {
916
+ return super.filter((e) => !e.removed).length;
917
+ }
918
+ }
919
+ *[Symbol.iterator](includeRemoved = false) {
920
+ if (includeRemoved) {
921
+ for (const entity of this.entities) {
922
+ yield entity;
923
+ }
924
+ }
925
+ else {
926
+ for (const entity of this.entities.filter((e) => !e.removed)) {
927
+ yield entity;
928
+ }
823
929
  }
824
930
  }
825
931
  }
@@ -1692,7 +1798,7 @@ class DiagramConnection extends DiagramElement {
1692
1798
  }
1693
1799
  }
1694
1800
  }
1695
- class DiagramConnectionSet extends DiagramEntitySet {
1801
+ class DiagramConnectionSet extends DiagramElementSet {
1696
1802
  /**
1697
1803
  * Instance a set of connections for the given model. This method is used internally.
1698
1804
  * @private
@@ -2263,10 +2369,13 @@ class DiagramSection extends DiagramElement {
2263
2369
  * @public
2264
2370
  * @returns A list of connections.
2265
2371
  */
2266
- getIncomingConnections() {
2372
+ getIncomingConnections(includeRemoved = false) {
2267
2373
  const result = [];
2268
2374
  for (const port of this.ports) {
2269
2375
  for (const incomingConnection of port.incomingConnections) {
2376
+ if (!includeRemoved && incomingConnection.removed) {
2377
+ continue;
2378
+ }
2270
2379
  result.push(incomingConnection);
2271
2380
  }
2272
2381
  }
@@ -2277,10 +2386,13 @@ class DiagramSection extends DiagramElement {
2277
2386
  * @public
2278
2387
  * @returns A list of connections.
2279
2388
  */
2280
- getOutgoingConnections() {
2389
+ getOutgoingConnections(includeRemoved = false) {
2281
2390
  const result = [];
2282
2391
  for (const port of this.ports) {
2283
2392
  for (const outgoingConnection of port.outgoingConnections) {
2393
+ if (!includeRemoved && outgoingConnection.removed) {
2394
+ continue;
2395
+ }
2284
2396
  result.push(outgoingConnection);
2285
2397
  }
2286
2398
  }
@@ -2291,13 +2403,19 @@ class DiagramSection extends DiagramElement {
2291
2403
  * @public
2292
2404
  * @returns A list of connections.
2293
2405
  */
2294
- getConnections() {
2406
+ getConnections(includeRemoved = false) {
2295
2407
  const result = [];
2296
2408
  for (const port of this.ports) {
2297
2409
  for (const incomingConnection of port.incomingConnections) {
2410
+ if (!includeRemoved && incomingConnection.removed) {
2411
+ continue;
2412
+ }
2298
2413
  result.push(incomingConnection);
2299
2414
  }
2300
2415
  for (const outgoingConnection of port.outgoingConnections) {
2416
+ if (!includeRemoved && outgoingConnection.removed) {
2417
+ continue;
2418
+ }
2301
2419
  result.push(outgoingConnection);
2302
2420
  }
2303
2421
  }
@@ -2392,13 +2510,17 @@ class DiagramSection extends DiagramElement {
2392
2510
  // Set label's dimensions as a function of ours.
2393
2511
  if (this.label) {
2394
2512
  this.label.coords = [
2395
- this.coords[0] + (this.getConfig()?.label?.margin || 0),
2396
- this.coords[1] + (this.getConfig()?.label?.margin || 0)
2513
+ this.coords[0] + getLeftMargin(this.getConfig()?.label),
2514
+ this.coords[1] + getTopMargin(this.getConfig()?.label)
2397
2515
  ];
2398
- (this.label.width =
2399
- this.width - (this.getConfig()?.label?.margin || 0) * 2),
2400
- (this.label.height =
2401
- this.height - (this.getConfig()?.label?.margin || 0) * 2);
2516
+ this.label.width =
2517
+ this.width -
2518
+ getLeftMargin(this.getConfig()?.label) -
2519
+ getRightMargin(this.getConfig()?.label);
2520
+ this.label.height =
2521
+ this.height -
2522
+ getTopMargin(this.getConfig()?.label) -
2523
+ getBottomMargin(this.getConfig()?.label);
2402
2524
  this.label.updateInView();
2403
2525
  }
2404
2526
  // Move decorators to match the new coords.
@@ -2410,7 +2532,7 @@ class DiagramSection extends DiagramElement {
2410
2532
  this.updateInView();
2411
2533
  }
2412
2534
  }
2413
- class DiagramSectionSet extends DiagramEntitySet {
2535
+ class DiagramSectionSet extends DiagramElementSet {
2414
2536
  /**
2415
2537
  * Instance a set of sections for the given model. This method is used internally.
2416
2538
  * @private
@@ -2480,9 +2602,13 @@ class DiagramSectionSet extends DiagramEntitySet {
2480
2602
  ...sectionLabel
2481
2603
  };
2482
2604
  this.model.fields.new(section, [
2483
- section.coords[0] + labelConfiguration.margin,
2484
- section.coords[1] + labelConfiguration.margin
2485
- ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width - labelConfiguration.margin * 2, section.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
2605
+ section.coords[0] + getLeftMargin(labelConfiguration),
2606
+ section.coords[1] + getTopMargin(labelConfiguration)
2607
+ ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width -
2608
+ getLeftMargin(labelConfiguration) -
2609
+ getRightMargin(labelConfiguration), section.height -
2610
+ getTopMargin(labelConfiguration) -
2611
+ getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
2486
2612
  }
2487
2613
  return section;
2488
2614
  }
@@ -2656,10 +2782,13 @@ class DiagramNode extends DiagramElement {
2656
2782
  * @public
2657
2783
  * @returns A list of connections.
2658
2784
  */
2659
- getIncomingConnections() {
2785
+ getIncomingConnections(includeRemoved = false) {
2660
2786
  const result = [];
2661
2787
  for (const port of this.ports) {
2662
2788
  for (const incomingConnection of port.incomingConnections) {
2789
+ if (!includeRemoved && incomingConnection.removed) {
2790
+ continue;
2791
+ }
2663
2792
  result.push(incomingConnection);
2664
2793
  }
2665
2794
  }
@@ -2670,10 +2799,13 @@ class DiagramNode extends DiagramElement {
2670
2799
  * @public
2671
2800
  * @returns A list of connections.
2672
2801
  */
2673
- getOutgoingConnections() {
2802
+ getOutgoingConnections(includeRemoved = false) {
2674
2803
  const result = [];
2675
2804
  for (const port of this.ports) {
2676
2805
  for (const outgoingConnection of port.outgoingConnections) {
2806
+ if (!includeRemoved && outgoingConnection.removed) {
2807
+ continue;
2808
+ }
2677
2809
  result.push(outgoingConnection);
2678
2810
  }
2679
2811
  }
@@ -2684,13 +2816,19 @@ class DiagramNode extends DiagramElement {
2684
2816
  * @public
2685
2817
  * @returns A list of connections.
2686
2818
  */
2687
- getConnections() {
2819
+ getConnections(includeRemoved = false) {
2688
2820
  const result = [];
2689
2821
  for (const port of this.ports) {
2690
2822
  for (const incomingConnection of port.incomingConnections) {
2823
+ if (!includeRemoved && incomingConnection.removed) {
2824
+ continue;
2825
+ }
2691
2826
  result.push(incomingConnection);
2692
2827
  }
2693
2828
  for (const outgoingConnection of port.outgoingConnections) {
2829
+ if (!includeRemoved && outgoingConnection.removed) {
2830
+ continue;
2831
+ }
2694
2832
  result.push(outgoingConnection);
2695
2833
  }
2696
2834
  }
@@ -2701,18 +2839,30 @@ class DiagramNode extends DiagramElement {
2701
2839
  * @public
2702
2840
  * @returns A list of nodes.
2703
2841
  */
2704
- getAdjacentNodes() {
2842
+ getAdjacentNodes(includeRemoved = false) {
2705
2843
  const result = [];
2706
2844
  for (const port of this.ports) {
2707
2845
  for (const incomingConnection of port.incomingConnections) {
2846
+ if (!includeRemoved && incomingConnection.removed) {
2847
+ continue;
2848
+ }
2708
2849
  const otherNode = incomingConnection.start?.getNode();
2709
2850
  if (otherNode) {
2851
+ if (!includeRemoved && otherNode.removed) {
2852
+ continue;
2853
+ }
2710
2854
  result.push(otherNode);
2711
2855
  }
2712
2856
  }
2713
2857
  for (const outgoingConnection of port.outgoingConnections) {
2858
+ if (!includeRemoved && outgoingConnection.removed) {
2859
+ continue;
2860
+ }
2714
2861
  const otherNode = outgoingConnection.end?.getNode();
2715
2862
  if (otherNode) {
2863
+ if (!includeRemoved && otherNode.removed) {
2864
+ continue;
2865
+ }
2716
2866
  result.push(otherNode);
2717
2867
  }
2718
2868
  }
@@ -2920,11 +3070,17 @@ class DiagramNode extends DiagramElement {
2920
3070
  // Set label's dimensions as a function of ours.
2921
3071
  if (this.label) {
2922
3072
  this.label.coords = [
2923
- this.coords[0] + (this.type.label?.margin || 0),
2924
- this.coords[1] + (this.type.label?.margin || 0)
3073
+ this.coords[0] + getLeftMargin(this.type.label),
3074
+ this.coords[1] + getTopMargin(this.type.label)
2925
3075
  ];
2926
- (this.label.width = this.width - (this.type.label?.margin || 0) * 2),
2927
- (this.label.height = this.height - (this.type.label?.margin || 0) * 2);
3076
+ this.label.width =
3077
+ this.width -
3078
+ getLeftMargin(this.type.label) -
3079
+ getRightMargin(this.type.label);
3080
+ this.label.height =
3081
+ this.height -
3082
+ getTopMargin(this.type.label) -
3083
+ getBottomMargin(this.type.label);
2928
3084
  this.label.updateInView();
2929
3085
  }
2930
3086
  // Move decorators to match the new coords.
@@ -2936,7 +3092,7 @@ class DiagramNode extends DiagramElement {
2936
3092
  this.updateInView();
2937
3093
  }
2938
3094
  }
2939
- class DiagramNodeSet extends DiagramEntitySet {
3095
+ class DiagramNodeSet extends DiagramElementSet {
2940
3096
  /**
2941
3097
  * Instance a set of nodes for the given model. This method is used internally.
2942
3098
  * @private
@@ -3042,9 +3198,13 @@ class DiagramNodeSet extends DiagramEntitySet {
3042
3198
  ...nodeType.label
3043
3199
  };
3044
3200
  this.model.fields.new(node, [
3045
- node.coords[0] + labelConfiguration.margin,
3046
- node.coords[1] + labelConfiguration.margin
3047
- ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width - labelConfiguration.margin * 2, node.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3201
+ node.coords[0] + getLeftMargin(labelConfiguration),
3202
+ node.coords[1] + getTopMargin(labelConfiguration)
3203
+ ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width -
3204
+ getLeftMargin(labelConfiguration) -
3205
+ getRightMargin(labelConfiguration), node.height -
3206
+ getTopMargin(labelConfiguration) -
3207
+ getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3048
3208
  }
3049
3209
  node.valueSet.resetValues();
3050
3210
  node.model.canvas?.fitNodeInView(node.id);
@@ -3061,6 +3221,10 @@ class DiagramNodeSet extends DiagramEntitySet {
3061
3221
  while (node.ports.length > 0) {
3062
3222
  this.model.ports.remove(node.ports[0].id);
3063
3223
  }
3224
+ // remove all decorators
3225
+ while (node.decorators.length > 0) {
3226
+ this.model.decorators.remove(node.decorators[0].id);
3227
+ }
3064
3228
  // remove label
3065
3229
  if (node.label) {
3066
3230
  this.model.fields.remove(node.label.id);
@@ -3179,7 +3343,7 @@ class DiagramPort extends DiagramElement {
3179
3343
  return distanceBetweenPoints(this.coords, coords);
3180
3344
  }
3181
3345
  }
3182
- class DiagramPortSet extends DiagramEntitySet {
3346
+ class DiagramPortSet extends DiagramElementSet {
3183
3347
  /**
3184
3348
  * Instance a set of ports for the given model. This method is used internally.
3185
3349
  * @private
@@ -3322,7 +3486,7 @@ class DiagramField extends DiagramElement {
3322
3486
  return this.rootElement?.getPriority() || DEFAULT_PRIORITY;
3323
3487
  }
3324
3488
  }
3325
- class DiagramFieldSet extends DiagramEntitySet {
3489
+ class DiagramFieldSet extends DiagramElementSet {
3326
3490
  /**
3327
3491
  * Instance a set of fields for the given model. This method is used internally.
3328
3492
  * @private
@@ -3363,6 +3527,206 @@ class DiagramFieldSet extends DiagramEntitySet {
3363
3527
  }
3364
3528
  }
3365
3529
  }
3530
+ const getBottomMargin = (config) => {
3531
+ if (config?.margin === null || config?.margin === undefined) {
3532
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3533
+ }
3534
+ else if (typeof config.margin === 'number') {
3535
+ return config.margin;
3536
+ }
3537
+ else {
3538
+ if (config.margin.length === 0) {
3539
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3540
+ }
3541
+ else if (config.margin.length === 1) {
3542
+ return config.margin[0];
3543
+ }
3544
+ else if (config.margin.length === 2) {
3545
+ return config.margin[0];
3546
+ }
3547
+ else if (config.margin.length === 3) {
3548
+ return config.margin[2];
3549
+ }
3550
+ else {
3551
+ return config.margin[2];
3552
+ }
3553
+ }
3554
+ };
3555
+ const getLeftMargin = (config) => {
3556
+ if (config?.margin === null || config?.margin === undefined) {
3557
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3558
+ }
3559
+ else if (typeof config.margin === 'number') {
3560
+ return config.margin;
3561
+ }
3562
+ else {
3563
+ if (config.margin.length === 0) {
3564
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3565
+ }
3566
+ else if (config.margin.length === 1) {
3567
+ return config.margin[0];
3568
+ }
3569
+ else if (config.margin.length === 2) {
3570
+ return config.margin[1];
3571
+ }
3572
+ else if (config.margin.length === 3) {
3573
+ return config.margin[1];
3574
+ }
3575
+ else {
3576
+ return config.margin[3];
3577
+ }
3578
+ }
3579
+ };
3580
+ const getRightMargin = (config) => {
3581
+ if (config?.margin === null || config?.margin === undefined) {
3582
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3583
+ }
3584
+ else if (typeof config.margin === 'number') {
3585
+ return config.margin;
3586
+ }
3587
+ else {
3588
+ if (config.margin.length === 0) {
3589
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3590
+ }
3591
+ else if (config.margin.length === 1) {
3592
+ return config.margin[0];
3593
+ }
3594
+ else if (config.margin.length === 2) {
3595
+ return config.margin[1];
3596
+ }
3597
+ else if (config.margin.length === 3) {
3598
+ return config.margin[1];
3599
+ }
3600
+ else {
3601
+ return config.margin[1];
3602
+ }
3603
+ }
3604
+ };
3605
+ const getTopMargin = (config) => {
3606
+ if (config?.margin === null || config?.margin === undefined) {
3607
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3608
+ }
3609
+ else if (typeof config.margin === 'number') {
3610
+ return config.margin;
3611
+ }
3612
+ else {
3613
+ if (config.margin.length === 0) {
3614
+ return DIAGRAM_FIELD_DEFAULTS.margin;
3615
+ }
3616
+ else if (config.margin.length === 1) {
3617
+ return config.margin[0];
3618
+ }
3619
+ else if (config.margin.length === 2) {
3620
+ return config.margin[0];
3621
+ }
3622
+ else if (config.margin.length === 3) {
3623
+ return config.margin[0];
3624
+ }
3625
+ else {
3626
+ return config.margin[0];
3627
+ }
3628
+ }
3629
+ };
3630
+ const getBottomPadding = (config) => {
3631
+ if (config?.padding === null || config?.padding === undefined) {
3632
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3633
+ }
3634
+ else if (typeof config.padding === 'number') {
3635
+ return config.padding;
3636
+ }
3637
+ else {
3638
+ if (config.padding.length === 0) {
3639
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3640
+ }
3641
+ else if (config.padding.length === 1) {
3642
+ return config.padding[0];
3643
+ }
3644
+ else if (config.padding.length === 2) {
3645
+ return config.padding[0];
3646
+ }
3647
+ else if (config.padding.length === 3) {
3648
+ return config.padding[2];
3649
+ }
3650
+ else {
3651
+ return config.padding[2];
3652
+ }
3653
+ }
3654
+ };
3655
+ const getLeftPadding = (config) => {
3656
+ if (config?.padding === null || config?.padding === undefined) {
3657
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3658
+ }
3659
+ else if (typeof config.padding === 'number') {
3660
+ return config.padding;
3661
+ }
3662
+ else {
3663
+ if (config.padding.length === 0) {
3664
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3665
+ }
3666
+ else if (config.padding.length === 1) {
3667
+ return config.padding[0];
3668
+ }
3669
+ else if (config.padding.length === 2) {
3670
+ return config.padding[1];
3671
+ }
3672
+ else if (config.padding.length === 3) {
3673
+ return config.padding[1];
3674
+ }
3675
+ else {
3676
+ return config.padding[3];
3677
+ }
3678
+ }
3679
+ };
3680
+ const getRightPadding = (config) => {
3681
+ if (config?.padding === null || config?.padding === undefined) {
3682
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3683
+ }
3684
+ else if (typeof config.padding === 'number') {
3685
+ return config.padding;
3686
+ }
3687
+ else {
3688
+ if (config.padding.length === 0) {
3689
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3690
+ }
3691
+ else if (config.padding.length === 1) {
3692
+ return config.padding[0];
3693
+ }
3694
+ else if (config.padding.length === 2) {
3695
+ return config.padding[1];
3696
+ }
3697
+ else if (config.padding.length === 3) {
3698
+ return config.padding[1];
3699
+ }
3700
+ else {
3701
+ return config.padding[1];
3702
+ }
3703
+ }
3704
+ };
3705
+ const getTopPadding = (config) => {
3706
+ if (config?.padding === null || config?.padding === undefined) {
3707
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3708
+ }
3709
+ else if (typeof config.padding === 'number') {
3710
+ return config.padding;
3711
+ }
3712
+ else {
3713
+ if (config.padding.length === 0) {
3714
+ return DIAGRAM_FIELD_DEFAULTS.padding;
3715
+ }
3716
+ else if (config.padding.length === 1) {
3717
+ return config.padding[0];
3718
+ }
3719
+ else if (config.padding.length === 2) {
3720
+ return config.padding[0];
3721
+ }
3722
+ else if (config.padding.length === 3) {
3723
+ return config.padding[0];
3724
+ }
3725
+ else {
3726
+ return config.padding[0];
3727
+ }
3728
+ }
3729
+ };
3366
3730
 
3367
3731
  /**
3368
3732
  * Importer which imports a diagram from its daga model representation.
@@ -3410,9 +3774,13 @@ class DagaImporter {
3410
3774
  ...newNodeType.label
3411
3775
  };
3412
3776
  const newField = new DiagramField(model, newNode, [
3413
- newNode.coords[0] + labelConfiguration.margin,
3414
- newNode.coords[1] + labelConfiguration.margin
3415
- ], newNode.width - labelConfiguration.margin * 2, newNode.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3777
+ newNode.coords[0] + getLeftMargin(labelConfiguration),
3778
+ newNode.coords[1] + getTopMargin(labelConfiguration)
3779
+ ], newNode.width -
3780
+ getLeftMargin(labelConfiguration) -
3781
+ getRightMargin(labelConfiguration), newNode.height -
3782
+ getTopMargin(labelConfiguration) -
3783
+ getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3416
3784
  newField.text = node.label;
3417
3785
  newNode.label = newField;
3418
3786
  model.fields.add(newField);
@@ -3431,9 +3799,13 @@ class DagaImporter {
3431
3799
  ...newNodeType.sectionGrid?.sections?.[section.indexYInNode]?.[section.indexXInNode]?.label
3432
3800
  };
3433
3801
  const newField = new DiagramField(model, newSection, [
3434
- newSection.coords[0] + labelConfiguration.margin,
3435
- newSection.coords[1] + labelConfiguration.margin
3436
- ], newSection.width - labelConfiguration.margin * 2, newSection.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3802
+ newSection.coords[0] + getLeftMargin(labelConfiguration),
3803
+ newSection.coords[1] + getTopMargin(labelConfiguration)
3804
+ ], newSection.width -
3805
+ getLeftMargin(labelConfiguration) -
3806
+ getRightMargin(labelConfiguration), newSection.height -
3807
+ getTopMargin(labelConfiguration) -
3808
+ getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelConfiguration.fit);
3437
3809
  newField.text = section.label;
3438
3810
  newSection.label = newField;
3439
3811
  model.fields.add(newField);
@@ -3650,7 +4022,7 @@ class SetGeometryCollabAction {
3650
4022
  this.timestamp = timestamp;
3651
4023
  }
3652
4024
  do() {
3653
- const node = this.canvas.model.nodes.get(this.nodeId);
4025
+ const node = this.canvas.model.nodes.get(this.nodeId, true);
3654
4026
  if (node && timestampWins(this.timestamp, node.geometryTimestamp)) {
3655
4027
  node.setGeometry(this.to);
3656
4028
  // Re-fit the labels, in case their text has changed since `this.to` was measured.
@@ -3691,8 +4063,8 @@ class AddConnectionCollabAction {
3691
4063
  this.endId = endId;
3692
4064
  }
3693
4065
  do() {
3694
- const start = this.canvas.model.ports.get(this.startId);
3695
- const end = this.canvas.model.ports.get(this.endId);
4066
+ const start = this.canvas.model.ports.get(this.startId, true);
4067
+ const end = this.canvas.model.ports.get(this.endId, true);
3696
4068
  if (start && end) {
3697
4069
  this.canvas.model.connections.new(this.typeId, start, end, this.id);
3698
4070
  }
@@ -3723,7 +4095,7 @@ class EditFieldCollabAction {
3723
4095
  this.timestamp = timestamp;
3724
4096
  }
3725
4097
  do() {
3726
- const field = this.canvas.model.fields.get(this.fieldId);
4098
+ const field = this.canvas.model.fields.get(this.fieldId, true);
3727
4099
  if (field && timestampWins(this.timestamp, field.textTimestamp)) {
3728
4100
  field.text = this.to;
3729
4101
  field.textTimestamp = this.timestamp;
@@ -3758,8 +4130,8 @@ class UpdateValuesCollabAction {
3758
4130
  return this.canvas.model.valueSet;
3759
4131
  }
3760
4132
  else {
3761
- return (this.canvas.model.nodes.get(this.id) ||
3762
- this.canvas.model.connections.get(this.id))?.valueSet;
4133
+ return (this.canvas.model.nodes.get(this.id, true) ||
4134
+ this.canvas.model.connections.get(this.id, true))?.valueSet;
3763
4135
  }
3764
4136
  }
3765
4137
  do() {
@@ -3807,19 +4179,19 @@ class SetSelfRemovedCollabAction {
3807
4179
  }
3808
4180
  do() {
3809
4181
  for (const nodeId of this.nodeIds) {
3810
- this.doOne(this.canvas.model.nodes.get(nodeId));
4182
+ this.doOne(this.canvas.model.nodes.get(nodeId, true));
3811
4183
  }
3812
4184
  for (const sectionId of this.sectionIds) {
3813
- this.doOne(this.canvas.model.sections.get(sectionId));
4185
+ this.doOne(this.canvas.model.sections.get(sectionId, true));
3814
4186
  }
3815
4187
  for (const portId of this.portIds) {
3816
- this.doOne(this.canvas.model.ports.get(portId));
4188
+ this.doOne(this.canvas.model.ports.get(portId, true));
3817
4189
  }
3818
4190
  for (const connectionId of this.connectionIds) {
3819
- this.doOne(this.canvas.model.connections.get(connectionId));
4191
+ this.doOne(this.canvas.model.connections.get(connectionId, true));
3820
4192
  }
3821
4193
  for (const fieldId of this.fieldIds) {
3822
- this.doOne(this.canvas.model.fields.get(fieldId));
4194
+ this.doOne(this.canvas.model.fields.get(fieldId, true));
3823
4195
  }
3824
4196
  // update view
3825
4197
  this.canvas.updateNodesInView(...this.nodeIds);
@@ -3827,6 +4199,8 @@ class SetSelfRemovedCollabAction {
3827
4199
  this.canvas.updatePortsInView(...this.portIds);
3828
4200
  this.canvas.updateConnectionsInView(...this.connectionIds);
3829
4201
  this.canvas.updateFieldsInView(...this.fieldIds);
4202
+ // some of the nodes and sections may have decorators, so update them
4203
+ this.canvas.updateDecoratorsInView();
3830
4204
  }
3831
4205
  serialize() {
3832
4206
  return {
@@ -4472,13 +4846,13 @@ class AdjacencyLayout {
4472
4846
  }
4473
4847
  // arrange nodes
4474
4848
  const nodeArrangement = new Grid();
4475
- const nodesToBeArranged = [...model.nodes];
4849
+ const nodesToBeArranged = model.nodes.all();
4476
4850
  while (nodesToBeArranged.length > 0) {
4477
4851
  arrangeNode(nodesToBeArranged[0], nodeArrangement, [0, 0], nodesToBeArranged);
4478
4852
  }
4479
4853
  // place nodes according to arrangement
4480
- const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
4481
- const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
4854
+ const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
4855
+ const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
4482
4856
  const gapSize = (model.canvas?.gridSize || 0) * 2;
4483
4857
  for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
4484
4858
  for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
@@ -4518,7 +4892,7 @@ class BreadthAdjacencyLayout {
4518
4892
  }
4519
4893
  // arrange nodes
4520
4894
  const nodeArrangement = new Grid();
4521
- const nodesToBeArranged = [...model.nodes];
4895
+ const nodesToBeArranged = model.nodes.all();
4522
4896
  const nodeGridIndices = {};
4523
4897
  const firstNode = nodesToBeArranged[0];
4524
4898
  let currentNodeLevel = [firstNode];
@@ -4528,7 +4902,9 @@ class BreadthAdjacencyLayout {
4528
4902
  for (const nodeInThisLevel of currentNodeLevel) {
4529
4903
  nodeArrangement.set(nodeArrangement.getClosestEmptyCoordinate(nodeGridIndices[nodeInThisLevel.id]), nodeInThisLevel);
4530
4904
  removeIfExists(nodesToBeArranged, nodeInThisLevel);
4531
- const nodesAdjacentToThisNode = nodeInThisLevel.getAdjacentNodes();
4905
+ const nodesAdjacentToThisNode = nodeInThisLevel
4906
+ .getAdjacentNodes()
4907
+ .filter((n) => !n.removed);
4532
4908
  for (const adjacentNode of nodesAdjacentToThisNode) {
4533
4909
  if (nodesToBeArranged.includes(adjacentNode)) {
4534
4910
  nextNodeLevel.push(adjacentNode);
@@ -4548,8 +4924,8 @@ class BreadthAdjacencyLayout {
4548
4924
  }
4549
4925
  }
4550
4926
  // place nodes according to arrangement
4551
- const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
4552
- const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
4927
+ const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
4928
+ const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
4553
4929
  const gapSize = (model.canvas?.gridSize || 0) * 2;
4554
4930
  for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
4555
4931
  for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
@@ -4578,7 +4954,7 @@ class BreadthLayout {
4578
4954
  return model;
4579
4955
  }
4580
4956
  const gapSize = (model.canvas?.gridSize || 0) * 2;
4581
- let nodesToBeArranged = [...model.nodes];
4957
+ let nodesToBeArranged = model.nodes.all();
4582
4958
  // Arrange nodes by a breadth first search
4583
4959
  const firstNode = nodesToBeArranged[0];
4584
4960
  removeIfExists(nodesToBeArranged, firstNode);
@@ -4594,7 +4970,9 @@ class BreadthLayout {
4594
4970
  const lastRowOfNodes = nodeArrangement[nodeArrangement.length - 1];
4595
4971
  const nodesInNextRow = [];
4596
4972
  for (const nodeInLastRow of lastRowOfNodes) {
4597
- const nodesAdjacentToThisNode = nodeInLastRow.getAdjacentNodes();
4973
+ const nodesAdjacentToThisNode = nodeInLastRow
4974
+ .getAdjacentNodes()
4975
+ .filter((n) => !n.removed);
4598
4976
  for (const adjacentNode of nodesAdjacentToThisNode) {
4599
4977
  if (nodesToBeArranged.includes(adjacentNode)) {
4600
4978
  removeIfExists(nodesToBeArranged, adjacentNode);
@@ -4799,17 +5177,17 @@ class PriorityLayout {
4799
5177
  // nothing to arrange...
4800
5178
  return model;
4801
5179
  }
4802
- const maximumPriority = Math.max(...model.nodes.filter((n) => !n.removed).map((n) => n.getPriority()));
4803
- const minimumPriority = Math.min(...model.nodes.filter((n) => !n.removed).map((n) => n.getPriority()));
5180
+ const maximumPriority = Math.max(...model.nodes.map((n) => n.getPriority()));
5181
+ const minimumPriority = Math.min(...model.nodes.map((n) => n.getPriority()));
4804
5182
  if (maximumPriority === minimumPriority) {
4805
5183
  // if there's no disparity in priorities, just use breadth layout
4806
5184
  new BreadthLayout().apply(model);
4807
5185
  return model;
4808
5186
  }
4809
5187
  const gapSize = (model.canvas?.gridSize || 0) * 2;
4810
- const nodesToBeArranged = [...model.nodes];
5188
+ const nodesToBeArranged = model.nodes.all();
4811
5189
  const nodeArrangement = [];
4812
- const nodesWithMaximumPriorityToBeArranged = model.nodes.filter((n) => !n.removed && n.getPriority() >= maximumPriority);
5190
+ const nodesWithMaximumPriorityToBeArranged = model.nodes.filter((n) => n.getPriority() >= maximumPriority);
4813
5191
  const nodesWithMaximumPriority = [];
4814
5192
  if (nodesWithMaximumPriorityToBeArranged.length > 1) {
4815
5193
  // use bfs to sort nodes by distance to the first node
@@ -4825,7 +5203,9 @@ class PriorityLayout {
4825
5203
  nodesWithMaximumPriority.push(bfsNode);
4826
5204
  removeIfExists(nodesWithMaximumPriorityToBeArranged, bfsNode);
4827
5205
  }
4828
- const bfsAdjacentNodes = bfsNode.getAdjacentNodes();
5206
+ const bfsAdjacentNodes = bfsNode
5207
+ .getAdjacentNodes()
5208
+ .filter((n) => !n.removed);
4829
5209
  for (const bfsAdjacentNode of bfsAdjacentNodes) {
4830
5210
  if (!bfsExplored.includes(bfsAdjacentNode)) {
4831
5211
  bfsQueue.push(bfsAdjacentNode);
@@ -4865,7 +5245,9 @@ class PriorityLayout {
4865
5245
  break;
4866
5246
  }
4867
5247
  else {
4868
- const bfsAdjacentNodes = bfsNode.getAdjacentNodes();
5248
+ const bfsAdjacentNodes = bfsNode
5249
+ .getAdjacentNodes()
5250
+ .filter((n) => !n.removed);
4869
5251
  for (const bfsAdjacentNode of bfsAdjacentNodes) {
4870
5252
  if (!bfsExplored.includes(bfsAdjacentNode)) {
4871
5253
  bfsQueue.push(bfsAdjacentNode);
@@ -4908,8 +5290,8 @@ class TreeLayout {
4908
5290
  // nothing to arrange...
4909
5291
  return model;
4910
5292
  }
4911
- const maximumPriority = Math.max(...model.nodes.filter((n) => !n.removed).map((n) => n.getPriority()));
4912
- const minimumPriority = Math.min(...model.nodes.filter((n) => !n.removed).map((n) => n.getPriority()));
5293
+ const maximumPriority = Math.max(...model.nodes.map((n) => n.getPriority()));
5294
+ const minimumPriority = Math.min(...model.nodes.map((n) => n.getPriority()));
4913
5295
  if (maximumPriority === minimumPriority) {
4914
5296
  // if there's no disparity in priorities, just use breadth layout
4915
5297
  new BreadthLayout().apply(model);
@@ -4930,7 +5312,7 @@ class TreeLayout {
4930
5312
  branchArrangement.push([branch]);
4931
5313
  arrangeBranches(branch, branchArrangement, branchArrangement.length);
4932
5314
  }
4933
- const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
5315
+ const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
4934
5316
  let widthAccumulator = 0;
4935
5317
  for (let i = 0; i < branchArrangement.length; ++i) {
4936
5318
  let heightAccumulator = 0;
@@ -4951,7 +5333,9 @@ class TreeLayout {
4951
5333
  }
4952
5334
  }
4953
5335
  const populateBranches = (branch, nodesToBeArranged) => {
4954
- for (const adjacentNode of branch.node.getAdjacentNodes()) {
5336
+ for (const adjacentNode of branch.node
5337
+ .getAdjacentNodes()
5338
+ .filter((n) => !n.removed)) {
4955
5339
  const indexOfAdjacentNode = nodesToBeArranged.indexOf(adjacentNode);
4956
5340
  if (indexOfAdjacentNode >= 0) {
4957
5341
  nodesToBeArranged.splice(indexOfAdjacentNode, 1);
@@ -5260,12 +5644,12 @@ class DagaExporter {
5260
5644
  if (model.description) {
5261
5645
  result.description = model.description;
5262
5646
  }
5263
- for (const node of model.nodes) {
5647
+ for (const node of model.nodes.all(true)) {
5264
5648
  if (!includeCollabMeta && node.removed)
5265
5649
  continue;
5266
5650
  result.nodes.push(this.exportNode(node, includeCollabMeta));
5267
5651
  }
5268
- for (const connection of model.connections) {
5652
+ for (const connection of model.connections.all(true)) {
5269
5653
  if (!includeCollabMeta && connection.removed)
5270
5654
  continue;
5271
5655
  result.connections.push(this.exportConnection(connection, includeCollabMeta));
@@ -5424,11 +5808,12 @@ class DiagramEvent {
5424
5808
  * @public
5425
5809
  */
5426
5810
  class DiagramDecorator extends DiagramElement {
5427
- constructor(model, coords, width, height, priority, html, id) {
5811
+ constructor(model, rootElement, coords, width, height, priority, html, id) {
5428
5812
  if (model.objects.get(id) !== undefined) {
5429
5813
  throw new Error(`DiagramObject with id "${id}" already exists`);
5430
5814
  }
5431
5815
  super(model, id);
5816
+ this.rootElement = rootElement;
5432
5817
  this.coords = coords;
5433
5818
  this.width = width;
5434
5819
  this.height = height;
@@ -5441,7 +5826,8 @@ class DiagramDecorator extends DiagramElement {
5441
5826
  ?.select(`foreignObject#${this.id}`);
5442
5827
  }
5443
5828
  get removed() {
5444
- return this.selfRemoved;
5829
+ return (this.selfRemoved ||
5830
+ (this.rootElement !== undefined && this.rootElement.removed));
5445
5831
  }
5446
5832
  updateInView() {
5447
5833
  this.model.canvas?.updateDecoratorsInView(this.id);
@@ -5459,7 +5845,7 @@ class DiagramDecorator extends DiagramElement {
5459
5845
  return this.priority;
5460
5846
  }
5461
5847
  }
5462
- class DiagramDecoratorSet extends DiagramEntitySet {
5848
+ class DiagramDecoratorSet extends DiagramElementSet {
5463
5849
  /**
5464
5850
  * Instance a set of decorators for the given model. This method is used internally.
5465
5851
  * @private
@@ -5473,7 +5859,7 @@ class DiagramDecoratorSet extends DiagramEntitySet {
5473
5859
  * @private
5474
5860
  */
5475
5861
  new(rootElement, coords, width, height, priority, html, id) {
5476
- const decorator = new DiagramDecorator(this.model, coords, width, height, priority, html, id);
5862
+ const decorator = new DiagramDecorator(this.model, rootElement, coords, width, height, priority, html, id);
5477
5863
  super.add(decorator);
5478
5864
  decorator.updateInView();
5479
5865
  // add this port to its root element
@@ -5483,12 +5869,17 @@ class DiagramDecoratorSet extends DiagramEntitySet {
5483
5869
  return decorator;
5484
5870
  }
5485
5871
  remove(id) {
5486
- const object = this.get(id);
5487
- if (object) {
5872
+ const decorator = this.get(id);
5873
+ if (decorator) {
5874
+ // remove from root element
5875
+ if (decorator.rootElement instanceof DiagramNode ||
5876
+ decorator.rootElement instanceof DiagramSection) {
5877
+ removeIfExists(decorator.rootElement.decorators, decorator);
5878
+ }
5488
5879
  // remove from set of objects
5489
5880
  super.remove(id);
5490
5881
  // remove from canvas
5491
- object.updateInView();
5882
+ decorator.updateInView();
5492
5883
  }
5493
5884
  }
5494
5885
  }
@@ -5534,7 +5925,7 @@ class DiagramObject extends DiagramElement {
5534
5925
  return this.priority;
5535
5926
  }
5536
5927
  }
5537
- class DiagramObjectSet extends DiagramEntitySet {
5928
+ class DiagramObjectSet extends DiagramElementSet {
5538
5929
  /**
5539
5930
  * Instance a set of objects for the given model. This method is used internally.
5540
5931
  * @private
@@ -5641,6 +6032,7 @@ class DiagramModel {
5641
6032
  this.connections.clear();
5642
6033
  this.fields.clear();
5643
6034
  this.objects.clear();
6035
+ this.decorators.clear();
5644
6036
  this.valueSet.resetValues();
5645
6037
  this.canvas?.updateModelInView();
5646
6038
  }
@@ -5798,20 +6190,20 @@ class DiagramCanvas {
5798
6190
  if (event.ctrlKey && event.key === 'a') {
5799
6191
  event.preventDefault();
5800
6192
  // select all
5801
- for (const node of this.model.nodes.filter((n) => !n.removed)) {
6193
+ for (const node of this.model.nodes) {
5802
6194
  this.addToUserSelection(node);
5803
6195
  }
5804
- for (const connection of this.model.connections.filter((c) => !c.removed)) {
6196
+ for (const connection of this.model.connections) {
5805
6197
  this.addToUserSelection(connection);
5806
6198
  }
5807
6199
  }
5808
6200
  if (event.ctrlKey && event.key === 'i') {
5809
6201
  event.preventDefault();
5810
6202
  // invert selection
5811
- for (const node of this.model.nodes.filter((n) => !n.removed)) {
6203
+ for (const node of this.model.nodes) {
5812
6204
  this.toggleUserSelection(node);
5813
6205
  }
5814
- for (const connection of this.model.connections.filter((c) => !c.removed)) {
6206
+ for (const connection of this.model.connections) {
5815
6207
  this.toggleUserSelection(connection);
5816
6208
  }
5817
6209
  }
@@ -5839,13 +6231,45 @@ class DiagramCanvas {
5839
6231
  this.cancelAllUserActions();
5840
6232
  }
5841
6233
  if (event.ctrlKey && event.key === 'y') {
6234
+ event.preventDefault();
5842
6235
  // redo
5843
6236
  this.actionQueue.redo();
5844
6237
  }
5845
6238
  if (event.ctrlKey && event.key === 'z') {
6239
+ event.preventDefault();
5846
6240
  // undo
5847
6241
  this.actionQueue.undo();
5848
6242
  }
6243
+ if (event.key === '+') {
6244
+ event.preventDefault();
6245
+ // zoom in
6246
+ this.parentComponent.diagramButtons.zoomIn();
6247
+ }
6248
+ if (event.key === '-') {
6249
+ event.preventDefault();
6250
+ // zoom out
6251
+ this.parentComponent.diagramButtons.zoomOut();
6252
+ }
6253
+ if (event.key === Keys.ArrowLeft) {
6254
+ event.preventDefault();
6255
+ // move left, faster if we're zoomed out and slower if we're zoomed in
6256
+ this.translateBy(-100 / this.zoomTransform.k, 0);
6257
+ }
6258
+ if (event.key === Keys.ArrowRight) {
6259
+ event.preventDefault();
6260
+ // move right, faster if we're zoomed out and slower if we're zoomed in
6261
+ this.translateBy(100 / this.zoomTransform.k, 0);
6262
+ }
6263
+ if (event.key === Keys.ArrowDown) {
6264
+ event.preventDefault();
6265
+ // move down, faster if we're zoomed out and slower if we're zoomed in
6266
+ this.translateBy(0, -100 / this.zoomTransform.k);
6267
+ }
6268
+ if (event.key === Keys.ArrowUp) {
6269
+ event.preventDefault();
6270
+ // move up, faster if we're zoomed out and slower if we're zoomed in
6271
+ this.translateBy(0, 100 / this.zoomTransform.k);
6272
+ }
5849
6273
  });
5850
6274
  const canvasView = this.selectRoot()
5851
6275
  .append('g')
@@ -5968,13 +6392,14 @@ class DiagramCanvas {
5968
6392
  // if there are no nodes, we have nothing to do here
5969
6393
  if (this.model.nodes.length > 0) {
5970
6394
  const canvasViewBoundingBox = this.selectCanvasView().select('rect').node().getBBox();
5971
- const minimumX = Math.min(...this.model.nodes.all().map((n) => n.coords[0]));
5972
- const maximumX = Math.max(...this.model.nodes.all().map((n) => n.coords[0] + n.width));
6395
+ const nonRemovedNodes = this.model.nodes.all();
6396
+ const minimumX = Math.min(...nonRemovedNodes.map((n) => n.coords[0]));
6397
+ const maximumX = Math.max(...nonRemovedNodes.map((n) => n.coords[0] + n.width));
5973
6398
  const averageX = (minimumX + maximumX) / 2;
5974
6399
  const rangeX = maximumX - minimumX;
5975
6400
  const windowRangeX = canvasViewBoundingBox.width;
5976
- const minimumY = Math.min(...this.model.nodes.all().map((n) => n.coords[1]));
5977
- const maximumY = Math.max(...this.model.nodes.all().map((n) => n.coords[1] + n.height));
6401
+ const minimumY = Math.min(...nonRemovedNodes.map((n) => n.coords[1]));
6402
+ const maximumY = Math.max(...nonRemovedNodes.map((n) => n.coords[1] + n.height));
5978
6403
  const averageY = (minimumY + maximumY) / 2;
5979
6404
  const rangeY = maximumY - minimumY;
5980
6405
  const windowRangeY = canvasViewBoundingBox.height;
@@ -6070,10 +6495,9 @@ class DiagramCanvas {
6070
6495
  updateNodesInView(...ids) {
6071
6496
  let updateSelection = this.selectCanvasNodes()
6072
6497
  .selectAll('g.diagram-node')
6073
- .data(this.model.nodes.filter((e) => !e.removed &&
6074
- (this.priorityThreshold !== undefined
6075
- ? e.getPriority() >= this.priorityThreshold
6076
- : true)), (d) => d.id);
6498
+ .data(this.model.nodes.filter((e) => this.priorityThreshold !== undefined
6499
+ ? e.getPriority() >= this.priorityThreshold
6500
+ : true), (d) => d.id);
6077
6501
  const exitSelection = updateSelection.exit();
6078
6502
  const enterSelection = updateSelection
6079
6503
  .enter()
@@ -6609,10 +7033,9 @@ class DiagramCanvas {
6609
7033
  updateSectionsInView(...ids) {
6610
7034
  let updateSelection = this.selectCanvasSections()
6611
7035
  .selectAll('g.diagram-section')
6612
- .data(this.model.sections.filter((e) => !e.removed &&
6613
- (this.priorityThreshold !== undefined
6614
- ? e.getPriority() >= this.priorityThreshold
6615
- : true)), (d) => d.id);
7036
+ .data(this.model.sections.filter((e) => this.priorityThreshold !== undefined
7037
+ ? e.getPriority() >= this.priorityThreshold
7038
+ : true), (d) => d.id);
6616
7039
  const exitSelection = updateSelection.exit();
6617
7040
  const enterSelection = updateSelection
6618
7041
  .enter()
@@ -7167,10 +7590,9 @@ class DiagramCanvas {
7167
7590
  updatePortsInView(...ids) {
7168
7591
  let updateSelection = this.selectCanvasPorts()
7169
7592
  .selectAll('g.diagram-port')
7170
- .data(this.model.ports.filter((e) => !e.removed &&
7171
- (this.priorityThreshold !== undefined
7172
- ? e.getPriority() >= this.priorityThreshold
7173
- : true)), (d) => d.id);
7593
+ .data(this.model.ports.filter((e) => this.priorityThreshold !== undefined
7594
+ ? e.getPriority() >= this.priorityThreshold
7595
+ : true), (d) => d.id);
7174
7596
  const exitSelection = updateSelection.exit();
7175
7597
  const enterSelection = updateSelection
7176
7598
  .enter()
@@ -7273,7 +7695,7 @@ class DiagramCanvas {
7273
7695
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7274
7696
  let minDistanceFound = Number.POSITIVE_INFINITY;
7275
7697
  let closestPortFound = undefined;
7276
- for (const port of this.model.ports.filter((p) => !p.removed)) {
7698
+ for (const port of this.model.ports) {
7277
7699
  const distance = port.distanceTo(pointerCoords);
7278
7700
  if (distance < minDistanceFound) {
7279
7701
  minDistanceFound = distance;
@@ -7345,10 +7767,9 @@ class DiagramCanvas {
7345
7767
  .attr('opacity', (d) => (d.highlighted || d.selected ? 0.5 : 0));
7346
7768
  }
7347
7769
  updateConnectionsInView(...ids) {
7348
- const connectionList = this.model.connections.filter((e) => !e.removed &&
7349
- (this.priorityThreshold !== undefined
7350
- ? e.getPriority() >= this.priorityThreshold
7351
- : true));
7770
+ const connectionList = this.model.connections.filter((e) => this.priorityThreshold !== undefined
7771
+ ? e.getPriority() >= this.priorityThreshold
7772
+ : true);
7352
7773
  if (this.unfinishedConnection) {
7353
7774
  connectionList.push(this.unfinishedConnection);
7354
7775
  }
@@ -7452,10 +7873,9 @@ class DiagramCanvas {
7452
7873
  updateFieldsInView(...ids) {
7453
7874
  let updateSelection = this.selectCanvasFields()
7454
7875
  .selectAll('foreignObject.diagram-field')
7455
- .data(this.model.fields.filter((e) => !e.removed &&
7456
- (this.priorityThreshold !== undefined
7457
- ? e.getPriority() >= this.priorityThreshold
7458
- : true)), (d) => d.id);
7876
+ .data(this.model.fields.filter((e) => this.priorityThreshold !== undefined
7877
+ ? e.getPriority() >= this.priorityThreshold
7878
+ : true), (d) => d.id);
7459
7879
  const exitSelection = updateSelection.exit();
7460
7880
  const enterSelection = updateSelection
7461
7881
  .enter()
@@ -7629,10 +8049,9 @@ class DiagramCanvas {
7629
8049
  updateObjectsInView(...ids) {
7630
8050
  let updateSelection = this.selectCanvasObjects()
7631
8051
  .selectAll('foreignObject.diagram-object')
7632
- .data(this.model.objects.filter((e) => !e.removed &&
7633
- (this.priorityThreshold !== undefined
7634
- ? e.getPriority() >= this.priorityThreshold
7635
- : true)), (d) => d.id);
8052
+ .data(this.model.objects.filter((e) => this.priorityThreshold !== undefined
8053
+ ? e.getPriority() >= this.priorityThreshold
8054
+ : true), (d) => d.id);
7636
8055
  const exitSelection = updateSelection.exit();
7637
8056
  const enterSelection = updateSelection
7638
8057
  .enter()
@@ -7667,10 +8086,9 @@ class DiagramCanvas {
7667
8086
  updateDecoratorsInView(...ids) {
7668
8087
  let updateSelection = this.selectCanvasDecorators()
7669
8088
  .selectAll('foreignObject.diagram-decorator')
7670
- .data(this.model.decorators.filter((e) => !e.removed &&
7671
- (this.priorityThreshold !== undefined
7672
- ? e.getPriority() >= this.priorityThreshold
7673
- : true)), (d) => d.id);
8089
+ .data(this.model.decorators.filter((e) => this.priorityThreshold !== undefined
8090
+ ? e.getPriority() >= this.priorityThreshold
8091
+ : true), (d) => d.id);
7674
8092
  const exitSelection = updateSelection.exit();
7675
8093
  const enterSelection = updateSelection
7676
8094
  .enter()
@@ -7734,13 +8152,14 @@ class DiagramCanvas {
7734
8152
  const boundingWidth = !connection.startLabel
7735
8153
  ? 0
7736
8154
  : startLabelBoundingRect.width / this.zoomTransform.k +
7737
- labelConfiguration.padding * 2;
8155
+ getLeftPadding(labelConfiguration) +
8156
+ getRightPadding(labelConfiguration);
7738
8157
  const boundingHeight = !connection.startLabel
7739
8158
  ? 0
7740
8159
  : startLabelBoundingRect.height / this.zoomTransform.k +
7741
- labelConfiguration.padding * 2;
7742
- const pathStartLabelPoint = pathNode.getPointAtLength(labelConfiguration.margin +
7743
- Math.max(boundingWidth / 2, boundingHeight / 2));
8160
+ getTopPadding(labelConfiguration) +
8161
+ getBottomPadding(labelConfiguration);
8162
+ const pathStartLabelPoint = pathNode.getPointAtLength(Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
7744
8163
  connectionSelection
7745
8164
  .select('g.diagram-connection-start-label path')
7746
8165
  .attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight))
@@ -7774,11 +8193,13 @@ class DiagramCanvas {
7774
8193
  const boundingWidth = !connection.middleLabel
7775
8194
  ? 0
7776
8195
  : middleLabelBoundingRect.width / this.zoomTransform.k +
7777
- labelConfiguration.padding * 2;
8196
+ getLeftPadding(labelConfiguration) +
8197
+ getRightPadding(labelConfiguration);
7778
8198
  const boundingHeight = !connection.middleLabel
7779
8199
  ? 0
7780
8200
  : middleLabelBoundingRect.height / this.zoomTransform.k +
7781
- labelConfiguration.padding * 2;
8201
+ getTopPadding(labelConfiguration) +
8202
+ getBottomPadding(labelConfiguration);
7782
8203
  const pathMiddleLabelPoint = pathNode.getPointAtLength(pathLength / 2);
7783
8204
  connectionSelection
7784
8205
  .select('g.diagram-connection-middle-label path')
@@ -7813,14 +8234,15 @@ class DiagramCanvas {
7813
8234
  const boundingWidth = !connection.endLabel
7814
8235
  ? 0
7815
8236
  : endLabelBoundingRect.width / this.zoomTransform.k +
7816
- labelConfiguration.padding * 2;
8237
+ getLeftPadding(labelConfiguration) +
8238
+ getRightPadding(labelConfiguration);
7817
8239
  const boundingHeight = !connection.endLabel
7818
8240
  ? 0
7819
8241
  : endLabelBoundingRect.height / this.zoomTransform.k +
7820
- labelConfiguration.padding * 2;
8242
+ getTopPadding(labelConfiguration) +
8243
+ getBottomPadding(labelConfiguration);
7821
8244
  const pathEndLabelPoint = pathNode.getPointAtLength(pathLength -
7822
- labelConfiguration.margin -
7823
- Math.max(boundingWidth / 2, boundingHeight / 2));
8245
+ Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
7824
8246
  connectionSelection
7825
8247
  .select('g.diagram-connection-end-label path')
7826
8248
  .attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight))
@@ -7887,10 +8309,12 @@ class DiagramCanvas {
7887
8309
  if (field.rootElement instanceof DiagramNode && field.fit) {
7888
8310
  const fieldDimensions = this.minimumSizeOfField(field);
7889
8311
  let stretchX = fieldDimensions[0] +
7890
- 2 * (field.rootElement.type.label?.margin || 0) -
8312
+ getLeftMargin(field.rootElement.type.label) +
8313
+ getRightMargin(field.rootElement.type.label) -
7891
8314
  field.rootElement.width;
7892
8315
  let stretchY = fieldDimensions[1] +
7893
- 2 * (field.rootElement.type.label?.margin || 0) -
8316
+ getTopMargin(field.rootElement.type.label) +
8317
+ getBottomMargin(field.rootElement.type.label) -
7894
8318
  field.rootElement.height;
7895
8319
  if (this.snapToGrid) {
7896
8320
  stretchX = Math.ceil(stretchX / this.gridSize) * this.gridSize;
@@ -7931,10 +8355,12 @@ class DiagramCanvas {
7931
8355
  fieldDimensions[1] = minimumFieldHeight;
7932
8356
  }
7933
8357
  let stretchX = fieldDimensions[0] +
7934
- 2 * (field.rootElement?.getConfig()?.label?.margin || 0) -
8358
+ getLeftMargin(field.rootElement?.getConfig()?.label) +
8359
+ getRightMargin(field.rootElement?.getConfig()?.label) -
7935
8360
  field.rootElement.width;
7936
8361
  let stretchY = fieldDimensions[1] +
7937
- 2 * (field.rootElement?.getConfig()?.label?.margin || 0) -
8362
+ getTopMargin(field.rootElement?.getConfig()?.label) +
8363
+ getBottomMargin(field.rootElement?.getConfig()?.label) -
7938
8364
  field.rootElement.height;
7939
8365
  if (this.snapToGrid) {
7940
8366
  stretchX = Math.ceil(stretchX / this.gridSize) * this.gridSize;
@@ -9169,7 +9595,7 @@ class PaletteComponent {
9169
9595
  };
9170
9596
  thisComponent
9171
9597
  .append('text')
9172
- .attr('transform', `translate(${type.defaultWidth / 2},${type.defaultHeight / 2 + 5})`)
9598
+ .attr('transform', `translate(${(getLeftMargin(labelConfig) + type.defaultWidth) / 2},${(getTopMargin(labelConfig) + type.defaultHeight) / 2})`)
9173
9599
  .attr('x', 0)
9174
9600
  .attr('y', 0)
9175
9601
  .attr('font-size', `${labelConfig.fontSize}px`)
@@ -10527,5 +10953,5 @@ function now() {
10527
10953
  * Generated bundle index. Do not edit.
10528
10954
  */
10529
10955
 
10530
- export { ACTION_QUEUE_SIZE, ActionQueue, AddConnectionAction, AddNodeAction, AdjacencyLayout, BreadthAdjacencyLayout, BreadthLayout, CanvasProviderService, ClosedShape, CollabClient, CollapseButtonComponent, Corner, DagaConfigurationService, DagaExporter, DagaImporter, DagaModule, DiagramActions, DiagramButtonsComponent, DiagramCanvas, DiagramComponent, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramDecorator, DiagramDecoratorSet, DiagramEditorComponent, DiagramElement, DiagramEntitySet, DiagramEvent, DiagramField, DiagramFieldSet, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramObject, DiagramObjectSet, DiagramPort, DiagramPortSet, DiagramSection, DiagramSectionSet, EditFieldAction, ErrorsComponent, ForceLayout, HorizontalAlign, HorizontalLayout, LineShape, LineStyle, ObjectEditorComponent, PaletteComponent, PriorityLayout, Property, PropertyEditorComponent, PropertySet, RemoveAction, SetGeometryAction, Side, TextListEditorComponent, TextMapEditorComponent, TreeLayout, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, layouts };
10956
+ export { ACTION_QUEUE_SIZE, ActionQueue, AddConnectionAction, AddNodeAction, AdjacencyLayout, BreadthAdjacencyLayout, BreadthLayout, CanvasProviderService, ClosedShape, CollabClient, CollapseButtonComponent, Corner, DagaConfigurationService, DagaExporter, DagaImporter, DagaModule, DiagramActions, DiagramButtonsComponent, DiagramCanvas, DiagramComponent, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramDecorator, DiagramDecoratorSet, DiagramEditorComponent, DiagramElement, DiagramElementSet, DiagramEntitySet, DiagramEvent, DiagramField, DiagramFieldSet, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramObject, DiagramObjectSet, DiagramPort, DiagramPortSet, DiagramSection, DiagramSectionSet, EditFieldAction, ErrorsComponent, ForceLayout, HorizontalAlign, HorizontalLayout, LineShape, LineStyle, ObjectEditorComponent, PaletteComponent, PriorityLayout, Property, PropertyEditorComponent, PropertySet, RemoveAction, SetGeometryAction, Side, TextListEditorComponent, TextMapEditorComponent, TreeLayout, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, layouts };
10531
10957
  //# sourceMappingURL=metadev-daga.mjs.map