ngx-vflow 0.10.0 → 0.12.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/esm2022/lib/vflow/components/node/node.component.mjs +19 -14
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +32 -6
- package/esm2022/lib/vflow/directives/changes-controller.directive.mjs +14 -2
- package/esm2022/lib/vflow/directives/flow-size-controller.directive.mjs +3 -3
- package/esm2022/lib/vflow/directives/root-pointer.directive.mjs +21 -4
- package/esm2022/lib/vflow/directives/template.directive.mjs +12 -1
- package/esm2022/lib/vflow/interfaces/node.interface.mjs +13 -1
- package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +2 -0
- package/esm2022/lib/vflow/models/handle.model.mjs +22 -9
- package/esm2022/lib/vflow/models/node.model.mjs +91 -15
- package/esm2022/lib/vflow/public-components/resizable/resizable.component.mjs +265 -0
- package/esm2022/lib/vflow/services/draggable.service.mjs +12 -3
- package/esm2022/lib/vflow/services/handle.service.mjs +7 -2
- package/esm2022/lib/vflow/services/node-accessor.service.mjs +16 -0
- package/esm2022/lib/vflow/services/node-changes.service.mjs +6 -2
- package/esm2022/lib/vflow/services/node-rendering.service.mjs +12 -3
- package/esm2022/lib/vflow/types/node-change.type.mjs +1 -1
- package/esm2022/lib/vflow/utils/resizable.mjs +3 -3
- package/esm2022/lib/vflow/vflow.module.mjs +13 -5
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/ngx-vflow.mjs +565 -96
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/node/node.component.d.ts +5 -2
- package/lib/vflow/components/vflow/vflow.component.d.ts +10 -5
- package/lib/vflow/directives/changes-controller.directive.d.ts +5 -2
- package/lib/vflow/directives/root-pointer.directive.d.ts +24 -6
- package/lib/vflow/directives/space-point-context.directive.d.ts +5 -0
- package/lib/vflow/directives/template.directive.d.ts +5 -0
- package/lib/vflow/interfaces/node.interface.d.ts +42 -2
- package/lib/vflow/interfaces/optimization.interface.d.ts +3 -0
- package/lib/vflow/models/edge.model.d.ts +1 -17
- package/lib/vflow/models/handle.model.d.ts +2 -1
- package/lib/vflow/models/node.model.d.ts +22 -2
- package/lib/vflow/public-components/resizable/resizable.component.d.ts +39 -0
- package/lib/vflow/services/handle.service.d.ts +1 -1
- package/lib/vflow/services/node-accessor.service.d.ts +10 -0
- package/lib/vflow/services/node-changes.service.d.ts +8 -0
- package/lib/vflow/services/node-rendering.service.d.ts +1 -0
- package/lib/vflow/types/node-change.type.d.ts +8 -1
- package/lib/vflow/utils/resizable.d.ts +2 -1
- package/lib/vflow/vflow.module.d.ts +13 -12
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, EventEmitter, Output, DestroyRef, Input, runInInjectionContext, Injector, Component, ChangeDetectionStrategy, HostListener, ViewChild, HostBinding, ContentChild, NgModule } from '@angular/core';
|
|
4
|
+
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, EventEmitter, Output, DestroyRef, Input, runInInjectionContext, Injector, Component, ChangeDetectionStrategy, HostListener, ViewChild, NgZone, HostBinding, ContentChild, NgModule } from '@angular/core';
|
|
5
5
|
import { select } from 'd3-selection';
|
|
6
6
|
import { zoomIdentity, zoom } from 'd3-zoom';
|
|
7
7
|
import { Subject, tap, merge, observeOn, animationFrameScheduler, switchMap, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, fromEvent, share, Observable, startWith } from 'rxjs';
|
|
@@ -420,10 +420,19 @@ class DraggableService {
|
|
|
420
420
|
deltaY = model.point().y - event.y;
|
|
421
421
|
})
|
|
422
422
|
.on('drag', (event) => {
|
|
423
|
-
|
|
423
|
+
let point = {
|
|
424
424
|
x: round(event.x + deltaX),
|
|
425
425
|
y: round(event.y + deltaY)
|
|
426
|
-
}
|
|
426
|
+
};
|
|
427
|
+
const parent = model.parent();
|
|
428
|
+
// keep node in bounds of parent
|
|
429
|
+
if (parent) {
|
|
430
|
+
point.x = Math.min(parent.size().width - model.size().width, point.x);
|
|
431
|
+
point.x = Math.max(0, point.x);
|
|
432
|
+
point.y = Math.min(parent.size().height - model.size().height, point.y);
|
|
433
|
+
point.y = Math.max(0, point.y);
|
|
434
|
+
}
|
|
435
|
+
model.setPoint(point, true);
|
|
427
436
|
});
|
|
428
437
|
}
|
|
429
438
|
/**
|
|
@@ -487,6 +496,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
487
496
|
type: Directive,
|
|
488
497
|
args: [{ selector: 'ng-template[nodeHtml]' }]
|
|
489
498
|
}] });
|
|
499
|
+
class GroupNodeTemplateDirective {
|
|
500
|
+
constructor() {
|
|
501
|
+
this.templateRef = inject(TemplateRef);
|
|
502
|
+
}
|
|
503
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupNodeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
504
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupNodeTemplateDirective, selector: "ng-template[groupNode]", ngImport: i0 }); }
|
|
505
|
+
}
|
|
506
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupNodeTemplateDirective, decorators: [{
|
|
507
|
+
type: Directive,
|
|
508
|
+
args: [{ selector: 'ng-template[groupNode]' }]
|
|
509
|
+
}] });
|
|
490
510
|
class HandleTemplateDirective {
|
|
491
511
|
constructor() {
|
|
492
512
|
this.templateRef = inject(TemplateRef);
|
|
@@ -811,24 +831,54 @@ function isDefaultStaticNode(node) {
|
|
|
811
831
|
function isDefaultDynamicNode(node) {
|
|
812
832
|
return node.type === 'default';
|
|
813
833
|
}
|
|
834
|
+
function isDefaultStaticGroupNode(node) {
|
|
835
|
+
return node.type === 'default-group';
|
|
836
|
+
}
|
|
837
|
+
function isDefaultDynamicGroupNode(node) {
|
|
838
|
+
return node.type === 'default-group';
|
|
839
|
+
}
|
|
840
|
+
function isTemplateStaticGroupNode(node) {
|
|
841
|
+
return node.type === 'template-group';
|
|
842
|
+
}
|
|
843
|
+
function isTemplateDynamicGroupNode(node) {
|
|
844
|
+
return node.type === 'template-group';
|
|
845
|
+
}
|
|
814
846
|
|
|
847
|
+
// TODO bad naming around points
|
|
815
848
|
class NodeModel {
|
|
816
849
|
static { this.defaultWidth = 100; }
|
|
817
850
|
static { this.defaultHeight = 50; }
|
|
851
|
+
static { this.defaultColor = '#1b262c'; }
|
|
818
852
|
constructor(node) {
|
|
819
853
|
this.node = node;
|
|
820
854
|
this.flowSettingsService = inject(FlowSettingsService);
|
|
855
|
+
this.entitiesService = inject(FlowEntitiesService);
|
|
821
856
|
this.internalPoint = this.createInternalPointSignal();
|
|
822
857
|
this.throttledPoint$ = toObservable(this.internalPoint).pipe(observeOn(animationFrameScheduler));
|
|
823
|
-
this.
|
|
858
|
+
this.notThrottledPoint$ = new Subject();
|
|
859
|
+
this.point = toSignal(merge(this.throttledPoint$, this.notThrottledPoint$), {
|
|
824
860
|
initialValue: this.internalPoint()
|
|
825
861
|
});
|
|
826
862
|
this.point$ = this.throttledPoint$;
|
|
827
863
|
this.size = signal({ width: 0, height: 0 });
|
|
864
|
+
this.size$ = toObservable(this.size);
|
|
865
|
+
this.width = computed(() => this.size().width);
|
|
866
|
+
this.height = computed(() => this.size().height);
|
|
828
867
|
this.renderOrder = signal(0);
|
|
829
868
|
this.selected = signal(false);
|
|
830
869
|
this.selected$ = toObservable(this.selected);
|
|
831
|
-
this.
|
|
870
|
+
this.globalPoint = computed(() => {
|
|
871
|
+
let parent = this.parent();
|
|
872
|
+
let x = this.point().x;
|
|
873
|
+
let y = this.point().y;
|
|
874
|
+
while (parent !== null) {
|
|
875
|
+
x += parent.point().x;
|
|
876
|
+
y += parent.point().y;
|
|
877
|
+
parent = parent.parent();
|
|
878
|
+
}
|
|
879
|
+
return { x, y };
|
|
880
|
+
});
|
|
881
|
+
this.pointTransform = computed(() => `translate(${this.globalPoint().x}, ${this.globalPoint().y})`);
|
|
832
882
|
// Now source and handle positions derived from parent flow
|
|
833
883
|
this.sourcePosition = computed(() => this.flowSettingsService.handlePositions().source);
|
|
834
884
|
this.targetPosition = computed(() => this.flowSettingsService.handlePositions().target);
|
|
@@ -849,6 +899,13 @@ class NodeModel {
|
|
|
849
899
|
_selected: this.selected()
|
|
850
900
|
};
|
|
851
901
|
});
|
|
902
|
+
this.parent = computed(() => this.entitiesService.nodes().find(n => n.node.id === this.parentId()) ?? null);
|
|
903
|
+
this.children = computed(() => this.entitiesService.nodes().filter(n => n.parentId() === this.node.id));
|
|
904
|
+
this.color = signal(NodeModel.defaultColor);
|
|
905
|
+
this.resizable = signal(false);
|
|
906
|
+
this.resizing = signal(false);
|
|
907
|
+
this.resizerTemplate = signal(null);
|
|
908
|
+
this.parentId = signal(null);
|
|
852
909
|
if (isDefined(node.draggable)) {
|
|
853
910
|
if (isDynamicNode(node)) {
|
|
854
911
|
this.draggable = node.draggable;
|
|
@@ -857,29 +914,79 @@ class NodeModel {
|
|
|
857
914
|
this.draggable.set(node.draggable);
|
|
858
915
|
}
|
|
859
916
|
}
|
|
917
|
+
if (isDefined(node.parentId)) {
|
|
918
|
+
if (isDynamicNode(node)) {
|
|
919
|
+
this.parentId = node.parentId;
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
this.parentId.set(node.parentId);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
if (node.type === 'default-group' && node.color) {
|
|
926
|
+
if (isDynamicNode(node)) {
|
|
927
|
+
this.color = node.color;
|
|
928
|
+
}
|
|
929
|
+
else {
|
|
930
|
+
this.color.set(node.color);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
if (node.type === 'default-group' && node.resizable) {
|
|
934
|
+
if (isDynamicNode(node)) {
|
|
935
|
+
this.resizable = node.resizable;
|
|
936
|
+
}
|
|
937
|
+
else {
|
|
938
|
+
this.resizable.set(node.resizable);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
860
941
|
}
|
|
861
|
-
setPoint(point) {
|
|
862
|
-
|
|
942
|
+
setPoint(point, throttle) {
|
|
943
|
+
if (throttle) {
|
|
944
|
+
this.internalPoint.set(point);
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
this.notThrottledPoint$.next(point);
|
|
948
|
+
}
|
|
863
949
|
}
|
|
864
950
|
/**
|
|
865
951
|
* TODO find the way to implement this better
|
|
866
952
|
*/
|
|
867
953
|
linkDefaultNodeSizeWithModelSize() {
|
|
868
954
|
const node = this.node;
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
955
|
+
switch (node.type) {
|
|
956
|
+
case 'default':
|
|
957
|
+
case 'default-group':
|
|
958
|
+
case 'template-group': {
|
|
959
|
+
if (isDynamicNode(node)) {
|
|
960
|
+
effect(() => {
|
|
961
|
+
this.size.set({
|
|
962
|
+
width: node.width?.() ?? NodeModel.defaultWidth,
|
|
963
|
+
height: node.height?.() ?? NodeModel.defaultHeight,
|
|
964
|
+
});
|
|
965
|
+
}, { allowSignalWrites: true });
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
872
968
|
this.size.set({
|
|
873
|
-
width: node.width
|
|
874
|
-
height: node.height
|
|
969
|
+
width: node.width ?? NodeModel.defaultWidth,
|
|
970
|
+
height: node.height ?? NodeModel.defaultHeight
|
|
875
971
|
});
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
if (node.type === 'html-template' || this.isComponentType) {
|
|
976
|
+
if (isDynamicNode(node)) {
|
|
977
|
+
effect(() => {
|
|
978
|
+
if (node.width && node.height) {
|
|
979
|
+
this.size.set({
|
|
980
|
+
width: node.width(),
|
|
981
|
+
height: node.height(),
|
|
982
|
+
});
|
|
983
|
+
}
|
|
876
984
|
}, { allowSignalWrites: true });
|
|
877
985
|
}
|
|
878
986
|
else {
|
|
879
|
-
|
|
880
|
-
width: node.width
|
|
881
|
-
|
|
882
|
-
});
|
|
987
|
+
if (node.width && node.height) {
|
|
988
|
+
this.size.set({ width: node.width, height: node.height });
|
|
989
|
+
}
|
|
883
990
|
}
|
|
884
991
|
}
|
|
885
992
|
}
|
|
@@ -1142,6 +1249,10 @@ class NodesChangeService {
|
|
|
1142
1249
|
map(changedNode => [
|
|
1143
1250
|
{ type: 'position', id: changedNode.node.id, point: changedNode.point() }
|
|
1144
1251
|
]));
|
|
1252
|
+
this.nodeSizeChange$ = toObservable(this.entitiesService.nodes)
|
|
1253
|
+
.pipe(switchMap((nodes) => merge(...nodes.map(node => node.size$.pipe(skip(1), map(() => node))))), map(changedNode => [
|
|
1254
|
+
{ type: 'size', id: changedNode.node.id, size: changedNode.size() }
|
|
1255
|
+
]));
|
|
1145
1256
|
this.nodeAddChange$ = toObservable(this.entitiesService.nodes)
|
|
1146
1257
|
.pipe(pairwise(), map(([oldList, newList]) => newList.filter(node => !oldList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map(node => ({ type: 'add', id: node.node.id }))));
|
|
1147
1258
|
this.nodeRemoveChange$ = toObservable(this.entitiesService.nodes)
|
|
@@ -1150,7 +1261,7 @@ class NodesChangeService {
|
|
|
1150
1261
|
.pipe(switchMap((nodes) => merge(...nodes.map(node => node.selected$.pipe(distinctUntilChanged(), skip(1), map(() => node))))), map((changedNode) => [
|
|
1151
1262
|
{ type: 'select', id: changedNode.node.id, selected: changedNode.selected() }
|
|
1152
1263
|
]));
|
|
1153
|
-
this.changes$ = merge(this.nodesPositionChange$, this.nodeAddChange$, this.nodeRemoveChange$, this.nodeSelectedChange$).pipe(
|
|
1264
|
+
this.changes$ = merge(this.nodesPositionChange$, this.nodeSizeChange$, this.nodeAddChange$, this.nodeRemoveChange$, this.nodeSelectedChange$).pipe(
|
|
1154
1265
|
// this fixes a bug when on fire node event change,
|
|
1155
1266
|
// you can't get valid list of detached edges
|
|
1156
1267
|
observeOn(asyncScheduler, DELAY_FOR_SCHEDULER));
|
|
@@ -1217,6 +1328,9 @@ class ChangesControllerDirective {
|
|
|
1217
1328
|
this.onNodesChangePosition = this.nodeChangesOfType('position');
|
|
1218
1329
|
this.onNodesChangePositionSignle = this.singleChange(this.nodeChangesOfType('position'));
|
|
1219
1330
|
this.onNodesChangePositionMany = this.manyChanges(this.nodeChangesOfType('position'));
|
|
1331
|
+
this.onNodesChangeSize = this.nodeChangesOfType('size');
|
|
1332
|
+
this.onNodesChangeSizeSingle = this.singleChange(this.nodeChangesOfType('size'));
|
|
1333
|
+
this.onNodesChangeSizeMany = this.manyChanges(this.nodeChangesOfType('size'));
|
|
1220
1334
|
this.onNodesChangeAdd = this.nodeChangesOfType('add');
|
|
1221
1335
|
this.onNodesChangeAddSingle = this.singleChange(this.nodeChangesOfType('add'));
|
|
1222
1336
|
this.onNodesChangeAddMany = this.manyChanges(this.nodeChangesOfType('add'));
|
|
@@ -1256,7 +1370,7 @@ class ChangesControllerDirective {
|
|
|
1256
1370
|
return changes$.pipe(filter(changes => changes.length > 1));
|
|
1257
1371
|
}
|
|
1258
1372
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChangesControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1259
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ChangesControllerDirective, isStandalone: true, selector: "[changesController]", outputs: { onNodesChange: "onNodesChange", onNodesChangePosition: "onNodesChange.position", onNodesChangePositionSignle: "onNodesChange.position.single", onNodesChangePositionMany: "onNodesChange.position.many", onNodesChangeAdd: "onNodesChange.add", onNodesChangeAddSingle: "onNodesChange.add.single", onNodesChangeAddMany: "onNodesChange.add.many", onNodesChangeRemove: "onNodesChange.remove", onNodesChangeRemoveSingle: "onNodesChange.remove.single", onNodesChangeRemoveMany: "onNodesChange.remove.many", onNodesChangeSelect: "onNodesChange.select", onNodesChangeSelectSingle: "onNodesChange.select.single", onNodesChangeSelectMany: "onNodesChange.select.many", onEdgesChange: "onEdgesChange", onNodesChangeDetached: "onEdgesChange.detached", onNodesChangeDetachedSingle: "onEdgesChange.detached.single", onNodesChangeDetachedMany: "onEdgesChange.detached.many", onEdgesChangeAdd: "onEdgesChange.add", onEdgeChangeAddSingle: "onEdgesChange.add.single", onEdgeChangeAddMany: "onEdgesChange.add.many", onEdgeChangeRemove: "onEdgesChange.remove", onEdgeChangeRemoveSingle: "onEdgesChange.remove.single", onEdgeChangeRemoveMany: "onEdgesChange.remove.many", onEdgeChangeSelect: "onEdgesChange.select", onEdgeChangeSelectSingle: "onEdgesChange.select.single", onEdgeChangeSelectMany: "onEdgesChange.select.many" }, ngImport: i0 }); }
|
|
1373
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ChangesControllerDirective, isStandalone: true, selector: "[changesController]", outputs: { onNodesChange: "onNodesChange", onNodesChangePosition: "onNodesChange.position", onNodesChangePositionSignle: "onNodesChange.position.single", onNodesChangePositionMany: "onNodesChange.position.many", onNodesChangeSize: "onNodesChange.size", onNodesChangeSizeSingle: "onNodesChange.size.single", onNodesChangeSizeMany: "onNodesChange.size.many", onNodesChangeAdd: "onNodesChange.add", onNodesChangeAddSingle: "onNodesChange.add.single", onNodesChangeAddMany: "onNodesChange.add.many", onNodesChangeRemove: "onNodesChange.remove", onNodesChangeRemoveSingle: "onNodesChange.remove.single", onNodesChangeRemoveMany: "onNodesChange.remove.many", onNodesChangeSelect: "onNodesChange.select", onNodesChangeSelectSingle: "onNodesChange.select.single", onNodesChangeSelectMany: "onNodesChange.select.many", onEdgesChange: "onEdgesChange", onNodesChangeDetached: "onEdgesChange.detached", onNodesChangeDetachedSingle: "onEdgesChange.detached.single", onNodesChangeDetachedMany: "onEdgesChange.detached.many", onEdgesChangeAdd: "onEdgesChange.add", onEdgeChangeAddSingle: "onEdgesChange.add.single", onEdgeChangeAddMany: "onEdgesChange.add.many", onEdgeChangeRemove: "onEdgesChange.remove", onEdgeChangeRemoveSingle: "onEdgesChange.remove.single", onEdgeChangeRemoveMany: "onEdgesChange.remove.many", onEdgeChangeSelect: "onEdgesChange.select", onEdgeChangeSelectSingle: "onEdgesChange.select.single", onEdgeChangeSelectMany: "onEdgesChange.select.many" }, ngImport: i0 }); }
|
|
1260
1374
|
}
|
|
1261
1375
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChangesControllerDirective, decorators: [{
|
|
1262
1376
|
type: Directive,
|
|
@@ -1275,6 +1389,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1275
1389
|
}], onNodesChangePositionMany: [{
|
|
1276
1390
|
type: Output,
|
|
1277
1391
|
args: ['onNodesChange.position.many']
|
|
1392
|
+
}], onNodesChangeSize: [{
|
|
1393
|
+
type: Output,
|
|
1394
|
+
args: ['onNodesChange.size']
|
|
1395
|
+
}], onNodesChangeSizeSingle: [{
|
|
1396
|
+
type: Output,
|
|
1397
|
+
args: ['onNodesChange.size.single']
|
|
1398
|
+
}], onNodesChangeSizeMany: [{
|
|
1399
|
+
type: Output,
|
|
1400
|
+
args: ['onNodesChange.size.many']
|
|
1278
1401
|
}], onNodesChangeAdd: [{
|
|
1279
1402
|
type: Output,
|
|
1280
1403
|
args: ['onNodesChange.add']
|
|
@@ -1349,10 +1472,19 @@ class NodeRenderingService {
|
|
|
1349
1472
|
return this.flowEntitiesService.nodes()
|
|
1350
1473
|
.sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
1351
1474
|
});
|
|
1475
|
+
this.maxOrder = computed(() => {
|
|
1476
|
+
return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
|
|
1477
|
+
});
|
|
1352
1478
|
}
|
|
1353
1479
|
pullNode(node) {
|
|
1354
|
-
|
|
1355
|
-
|
|
1480
|
+
// TODO do not pull when the node is already on top
|
|
1481
|
+
// pull node
|
|
1482
|
+
node.renderOrder.set(this.maxOrder() + 1);
|
|
1483
|
+
// pull children
|
|
1484
|
+
this.flowEntitiesService
|
|
1485
|
+
.nodes()
|
|
1486
|
+
.filter(n => n.parent() === node)
|
|
1487
|
+
.forEach(n => this.pullNode(n));
|
|
1356
1488
|
}
|
|
1357
1489
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1358
1490
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeRenderingService }); }
|
|
@@ -1365,25 +1497,42 @@ class RootPointerDirective {
|
|
|
1365
1497
|
constructor() {
|
|
1366
1498
|
this.host = inject(ElementRef).nativeElement;
|
|
1367
1499
|
this.initialTouch$ = new Subject();
|
|
1500
|
+
this.prevTouchEvent = null;
|
|
1368
1501
|
// TODO: do not emit if mouse not down
|
|
1369
1502
|
this.mouseMovement$ = fromEvent(this.host, 'mousemove').pipe(map(event => ({
|
|
1370
1503
|
x: event.clientX,
|
|
1371
1504
|
y: event.clientY,
|
|
1505
|
+
movementX: event.movementX,
|
|
1506
|
+
movementY: event.movementY,
|
|
1507
|
+
target: event.target,
|
|
1372
1508
|
originalEvent: event
|
|
1373
1509
|
})), observeOn(animationFrameScheduler), share());
|
|
1374
1510
|
this.touchMovement$ = merge(this.initialTouch$, fromEvent(this.host, 'touchmove')).pipe(tap((event) => event.preventDefault()), map((originalEvent) => {
|
|
1375
1511
|
const x = originalEvent.touches[0]?.clientX ?? 0;
|
|
1376
1512
|
const y = originalEvent.touches[0]?.clientY ?? 0;
|
|
1513
|
+
const movementX = this.prevTouchEvent
|
|
1514
|
+
? originalEvent.touches[0].pageX - this.prevTouchEvent.touches[0].pageX
|
|
1515
|
+
: 0;
|
|
1516
|
+
const movementY = this.prevTouchEvent
|
|
1517
|
+
? originalEvent.touches[0].pageY - this.prevTouchEvent.touches[0].pageY
|
|
1518
|
+
: 0;
|
|
1377
1519
|
const target = document.elementFromPoint(x, y);
|
|
1378
|
-
return { x, y, target, originalEvent };
|
|
1379
|
-
}), observeOn(animationFrameScheduler), share());
|
|
1520
|
+
return { x, y, movementX, movementY, target, originalEvent };
|
|
1521
|
+
}), tap((event) => this.prevTouchEvent = event.originalEvent), observeOn(animationFrameScheduler), share());
|
|
1522
|
+
this.pointerMovement$ = merge(this.mouseMovement$, this.touchMovement$);
|
|
1380
1523
|
this.touchEnd$ = fromEvent(this.host, 'touchend').pipe(map((originalEvent) => {
|
|
1381
1524
|
const x = originalEvent.changedTouches[0]?.clientX ?? 0;
|
|
1382
1525
|
const y = originalEvent.changedTouches[0]?.clientY ?? 0;
|
|
1383
1526
|
const target = document.elementFromPoint(x, y);
|
|
1384
1527
|
return { x, y, target, originalEvent };
|
|
1528
|
+
}), tap(() => this.prevTouchEvent = null), share());
|
|
1529
|
+
this.mouseUp$ = fromEvent(this.host, 'mouseup').pipe(map((originalEvent) => {
|
|
1530
|
+
const x = originalEvent.clientX;
|
|
1531
|
+
const y = originalEvent.clientY;
|
|
1532
|
+
const target = originalEvent.target;
|
|
1533
|
+
return { x, y, target, originalEvent };
|
|
1385
1534
|
}), share());
|
|
1386
|
-
this.
|
|
1535
|
+
this.documentPointerEnd$ = merge(fromEvent(document, 'mouseup'), fromEvent(document, 'touchend')).pipe(share());
|
|
1387
1536
|
}
|
|
1388
1537
|
/**
|
|
1389
1538
|
* We should know when user started a touch in order to not
|
|
@@ -1434,6 +1583,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1434
1583
|
args: [{ selector: 'g[spacePointContext]' }]
|
|
1435
1584
|
}] });
|
|
1436
1585
|
|
|
1586
|
+
function Microtask(target, key, descriptor) {
|
|
1587
|
+
const originalMethod = descriptor.value;
|
|
1588
|
+
descriptor.value = function (...args) {
|
|
1589
|
+
queueMicrotask(() => {
|
|
1590
|
+
originalMethod?.apply(this, args);
|
|
1591
|
+
});
|
|
1592
|
+
};
|
|
1593
|
+
// Return the modified descriptor
|
|
1594
|
+
return descriptor;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1437
1597
|
class HandleService {
|
|
1438
1598
|
constructor() {
|
|
1439
1599
|
this.node = signal(null);
|
|
@@ -1453,14 +1613,17 @@ class HandleService {
|
|
|
1453
1613
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1454
1614
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService }); }
|
|
1455
1615
|
}
|
|
1616
|
+
__decorate([
|
|
1617
|
+
Microtask // TODO fixes rendering of handle for group node
|
|
1618
|
+
], HandleService.prototype, "createHandle", null);
|
|
1456
1619
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService, decorators: [{
|
|
1457
1620
|
type: Injectable
|
|
1458
|
-
}] });
|
|
1621
|
+
}], propDecorators: { createHandle: [] } });
|
|
1459
1622
|
|
|
1460
|
-
function resizable(elems) {
|
|
1623
|
+
function resizable(elems, zone) {
|
|
1461
1624
|
return new Observable((subscriber) => {
|
|
1462
1625
|
let ro = new ResizeObserver((entries) => {
|
|
1463
|
-
subscriber.next(entries);
|
|
1626
|
+
zone.run(() => subscriber.next(entries));
|
|
1464
1627
|
});
|
|
1465
1628
|
elems.forEach(e => ro.observe(e));
|
|
1466
1629
|
return () => ro.disconnect();
|
|
@@ -1484,16 +1647,19 @@ const implementsWithInjector = (instance) => {
|
|
|
1484
1647
|
return 'injector' in instance && 'get' in instance.injector;
|
|
1485
1648
|
};
|
|
1486
1649
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1650
|
+
/**
|
|
1651
|
+
* Service to fix cyclic dependency between node and resizable component
|
|
1652
|
+
*/
|
|
1653
|
+
class NodeAccessorService {
|
|
1654
|
+
constructor() {
|
|
1655
|
+
this.model = signal(null);
|
|
1656
|
+
}
|
|
1657
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1658
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService }); }
|
|
1496
1659
|
}
|
|
1660
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService, decorators: [{
|
|
1661
|
+
type: Injectable
|
|
1662
|
+
}] });
|
|
1497
1663
|
|
|
1498
1664
|
class HandleModel {
|
|
1499
1665
|
constructor(rawHandle, parentNode) {
|
|
@@ -1538,21 +1704,22 @@ class HandleModel {
|
|
|
1538
1704
|
});
|
|
1539
1705
|
this.pointAbsolute = computed(() => {
|
|
1540
1706
|
return {
|
|
1541
|
-
x: this.parentNode.
|
|
1542
|
-
y: this.parentNode.
|
|
1707
|
+
x: this.parentNode.globalPoint().x + this.offset().x + this.sizeOffset().x,
|
|
1708
|
+
y: this.parentNode.globalPoint().y + this.offset().y + this.sizeOffset().y,
|
|
1543
1709
|
};
|
|
1544
1710
|
});
|
|
1545
1711
|
this.state = signal('idle');
|
|
1546
1712
|
this.updateParentSizeAndPosition$ = new Subject();
|
|
1547
|
-
this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
|
|
1548
|
-
width: this.parentReference.offsetWidth,
|
|
1549
|
-
height: this.parentReference.offsetHeight
|
|
1550
|
-
}))), {
|
|
1713
|
+
this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
|
|
1551
1714
|
initialValue: { width: 0, height: 0 }
|
|
1552
1715
|
});
|
|
1553
1716
|
this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
|
|
1554
|
-
x: this.parentReference
|
|
1555
|
-
|
|
1717
|
+
x: this.parentReference instanceof HTMLElement
|
|
1718
|
+
? this.parentReference.offsetLeft
|
|
1719
|
+
: 0,
|
|
1720
|
+
y: this.parentReference instanceof HTMLElement
|
|
1721
|
+
? this.parentReference.offsetTop
|
|
1722
|
+
: 0 // for now just 0 for group nodes
|
|
1556
1723
|
}))), {
|
|
1557
1724
|
initialValue: { x: 0, y: 0 }
|
|
1558
1725
|
});
|
|
@@ -1568,6 +1735,18 @@ class HandleModel {
|
|
|
1568
1735
|
updateParent() {
|
|
1569
1736
|
this.updateParentSizeAndPosition$.next();
|
|
1570
1737
|
}
|
|
1738
|
+
getParentSize() {
|
|
1739
|
+
if (this.parentReference instanceof HTMLElement) {
|
|
1740
|
+
return {
|
|
1741
|
+
width: this.parentReference.offsetWidth,
|
|
1742
|
+
height: this.parentReference.offsetHeight
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
else if (this.parentReference instanceof SVGGraphicsElement) {
|
|
1746
|
+
return this.parentReference.getBBox();
|
|
1747
|
+
}
|
|
1748
|
+
return { width: 0, height: 0 };
|
|
1749
|
+
}
|
|
1571
1750
|
}
|
|
1572
1751
|
|
|
1573
1752
|
class HandleComponent {
|
|
@@ -1611,42 +1790,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1611
1790
|
type: Input
|
|
1612
1791
|
}], ngOnInit: [] } });
|
|
1613
1792
|
|
|
1614
|
-
class HandleSizeControllerDirective {
|
|
1615
|
-
constructor() {
|
|
1616
|
-
this.handleWrapper = inject(ElementRef);
|
|
1617
|
-
}
|
|
1618
|
-
ngAfterViewInit() {
|
|
1619
|
-
const element = this.handleWrapper.nativeElement;
|
|
1620
|
-
const rect = element.getBBox();
|
|
1621
|
-
const stroke = getChildStrokeWidth(element);
|
|
1622
|
-
this.handleModel.size.set({
|
|
1623
|
-
width: rect.width + stroke,
|
|
1624
|
-
height: rect.height + stroke
|
|
1625
|
-
});
|
|
1626
|
-
}
|
|
1627
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1628
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: { handleModel: ["handleSizeController", "handleModel"] }, ngImport: i0 }); }
|
|
1629
|
-
}
|
|
1630
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
|
|
1631
|
-
type: Directive,
|
|
1632
|
-
args: [{ selector: '[handleSizeController]' }]
|
|
1633
|
-
}], propDecorators: { handleModel: [{
|
|
1634
|
-
type: Input,
|
|
1635
|
-
args: [{ required: true, alias: 'handleSizeController' }]
|
|
1636
|
-
}] } });
|
|
1637
|
-
function getChildStrokeWidth(element) {
|
|
1638
|
-
const child = element.firstElementChild;
|
|
1639
|
-
if (child) {
|
|
1640
|
-
const stroke = getComputedStyle(child).strokeWidth;
|
|
1641
|
-
const strokeAsNumber = Number(stroke.replace('px', ''));
|
|
1642
|
-
if (isNaN(strokeAsNumber)) {
|
|
1643
|
-
return 0;
|
|
1644
|
-
}
|
|
1645
|
-
return strokeAsNumber;
|
|
1646
|
-
}
|
|
1647
|
-
return 0;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
1793
|
class PointerDirective {
|
|
1651
1794
|
constructor() {
|
|
1652
1795
|
this.hostElement = inject(ElementRef).nativeElement;
|
|
@@ -1726,6 +1869,295 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1726
1869
|
args: ['mouseout', ['$event']]
|
|
1727
1870
|
}] } });
|
|
1728
1871
|
|
|
1872
|
+
class ResizableComponent {
|
|
1873
|
+
constructor() {
|
|
1874
|
+
this.nodeAccessor = inject(NodeAccessorService);
|
|
1875
|
+
this.rootPointer = inject(RootPointerDirective);
|
|
1876
|
+
this.viewportService = inject(ViewportService);
|
|
1877
|
+
this.hostRef = inject(ElementRef);
|
|
1878
|
+
this.resizerColor = '#2e414c';
|
|
1879
|
+
this.gap = 1.5;
|
|
1880
|
+
this.lineGap = 3;
|
|
1881
|
+
this.handleSize = 6;
|
|
1882
|
+
this.resizeSide = null;
|
|
1883
|
+
this.zoom = computed(() => this.viewportService.readableViewport().zoom ?? 0);
|
|
1884
|
+
this.minWidth = 0;
|
|
1885
|
+
this.minHeight = 0;
|
|
1886
|
+
// TODO: allow reszie beside the flow
|
|
1887
|
+
this.resizeOnGlobalMouseMove = this.rootPointer.pointerMovement$
|
|
1888
|
+
.pipe(filter(() => this.resizeSide !== null), tap((event) => this.resize(event)), takeUntilDestroyed())
|
|
1889
|
+
.subscribe();
|
|
1890
|
+
this.endResizeOnGlobalMouseUp = this.rootPointer.documentPointerEnd$
|
|
1891
|
+
.pipe(tap(() => this.endResize()), takeUntilDestroyed())
|
|
1892
|
+
.subscribe();
|
|
1893
|
+
}
|
|
1894
|
+
set resizable(value) {
|
|
1895
|
+
if (typeof value === 'boolean') {
|
|
1896
|
+
this.model.resizable.set(value);
|
|
1897
|
+
}
|
|
1898
|
+
else {
|
|
1899
|
+
this.model.resizable.set(true);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
get model() {
|
|
1903
|
+
return this.nodeAccessor.model();
|
|
1904
|
+
}
|
|
1905
|
+
ngOnInit() {
|
|
1906
|
+
this.model.resizerTemplate.set(this.resizer);
|
|
1907
|
+
}
|
|
1908
|
+
ngAfterViewInit() {
|
|
1909
|
+
this.minWidth = +getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
|
|
1910
|
+
this.minHeight = +getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
|
|
1911
|
+
}
|
|
1912
|
+
startResize(side, event) {
|
|
1913
|
+
event.stopPropagation();
|
|
1914
|
+
this.resizeSide = side;
|
|
1915
|
+
this.model.resizing.set(true);
|
|
1916
|
+
}
|
|
1917
|
+
resize({ movementX, movementY }) {
|
|
1918
|
+
const offsetX = round(movementX / this.zoom());
|
|
1919
|
+
const offsetY = round(movementY / this.zoom());
|
|
1920
|
+
switch (this.resizeSide) {
|
|
1921
|
+
case 'left':
|
|
1922
|
+
let x = this.model.point().x + offsetX;
|
|
1923
|
+
x = Math.max(x, this.getMinX());
|
|
1924
|
+
x = Math.min(x, this.getMaxX());
|
|
1925
|
+
// TODO this fixes increasing width when current node hits the parent
|
|
1926
|
+
if (x === this.getMinX() || x === this.getMaxX()) {
|
|
1927
|
+
return;
|
|
1928
|
+
}
|
|
1929
|
+
this.model.setPoint({ x, y: this.model.point().y }, false);
|
|
1930
|
+
this.model.size.update(({ height, width }) => {
|
|
1931
|
+
width -= offsetX;
|
|
1932
|
+
width = Math.max(width, this.minWidth);
|
|
1933
|
+
width = Math.min(width, this.getMaxWidth());
|
|
1934
|
+
return { height, width: width };
|
|
1935
|
+
});
|
|
1936
|
+
return;
|
|
1937
|
+
case 'right':
|
|
1938
|
+
this.model.size.update(({ height, width }) => {
|
|
1939
|
+
width += offsetX;
|
|
1940
|
+
width = Math.max(width, this.minWidth);
|
|
1941
|
+
width = Math.min(width, this.getMaxWidth());
|
|
1942
|
+
const bounds = getNodesBounds(this.model.children());
|
|
1943
|
+
width = Math.max(width, bounds.x + bounds.width);
|
|
1944
|
+
return { height, width };
|
|
1945
|
+
});
|
|
1946
|
+
return;
|
|
1947
|
+
case 'top':
|
|
1948
|
+
let y = this.model.point().y + offsetY;
|
|
1949
|
+
y = Math.max(y, this.getMinY());
|
|
1950
|
+
y = Math.min(y, this.getMaxY());
|
|
1951
|
+
if (y === this.getMinY() || y === this.getMaxY()) {
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
this.model.setPoint({ x: this.model.point().x, y }, false);
|
|
1955
|
+
this.model.size.update(({ height, width }) => {
|
|
1956
|
+
height -= offsetY;
|
|
1957
|
+
height = Math.max(height, this.minHeight);
|
|
1958
|
+
height = Math.min(height, this.getMaxHeight());
|
|
1959
|
+
return { width, height };
|
|
1960
|
+
});
|
|
1961
|
+
return;
|
|
1962
|
+
case 'bottom':
|
|
1963
|
+
this.model.size.update(({ height, width }) => {
|
|
1964
|
+
height += offsetY;
|
|
1965
|
+
height = Math.max(height, this.minHeight);
|
|
1966
|
+
height = Math.min(height, this.getMaxHeight());
|
|
1967
|
+
const bounds = getNodesBounds(this.model.children());
|
|
1968
|
+
height = Math.max(height, bounds.y + bounds.height);
|
|
1969
|
+
return { width, height };
|
|
1970
|
+
});
|
|
1971
|
+
return;
|
|
1972
|
+
case 'top-left': {
|
|
1973
|
+
let x = this.model.point().x + offsetX;
|
|
1974
|
+
x = Math.max(x, this.getMinX());
|
|
1975
|
+
x = Math.min(x, this.getMaxX());
|
|
1976
|
+
let y = this.model.point().y + offsetY;
|
|
1977
|
+
y = Math.max(y, this.getMinY());
|
|
1978
|
+
y = Math.min(y, this.getMaxY());
|
|
1979
|
+
if (x === this.getMinX() || y === this.getMinY() ||
|
|
1980
|
+
x === this.getMaxX() || y === this.getMaxY()) {
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
this.model.setPoint({ x, y }, false);
|
|
1984
|
+
this.model.size.update(({ height, width }) => {
|
|
1985
|
+
width -= offsetX;
|
|
1986
|
+
width = Math.max(width, this.minWidth);
|
|
1987
|
+
width = Math.min(width, this.getMaxWidth());
|
|
1988
|
+
height -= offsetY;
|
|
1989
|
+
height = Math.max(height, this.minHeight);
|
|
1990
|
+
height = Math.min(height, this.getMaxHeight());
|
|
1991
|
+
return { height, width };
|
|
1992
|
+
});
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
case 'top-right': {
|
|
1996
|
+
let y = this.model.point().y + offsetY;
|
|
1997
|
+
y = Math.max(y, this.getMinY());
|
|
1998
|
+
y = Math.min(y, this.getMaxY());
|
|
1999
|
+
if (y === this.getMinX() || y === this.getMaxY()) {
|
|
2000
|
+
return;
|
|
2001
|
+
}
|
|
2002
|
+
this.model.setPoint({ x: this.model.point().x, y }, false);
|
|
2003
|
+
this.model.size.update(({ height, width }) => {
|
|
2004
|
+
const bounds = getNodesBounds(this.model.children());
|
|
2005
|
+
width += offsetX;
|
|
2006
|
+
width = Math.max(width, this.minWidth);
|
|
2007
|
+
width = Math.min(width, this.getMaxWidth());
|
|
2008
|
+
width = Math.max(width, bounds.x + bounds.width);
|
|
2009
|
+
height -= offsetY;
|
|
2010
|
+
height = Math.max(height, this.minHeight);
|
|
2011
|
+
height = Math.min(height, this.getMaxHeight());
|
|
2012
|
+
return { height, width };
|
|
2013
|
+
});
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
2016
|
+
case 'bottom-left': {
|
|
2017
|
+
let x = this.model.point().x + offsetX;
|
|
2018
|
+
x = Math.max(x, this.getMinX());
|
|
2019
|
+
x = Math.min(x, this.getMaxX());
|
|
2020
|
+
if (x === this.getMinX() || x === this.getMaxX()) {
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
this.model.setPoint({ x, y: this.model.point().y }, false);
|
|
2024
|
+
this.model.size.update(({ height, width }) => {
|
|
2025
|
+
width -= offsetX;
|
|
2026
|
+
width = Math.max(width, this.minWidth);
|
|
2027
|
+
width = Math.min(width, this.getMaxWidth());
|
|
2028
|
+
height += offsetY;
|
|
2029
|
+
height = Math.max(height, this.minHeight);
|
|
2030
|
+
height = Math.min(height, this.getMaxHeight());
|
|
2031
|
+
const bounds = getNodesBounds(this.model.children());
|
|
2032
|
+
height = Math.max(height, bounds.y + bounds.height);
|
|
2033
|
+
return { height, width };
|
|
2034
|
+
});
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
case 'bottom-right': {
|
|
2038
|
+
this.model.size.update(({ height, width }) => {
|
|
2039
|
+
const bounds = getNodesBounds(this.model.children());
|
|
2040
|
+
width += offsetX;
|
|
2041
|
+
width = Math.max(width, this.minWidth);
|
|
2042
|
+
width = Math.min(width, this.getMaxWidth());
|
|
2043
|
+
width = Math.max(width, bounds.x + bounds.width);
|
|
2044
|
+
height += offsetY;
|
|
2045
|
+
height = Math.max(height, this.minHeight);
|
|
2046
|
+
height = Math.min(height, this.getMaxHeight());
|
|
2047
|
+
height = Math.max(height, bounds.y + bounds.height);
|
|
2048
|
+
return { height, width };
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
endResize() {
|
|
2054
|
+
this.resizeSide = null;
|
|
2055
|
+
this.model.resizing.set(false);
|
|
2056
|
+
}
|
|
2057
|
+
getMaxWidth() {
|
|
2058
|
+
const parent = this.model.parent();
|
|
2059
|
+
if (parent) {
|
|
2060
|
+
return parent.size().width - this.model.point().x;
|
|
2061
|
+
}
|
|
2062
|
+
return Infinity;
|
|
2063
|
+
}
|
|
2064
|
+
getMaxHeight() {
|
|
2065
|
+
const parent = this.model.parent();
|
|
2066
|
+
if (parent) {
|
|
2067
|
+
return parent.size().height - this.model.point().y;
|
|
2068
|
+
}
|
|
2069
|
+
return Infinity;
|
|
2070
|
+
}
|
|
2071
|
+
getMinX() {
|
|
2072
|
+
const parent = this.model.parent();
|
|
2073
|
+
if (parent) {
|
|
2074
|
+
return 0;
|
|
2075
|
+
}
|
|
2076
|
+
return -Infinity;
|
|
2077
|
+
}
|
|
2078
|
+
getMinY() {
|
|
2079
|
+
const parent = this.model.parent();
|
|
2080
|
+
if (parent) {
|
|
2081
|
+
return 0;
|
|
2082
|
+
}
|
|
2083
|
+
return -Infinity;
|
|
2084
|
+
}
|
|
2085
|
+
getMaxX() {
|
|
2086
|
+
const x = this.model.point().x;
|
|
2087
|
+
const width = this.model.size().width;
|
|
2088
|
+
const children = this.model.children();
|
|
2089
|
+
if (children) {
|
|
2090
|
+
const bounds = getNodesBounds(children);
|
|
2091
|
+
return x + (bounds.x + bounds.width) >= x + width ? x : (width - this.minWidth) + x;
|
|
2092
|
+
}
|
|
2093
|
+
return (width - this.minWidth) + x;
|
|
2094
|
+
}
|
|
2095
|
+
getMaxY() {
|
|
2096
|
+
const y = this.model.point().y;
|
|
2097
|
+
const height = this.model.size().height;
|
|
2098
|
+
const children = this.model.children();
|
|
2099
|
+
if (children) {
|
|
2100
|
+
const bounds = getNodesBounds(children);
|
|
2101
|
+
return y + (bounds.y + bounds.height) >= y + height ? y : (height - this.minHeight) + y;
|
|
2102
|
+
}
|
|
2103
|
+
return (height - this.minHeight) + y;
|
|
2104
|
+
}
|
|
2105
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2106
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ResizableComponent, selector: "[resizable]", inputs: { resizable: "resizable", resizerColor: "resizerColor", gap: "gap" }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }] }); }
|
|
2107
|
+
}
|
|
2108
|
+
__decorate([
|
|
2109
|
+
Microtask
|
|
2110
|
+
], ResizableComponent.prototype, "ngAfterViewInit", null);
|
|
2111
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ResizableComponent, decorators: [{
|
|
2112
|
+
type: Component,
|
|
2113
|
+
args: [{ selector: '[resizable]', template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
|
|
2114
|
+
}], propDecorators: { resizable: [{
|
|
2115
|
+
type: Input
|
|
2116
|
+
}], resizerColor: [{
|
|
2117
|
+
type: Input
|
|
2118
|
+
}], gap: [{
|
|
2119
|
+
type: Input
|
|
2120
|
+
}], resizer: [{
|
|
2121
|
+
type: ViewChild,
|
|
2122
|
+
args: ['resizer', { static: true }]
|
|
2123
|
+
}], ngAfterViewInit: [] } });
|
|
2124
|
+
|
|
2125
|
+
class HandleSizeControllerDirective {
|
|
2126
|
+
constructor() {
|
|
2127
|
+
this.handleWrapper = inject(ElementRef);
|
|
2128
|
+
}
|
|
2129
|
+
ngAfterViewInit() {
|
|
2130
|
+
const element = this.handleWrapper.nativeElement;
|
|
2131
|
+
const rect = element.getBBox();
|
|
2132
|
+
const stroke = getChildStrokeWidth(element);
|
|
2133
|
+
this.handleModel.size.set({
|
|
2134
|
+
width: rect.width + stroke,
|
|
2135
|
+
height: rect.height + stroke
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2139
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: { handleModel: ["handleSizeController", "handleModel"] }, ngImport: i0 }); }
|
|
2140
|
+
}
|
|
2141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
|
|
2142
|
+
type: Directive,
|
|
2143
|
+
args: [{ selector: '[handleSizeController]' }]
|
|
2144
|
+
}], propDecorators: { handleModel: [{
|
|
2145
|
+
type: Input,
|
|
2146
|
+
args: [{ required: true, alias: 'handleSizeController' }]
|
|
2147
|
+
}] } });
|
|
2148
|
+
function getChildStrokeWidth(element) {
|
|
2149
|
+
const child = element.firstElementChild;
|
|
2150
|
+
if (child) {
|
|
2151
|
+
const stroke = getComputedStyle(child).strokeWidth;
|
|
2152
|
+
const strokeAsNumber = Number(stroke.replace('px', ''));
|
|
2153
|
+
if (isNaN(strokeAsNumber)) {
|
|
2154
|
+
return 0;
|
|
2155
|
+
}
|
|
2156
|
+
return strokeAsNumber;
|
|
2157
|
+
}
|
|
2158
|
+
return 0;
|
|
2159
|
+
}
|
|
2160
|
+
|
|
1729
2161
|
class NodeComponent {
|
|
1730
2162
|
constructor() {
|
|
1731
2163
|
this.injector = inject(Injector);
|
|
@@ -1737,12 +2169,15 @@ class NodeComponent {
|
|
|
1737
2169
|
this.selectionService = inject(SelectionService);
|
|
1738
2170
|
this.hostRef = inject(ElementRef);
|
|
1739
2171
|
this.connectionController = inject(ConnectionControllerDirective);
|
|
2172
|
+
this.nodeAccessor = inject(NodeAccessorService);
|
|
2173
|
+
this.zone = inject(NgZone);
|
|
1740
2174
|
this.showMagnet = computed(() => this.flowStatusService.status().state === 'connection-start' ||
|
|
1741
2175
|
this.flowStatusService.status().state === 'connection-validation');
|
|
1742
2176
|
this.styleWidth = computed(() => `${this.nodeModel.size().width}px`);
|
|
1743
2177
|
this.styleHeight = computed(() => `${this.nodeModel.size().height}px`);
|
|
1744
2178
|
}
|
|
1745
2179
|
ngOnInit() {
|
|
2180
|
+
this.nodeAccessor.model.set(this.nodeModel);
|
|
1746
2181
|
this.handleService.node.set(this.nodeModel);
|
|
1747
2182
|
effect(() => {
|
|
1748
2183
|
if (this.nodeModel.draggable()) {
|
|
@@ -1753,7 +2188,8 @@ class NodeComponent {
|
|
|
1753
2188
|
}
|
|
1754
2189
|
});
|
|
1755
2190
|
this.nodeModel.handles$
|
|
1756
|
-
.pipe(switchMap((handles) => resizable(handles.map(h => h.parentReference)
|
|
2191
|
+
.pipe(switchMap((handles) => resizable(handles.map(h => h.parentReference), this.zone)
|
|
2192
|
+
.pipe(map(() => handles))), tap((handles) => {
|
|
1757
2193
|
// TODO (performance) inspect how to avoid calls of this when flow initially rendered
|
|
1758
2194
|
handles.forEach(h => h.updateParent());
|
|
1759
2195
|
}), takeUntilDestroyed())
|
|
@@ -1762,8 +2198,8 @@ class NodeComponent {
|
|
|
1762
2198
|
ngAfterViewInit() {
|
|
1763
2199
|
this.nodeModel.linkDefaultNodeSizeWithModelSize();
|
|
1764
2200
|
if (this.nodeModel.node.type === 'html-template' || this.nodeModel.isComponentType) {
|
|
1765
|
-
resizable([this.htmlWrapperRef.nativeElement])
|
|
1766
|
-
.pipe(startWith(null), tap(() => {
|
|
2201
|
+
resizable([this.htmlWrapperRef.nativeElement], this.zone)
|
|
2202
|
+
.pipe(startWith(null), tap(() => this.nodeModel.handles().forEach(h => h.updateParent())), filter(() => !this.nodeModel.resizing()), tap(() => {
|
|
1767
2203
|
const width = this.htmlWrapperRef.nativeElement.clientWidth;
|
|
1768
2204
|
const height = this.htmlWrapperRef.nativeElement.clientHeight;
|
|
1769
2205
|
this.nodeModel.size.set({ width, height });
|
|
@@ -1796,22 +2232,22 @@ class NodeComponent {
|
|
|
1796
2232
|
}
|
|
1797
2233
|
}
|
|
1798
2234
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1799
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NodeComponent, selector: "g[node]", inputs: { nodeModel: "nodeModel",
|
|
2235
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NodeComponent, selector: "g[node]", inputs: { nodeModel: "nodeModel", nodeTemplate: "nodeTemplate", groupNodeTemplate: "groupNodeTemplate" }, providers: [HandleService, NodeAccessorService], viewQueries: [{ propertyName: "nodeContentRef", first: true, predicate: ["nodeContent"], descendants: true }, { propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true }], ngImport: i0, template: "<!-- Default node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'default'\"\n class=\"selectable\"\n #nodeContent\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode(); selectNode()\"\n>\n <div\n #htmlWrapper\n class=\"default-node\"\n [class.default-node_selected]=\"nodeModel.selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel.text()\"></div>\n\n <handle type=\"source\" [position]=\"nodeModel.sourcePosition()\" />\n <handle type=\"target\" [position]=\"nodeModel.targetPosition()\" />\n </div>\n</svg:foreignObject>\n\n<!-- Template node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'html-template' && nodeTemplate\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Component node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.isComponentType\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel.node.type)\"\n [ngComponentOutletInputs]=\"nodeModel.componentTypeInputs()\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Default group node -->\n<svg:rect\n *ngIf=\"nodeModel.node.type === 'default-group'\"\n [resizable]=\"nodeModel.resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel.color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel.selected()\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n [style.stroke]=\"nodeModel.color()\"\n [style.fill]=\"nodeModel.color()\"\n (mousedown)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (mousedown)=\"pullNode()\"\n>\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected, width: nodeModel.width, height: nodeModel.height } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n</svg:g>\n\n<!-- Resizer -->\n<ng-container *ngIf=\"nodeModel.resizerTemplate() as template\">\n <ng-container *ngIf=\"nodeModel.resizable()\">\n <ng-template [ngTemplateOutlet]=\"template\" />\n </ng-container>\n</ng-container>\n\n<!-- Handles -->\n<ng-container *ngFor=\"let handle of nodeModel.handles()\">\n <svg:circle\n *ngIf=\"!handle.template\"\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n\n <svg:g\n *ngIf=\"handle.template\"\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n\n <svg:circle\n *ngIf=\"showMagnet()\"\n class=\"magnet\"\n [attr.r]=\"nodeModel.magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n</ng-container>\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-node{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}.default-node_selected{border-width:2px}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HandleComponent, selector: "handle", inputs: ["position", "type", "id", "template"] }, { kind: "component", type: ResizableComponent, selector: "[resizable]", inputs: ["resizable", "resizerColor", "gap"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1800
2236
|
}
|
|
1801
2237
|
__decorate([
|
|
1802
2238
|
InjectionContext
|
|
1803
2239
|
], NodeComponent.prototype, "ngOnInit", null);
|
|
1804
2240
|
__decorate([
|
|
1805
|
-
Microtask // TODO (performance) check if we need microtask here
|
|
1806
|
-
,
|
|
1807
2241
|
InjectionContext
|
|
1808
2242
|
], NodeComponent.prototype, "ngAfterViewInit", null);
|
|
1809
2243
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, decorators: [{
|
|
1810
2244
|
type: Component,
|
|
1811
|
-
args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService], template: "<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'default'\"\n class=\"selectable\"\n #nodeContent\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode(); selectNode()\"\n>\n <div\n #htmlWrapper\n class=\"default-node\"\n [class.default-node_selected]=\"nodeModel.selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel.text()\"></div>\n\n <handle type=\"source\" [position]=\"nodeModel.sourcePosition()\" />\n <handle type=\"target\" [position]=\"nodeModel.targetPosition()\" />\n </div>\n</svg:foreignObject>\n\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'html-template' &&
|
|
2245
|
+
args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], template: "<!-- Default node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'default'\"\n class=\"selectable\"\n #nodeContent\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode(); selectNode()\"\n>\n <div\n #htmlWrapper\n class=\"default-node\"\n [class.default-node_selected]=\"nodeModel.selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel.text()\"></div>\n\n <handle type=\"source\" [position]=\"nodeModel.sourcePosition()\" />\n <handle type=\"target\" [position]=\"nodeModel.targetPosition()\" />\n </div>\n</svg:foreignObject>\n\n<!-- Template node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'html-template' && nodeTemplate\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Component node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.isComponentType\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (mousedown)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel.node.type)\"\n [ngComponentOutletInputs]=\"nodeModel.componentTypeInputs()\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Default group node -->\n<svg:rect\n *ngIf=\"nodeModel.node.type === 'default-group'\"\n [resizable]=\"nodeModel.resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel.color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel.selected()\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n [style.stroke]=\"nodeModel.color()\"\n [style.fill]=\"nodeModel.color()\"\n (mousedown)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (mousedown)=\"pullNode()\"\n>\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected, width: nodeModel.width, height: nodeModel.height } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n</svg:g>\n\n<!-- Resizer -->\n<ng-container *ngIf=\"nodeModel.resizerTemplate() as template\">\n <ng-container *ngIf=\"nodeModel.resizable()\">\n <ng-template [ngTemplateOutlet]=\"template\" />\n </ng-container>\n</ng-container>\n\n<!-- Handles -->\n<ng-container *ngFor=\"let handle of nodeModel.handles()\">\n <svg:circle\n *ngIf=\"!handle.template\"\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n\n <svg:g\n *ngIf=\"handle.template\"\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n\n <svg:circle\n *ngIf=\"showMagnet()\"\n class=\"magnet\"\n [attr.r]=\"nodeModel.magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n</ng-container>\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-node{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}.default-node_selected{border-width:2px}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
|
|
1812
2246
|
}], propDecorators: { nodeModel: [{
|
|
1813
2247
|
type: Input
|
|
1814
|
-
}],
|
|
2248
|
+
}], nodeTemplate: [{
|
|
2249
|
+
type: Input
|
|
2250
|
+
}], groupNodeTemplate: [{
|
|
1815
2251
|
type: Input
|
|
1816
2252
|
}], nodeContentRef: [{
|
|
1817
2253
|
type: ViewChild,
|
|
@@ -2154,7 +2590,7 @@ class FlowSizeControllerDirective {
|
|
|
2154
2590
|
this.flowWidth = view === 'auto' ? '100%' : view[0];
|
|
2155
2591
|
this.flowHeight = view === 'auto' ? '100%' : view[1];
|
|
2156
2592
|
});
|
|
2157
|
-
resizable([this.host.nativeElement]).pipe(tap(([entry]) => {
|
|
2593
|
+
resizable([this.host.nativeElement], inject(NgZone)).pipe(tap(([entry]) => {
|
|
2158
2594
|
this.flowSettingsService.computedFlowWidth.set(entry.contentRect.width);
|
|
2159
2595
|
this.flowSettingsService.computedFlowHeight.set(entry.contentRect.height);
|
|
2160
2596
|
}), takeUntilDestroyed()).subscribe();
|
|
@@ -2184,6 +2620,9 @@ const changesControllerHostDirective = {
|
|
|
2184
2620
|
'onNodesChange.position',
|
|
2185
2621
|
'onNodesChange.position.single',
|
|
2186
2622
|
'onNodesChange.position.many',
|
|
2623
|
+
'onNodesChange.size',
|
|
2624
|
+
'onNodesChange.size.single',
|
|
2625
|
+
'onNodesChange.size.many',
|
|
2187
2626
|
'onNodesChange.add',
|
|
2188
2627
|
'onNodesChange.add.single',
|
|
2189
2628
|
'onNodesChange.add.many',
|
|
@@ -2223,6 +2662,9 @@ class VflowComponent {
|
|
|
2223
2662
|
* Background for flow
|
|
2224
2663
|
*/
|
|
2225
2664
|
this.background = '#fff';
|
|
2665
|
+
this.optimization = {
|
|
2666
|
+
computeLayersOnInit: true
|
|
2667
|
+
};
|
|
2226
2668
|
this.nodeModels = computed(() => this.nodeRenderingService.nodes());
|
|
2227
2669
|
this.edgeModels = computed(() => this.flowEntitiesService.validEdges());
|
|
2228
2670
|
// #endregion
|
|
@@ -2333,6 +2775,9 @@ class VflowComponent {
|
|
|
2333
2775
|
addNodesToEdges(this.nodeModels(), newModels);
|
|
2334
2776
|
this.flowEntitiesService.edges.set(newModels);
|
|
2335
2777
|
}
|
|
2778
|
+
ngOnInit() {
|
|
2779
|
+
this.setInitialNodesOrder();
|
|
2780
|
+
}
|
|
2336
2781
|
// #region METHODS_API
|
|
2337
2782
|
/**
|
|
2338
2783
|
* Change viewport to specified state
|
|
@@ -2388,8 +2833,20 @@ class VflowComponent {
|
|
|
2388
2833
|
trackEdges(idx, { edge }) {
|
|
2389
2834
|
return edge;
|
|
2390
2835
|
}
|
|
2836
|
+
setInitialNodesOrder() {
|
|
2837
|
+
if (this.optimization.computeLayersOnInit) {
|
|
2838
|
+
this.nodeModels().forEach(model => {
|
|
2839
|
+
switch (model.node.type) {
|
|
2840
|
+
case 'default-group':
|
|
2841
|
+
case 'template-group': {
|
|
2842
|
+
this.nodeRenderingService.pullNode(model);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
});
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2391
2848
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2392
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "16.2.12", type: VflowComponent, selector: "vflow", inputs: { view: "view", minZoom: "minZoom", maxZoom: "maxZoom", handlePositions: "handlePositions", background: "background", entitiesSelectable: "entitiesSelectable", connection: ["connection", "connection", (settings) => new ConnectionModel(settings)], nodes: "nodes", edges: "edges" }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
2849
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "16.2.12", type: VflowComponent, selector: "vflow", inputs: { view: "view", minZoom: "minZoom", maxZoom: "maxZoom", handlePositions: "handlePositions", background: "background", optimization: "optimization", entitiesSelectable: "entitiesSelectable", connection: ["connection", "connection", (settings) => new ConnectionModel(settings)], nodes: "nodes", edges: "edges" }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
2393
2850
|
DraggableService,
|
|
2394
2851
|
ViewportService,
|
|
2395
2852
|
FlowStatusService,
|
|
@@ -2400,7 +2857,7 @@ class VflowComponent {
|
|
|
2400
2857
|
SelectionService,
|
|
2401
2858
|
FlowSettingsService,
|
|
2402
2859
|
ComponentEventBusService
|
|
2403
|
-
], queries: [{ propertyName: "
|
|
2860
|
+
], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g [background]=\"background\"/>\n\n <svg:g\n mapContext\n spacePointContext\n >\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective?.templateRef\"\n />\n\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </svg:g>\n\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]", inputs: ["background"] }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2404
2861
|
}
|
|
2405
2862
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, decorators: [{
|
|
2406
2863
|
type: Component,
|
|
@@ -2418,7 +2875,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2418
2875
|
], hostDirectives: [
|
|
2419
2876
|
connectionControllerHostDirective,
|
|
2420
2877
|
changesControllerHostDirective
|
|
2421
|
-
], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g [background]=\"background\"/>\n\n <svg:g\n mapContext\n spacePointContext\n >\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective?.templateRef\"\n />\n\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [
|
|
2878
|
+
], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g [background]=\"background\"/>\n\n <svg:g\n mapContext\n spacePointContext\n >\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective?.templateRef\"\n />\n\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </svg:g>\n\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
|
|
2422
2879
|
}], propDecorators: { view: [{
|
|
2423
2880
|
type: Input
|
|
2424
2881
|
}], minZoom: [{
|
|
@@ -2429,6 +2886,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2429
2886
|
type: Input
|
|
2430
2887
|
}], background: [{
|
|
2431
2888
|
type: Input
|
|
2889
|
+
}], optimization: [{
|
|
2890
|
+
type: Input
|
|
2432
2891
|
}], entitiesSelectable: [{
|
|
2433
2892
|
type: Input
|
|
2434
2893
|
}], connection: [{
|
|
@@ -2441,9 +2900,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2441
2900
|
type: Input
|
|
2442
2901
|
}], onComponentNodeEvent: [{
|
|
2443
2902
|
type: Output
|
|
2444
|
-
}],
|
|
2903
|
+
}], nodeTemplateDirective: [{
|
|
2445
2904
|
type: ContentChild,
|
|
2446
2905
|
args: [NodeHtmlTemplateDirective]
|
|
2906
|
+
}], groupNodeTemplateDirective: [{
|
|
2907
|
+
type: ContentChild,
|
|
2908
|
+
args: [GroupNodeTemplateDirective]
|
|
2447
2909
|
}], edgeTemplateDirective: [{
|
|
2448
2910
|
type: ContentChild,
|
|
2449
2911
|
args: [EdgeTemplateDirective]
|
|
@@ -2502,7 +2964,8 @@ const components = [
|
|
|
2502
2964
|
ConnectionComponent,
|
|
2503
2965
|
HandleComponent,
|
|
2504
2966
|
DefsComponent,
|
|
2505
|
-
BackgroundComponent
|
|
2967
|
+
BackgroundComponent,
|
|
2968
|
+
ResizableComponent,
|
|
2506
2969
|
];
|
|
2507
2970
|
const directives = [
|
|
2508
2971
|
SpacePointContextDirective,
|
|
@@ -2513,10 +2976,11 @@ const directives = [
|
|
|
2513
2976
|
SelectableDirective,
|
|
2514
2977
|
PointerDirective,
|
|
2515
2978
|
RootPointerDirective,
|
|
2516
|
-
FlowSizeControllerDirective
|
|
2979
|
+
FlowSizeControllerDirective,
|
|
2517
2980
|
];
|
|
2518
2981
|
const templateDirectives = [
|
|
2519
2982
|
NodeHtmlTemplateDirective,
|
|
2983
|
+
GroupNodeTemplateDirective,
|
|
2520
2984
|
EdgeLabelHtmlTemplateDirective,
|
|
2521
2985
|
EdgeTemplateDirective,
|
|
2522
2986
|
ConnectionTemplateDirective,
|
|
@@ -2531,7 +2995,8 @@ class VflowModule {
|
|
|
2531
2995
|
ConnectionComponent,
|
|
2532
2996
|
HandleComponent,
|
|
2533
2997
|
DefsComponent,
|
|
2534
|
-
BackgroundComponent,
|
|
2998
|
+
BackgroundComponent,
|
|
2999
|
+
ResizableComponent, SpacePointContextDirective,
|
|
2535
3000
|
MapContextDirective,
|
|
2536
3001
|
RootSvgReferenceDirective,
|
|
2537
3002
|
RootSvgContextDirective,
|
|
@@ -2540,12 +3005,15 @@ class VflowModule {
|
|
|
2540
3005
|
PointerDirective,
|
|
2541
3006
|
RootPointerDirective,
|
|
2542
3007
|
FlowSizeControllerDirective, NodeHtmlTemplateDirective,
|
|
3008
|
+
GroupNodeTemplateDirective,
|
|
2543
3009
|
EdgeLabelHtmlTemplateDirective,
|
|
2544
3010
|
EdgeTemplateDirective,
|
|
2545
3011
|
ConnectionTemplateDirective,
|
|
2546
3012
|
HandleTemplateDirective], imports: [CommonModule], exports: [VflowComponent,
|
|
2547
3013
|
HandleComponent,
|
|
3014
|
+
ResizableComponent,
|
|
2548
3015
|
SelectableDirective, NodeHtmlTemplateDirective,
|
|
3016
|
+
GroupNodeTemplateDirective,
|
|
2549
3017
|
EdgeLabelHtmlTemplateDirective,
|
|
2550
3018
|
EdgeTemplateDirective,
|
|
2551
3019
|
ConnectionTemplateDirective,
|
|
@@ -2559,6 +3027,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2559
3027
|
exports: [
|
|
2560
3028
|
VflowComponent,
|
|
2561
3029
|
HandleComponent,
|
|
3030
|
+
ResizableComponent,
|
|
2562
3031
|
SelectableDirective,
|
|
2563
3032
|
...templateDirectives
|
|
2564
3033
|
],
|
|
@@ -2572,5 +3041,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2572
3041
|
* Generated bundle index. Do not edit.
|
|
2573
3042
|
*/
|
|
2574
3043
|
|
|
2575
|
-
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, HandleComponent, HandleTemplateDirective, NodeHtmlTemplateDirective, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicNode, isTemplateStaticNode };
|
|
3044
|
+
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, NodeHtmlTemplateDirective, ResizableComponent, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode };
|
|
2576
3045
|
//# sourceMappingURL=ngx-vflow.mjs.map
|