ngx-vflow 0.13.0-0 → 0.14.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/background/background.component.mjs +7 -16
- package/esm2022/lib/vflow/components/default-node/default-node.component.mjs +18 -0
- package/esm2022/lib/vflow/components/node/node.component.mjs +8 -7
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +23 -10
- package/esm2022/lib/vflow/directives/root-pointer.directive.mjs +1 -1
- package/esm2022/lib/vflow/directives/selectable.directive.mjs +5 -2
- package/esm2022/lib/vflow/models/minimap.model.mjs +7 -0
- package/esm2022/lib/vflow/public-components/minimap/minimap.component.mjs +119 -0
- package/esm2022/lib/vflow/public-components/resizable/resizable.component.mjs +124 -180
- package/esm2022/lib/vflow/services/draggable.service.mjs +40 -19
- package/esm2022/lib/vflow/services/flow-entities.service.mjs +6 -5
- package/esm2022/lib/vflow/services/flow-settings.service.mjs +2 -1
- package/esm2022/lib/vflow/services/keyboard.service.mjs +45 -0
- package/esm2022/lib/vflow/services/node-changes.service.mjs +6 -7
- package/esm2022/lib/vflow/services/selection.service.mjs +12 -5
- package/esm2022/lib/vflow/types/keyboard-action.type.mjs +2 -0
- package/esm2022/lib/vflow/utils/get-os.mjs +24 -0
- package/esm2022/lib/vflow/utils/transform-background.mjs +6 -0
- package/esm2022/lib/vflow/vflow.module.mjs +11 -3
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/ngx-vflow.mjs +423 -242
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/background/background.component.d.ts +3 -6
- package/lib/vflow/components/default-node/default-node.component.d.ts +6 -0
- package/lib/vflow/components/vflow/vflow.component.d.ts +6 -2
- package/lib/vflow/directives/root-pointer.directive.d.ts +10 -16
- package/lib/vflow/directives/space-point-context.directive.d.ts +1 -15
- package/lib/vflow/models/edge.model.d.ts +17 -1
- package/lib/vflow/models/minimap.model.d.ts +4 -0
- package/lib/vflow/public-components/minimap/minimap.component.d.ts +49 -0
- package/lib/vflow/public-components/resizable/resizable.component.d.ts +6 -11
- package/lib/vflow/services/draggable.service.d.ts +2 -0
- package/lib/vflow/services/flow-entities.service.d.ts +7 -5
- package/lib/vflow/services/flow-settings.service.d.ts +2 -0
- package/lib/vflow/services/keyboard.service.d.ts +11 -0
- package/lib/vflow/services/selection.service.d.ts +1 -0
- package/lib/vflow/types/keyboard-action.type.d.ts +2 -0
- package/lib/vflow/utils/get-os.d.ts +1 -0
- package/lib/vflow/utils/transform-background.d.ts +2 -0
- package/lib/vflow/vflow.module.d.ts +21 -19
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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,
|
|
4
|
+
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, EventEmitter, Output, DestroyRef, Input, runInInjectionContext, Component, Injector, ChangeDetectionStrategy, HostListener, ViewChild, NgZone, ContentChild, NgModule } from '@angular/core';
|
|
5
5
|
import { select } from 'd3-selection';
|
|
6
6
|
import { zoomIdentity, zoom } from 'd3-zoom';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { switchMap, merge, fromEvent, tap, Subject, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share, Observable, startWith } from 'rxjs';
|
|
8
|
+
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
9
9
|
import { drag } from 'd3-drag';
|
|
10
10
|
import { path } from 'd3-path';
|
|
11
11
|
import { __decorate } from 'tslib';
|
|
@@ -94,6 +94,10 @@ class FlowEntitiesService {
|
|
|
94
94
|
// empty arrays considered equal, other arrays may not be equal
|
|
95
95
|
equal: (a, b) => !a.length && !b.length ? true : a === b
|
|
96
96
|
});
|
|
97
|
+
this.validEdges = computed(() => {
|
|
98
|
+
const nodes = this.nodes();
|
|
99
|
+
return this.edges().filter(e => nodes.includes(e.source()) && nodes.includes(e.target()));
|
|
100
|
+
});
|
|
97
101
|
this.connection = signal(new ConnectionModel({}));
|
|
98
102
|
this.markers = computed(() => {
|
|
99
103
|
const markersMap = new Map();
|
|
@@ -114,14 +118,11 @@ class FlowEntitiesService {
|
|
|
114
118
|
}
|
|
115
119
|
return markersMap;
|
|
116
120
|
});
|
|
117
|
-
this.validEdges = computed(() => {
|
|
118
|
-
const nodes = this.nodes();
|
|
119
|
-
return this.edges().filter(e => nodes.includes(e.source()) && nodes.includes(e.target()));
|
|
120
|
-
});
|
|
121
121
|
this.entities = computed(() => [
|
|
122
122
|
...this.nodes(),
|
|
123
123
|
...this.edges()
|
|
124
124
|
]);
|
|
125
|
+
this.minimap = signal(null);
|
|
125
126
|
}
|
|
126
127
|
getNode(id) {
|
|
127
128
|
return this.nodes().find(({ node }) => node.id === id);
|
|
@@ -174,6 +175,7 @@ class FlowSettingsService {
|
|
|
174
175
|
this.computedFlowHeight = signal(0);
|
|
175
176
|
this.minZoom = signal(0.5);
|
|
176
177
|
this.maxZoom = signal(3);
|
|
178
|
+
this.background = signal({ type: 'solid', color: '#fff' });
|
|
177
179
|
}
|
|
178
180
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
179
181
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService }); }
|
|
@@ -249,9 +251,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
249
251
|
}]
|
|
250
252
|
}] });
|
|
251
253
|
|
|
254
|
+
function getOS() {
|
|
255
|
+
const userAgent = window.navigator.userAgent.toLowerCase();
|
|
256
|
+
const macosPlatforms = /(macintosh|macintel|macppc|mac68k|macos)/i;
|
|
257
|
+
const windowsPlatforms = /(win32|win64|windows|wince)/i;
|
|
258
|
+
const iosPlatforms = /(iphone|ipad|ipod)/i;
|
|
259
|
+
let os = null;
|
|
260
|
+
if (macosPlatforms.test(userAgent)) {
|
|
261
|
+
os = "macos";
|
|
262
|
+
}
|
|
263
|
+
else if (iosPlatforms.test(userAgent)) {
|
|
264
|
+
os = "ios";
|
|
265
|
+
}
|
|
266
|
+
else if (windowsPlatforms.test(userAgent)) {
|
|
267
|
+
os = "windows";
|
|
268
|
+
}
|
|
269
|
+
else if (/android/.test(userAgent)) {
|
|
270
|
+
os = "android";
|
|
271
|
+
}
|
|
272
|
+
else if (!os && /linux/.test(userAgent)) {
|
|
273
|
+
os = "linux";
|
|
274
|
+
}
|
|
275
|
+
return os;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
class KeyboardService {
|
|
279
|
+
constructor() {
|
|
280
|
+
this.actions = signal({
|
|
281
|
+
multiSelection: [
|
|
282
|
+
getOS() === 'macos' ? 'MetaLeft' : 'ControlLeft',
|
|
283
|
+
getOS() === 'macos' ? 'MetaRight' : 'ControlRight',
|
|
284
|
+
]
|
|
285
|
+
});
|
|
286
|
+
this.actionsActive = {
|
|
287
|
+
multiSelection: false
|
|
288
|
+
};
|
|
289
|
+
toObservable(this.actions).pipe(switchMap(() => merge(fromEvent(document, 'keydown').pipe(tap(event => {
|
|
290
|
+
for (const action in this.actions()) {
|
|
291
|
+
const keyCodes = this.actions()[action] ?? [];
|
|
292
|
+
if (keyCodes.includes(event.code)) {
|
|
293
|
+
this.actionsActive[action] = true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
})), fromEvent(document, 'keyup').pipe(tap(event => {
|
|
297
|
+
for (const action in this.actions()) {
|
|
298
|
+
const keyCodes = this.actions()[action] ?? [];
|
|
299
|
+
if (keyCodes.includes(event.code)) {
|
|
300
|
+
this.actionsActive[action] = false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
})))), takeUntilDestroyed()).subscribe();
|
|
304
|
+
}
|
|
305
|
+
setShortcuts(newActions) {
|
|
306
|
+
this.actions.update((actions) => ({ ...actions, ...newActions }));
|
|
307
|
+
}
|
|
308
|
+
isActiveAction(action) {
|
|
309
|
+
return this.actionsActive[action];
|
|
310
|
+
}
|
|
311
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
312
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService }); }
|
|
313
|
+
}
|
|
314
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService, decorators: [{
|
|
315
|
+
type: Injectable
|
|
316
|
+
}], ctorParameters: function () { return []; } });
|
|
317
|
+
|
|
252
318
|
class SelectionService {
|
|
253
319
|
constructor() {
|
|
254
320
|
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
321
|
+
this.keyboardService = inject(KeyboardService);
|
|
255
322
|
this.viewport$ = new Subject();
|
|
256
323
|
this.resetSelection = this.viewport$.pipe(tap(({ start, end, target }) => {
|
|
257
324
|
if (start && end && target) {
|
|
@@ -273,10 +340,15 @@ class SelectionService {
|
|
|
273
340
|
this.viewport$.next(viewport);
|
|
274
341
|
}
|
|
275
342
|
select(entity) {
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
343
|
+
// ? May be not a responsibility of this method
|
|
344
|
+
// if entity already selected - do nothing
|
|
345
|
+
if (entity?.selected()) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (!this.keyboardService.isActiveAction('multiSelection')) {
|
|
349
|
+
// undo select for previously selected nodes
|
|
350
|
+
this.flowEntitiesService.entities().forEach(n => n.selected.set(false));
|
|
351
|
+
}
|
|
280
352
|
if (entity) {
|
|
281
353
|
// select passed entity
|
|
282
354
|
entity.selected.set(true);
|
|
@@ -377,6 +449,9 @@ const evTarget = (anyEvent) => {
|
|
|
377
449
|
const round = (num) => Math.round(num * 100) / 100;
|
|
378
450
|
|
|
379
451
|
class DraggableService {
|
|
452
|
+
constructor() {
|
|
453
|
+
this.entitiesService = inject(FlowEntitiesService);
|
|
454
|
+
}
|
|
380
455
|
/**
|
|
381
456
|
* Enable draggable behavior for element.
|
|
382
457
|
*
|
|
@@ -412,27 +487,24 @@ class DraggableService {
|
|
|
412
487
|
* @returns
|
|
413
488
|
*/
|
|
414
489
|
getDragBehavior(model) {
|
|
415
|
-
let
|
|
416
|
-
let
|
|
490
|
+
let dragNodes = [];
|
|
491
|
+
let initialPositions = [];
|
|
417
492
|
return drag()
|
|
418
493
|
.on('start', (event) => {
|
|
419
|
-
|
|
420
|
-
|
|
494
|
+
dragNodes = this.getDragNodes(model);
|
|
495
|
+
initialPositions = dragNodes.map(node => ({
|
|
496
|
+
x: node.point().x - event.x,
|
|
497
|
+
y: node.point().y - event.y
|
|
498
|
+
}));
|
|
421
499
|
})
|
|
422
500
|
.on('drag', (event) => {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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);
|
|
501
|
+
dragNodes.forEach((model, index) => {
|
|
502
|
+
let point = {
|
|
503
|
+
x: round(event.x + initialPositions[index].x),
|
|
504
|
+
y: round(event.y + initialPositions[index].y)
|
|
505
|
+
};
|
|
506
|
+
moveNode(model, point);
|
|
507
|
+
});
|
|
436
508
|
});
|
|
437
509
|
}
|
|
438
510
|
/**
|
|
@@ -445,12 +517,32 @@ class DraggableService {
|
|
|
445
517
|
event.sourceEvent.stopPropagation();
|
|
446
518
|
});
|
|
447
519
|
}
|
|
520
|
+
getDragNodes(model) {
|
|
521
|
+
return model.selected()
|
|
522
|
+
? this.entitiesService
|
|
523
|
+
.nodes()
|
|
524
|
+
// selected draggable nodes (with current node)
|
|
525
|
+
.filter(node => node.selected() && node.draggable())
|
|
526
|
+
// we only can move current node if it's not selected
|
|
527
|
+
: [model];
|
|
528
|
+
}
|
|
448
529
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
449
530
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService }); }
|
|
450
531
|
}
|
|
451
532
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, decorators: [{
|
|
452
533
|
type: Injectable
|
|
453
534
|
}] });
|
|
535
|
+
function moveNode(model, point) {
|
|
536
|
+
const parent = model.parent();
|
|
537
|
+
// keep node in bounds of parent
|
|
538
|
+
if (parent) {
|
|
539
|
+
point.x = Math.min(parent.size().width - model.size().width, point.x);
|
|
540
|
+
point.x = Math.max(0, point.x);
|
|
541
|
+
point.y = Math.min(parent.size().height - model.size().height, point.y);
|
|
542
|
+
point.y = Math.max(0, point.y);
|
|
543
|
+
}
|
|
544
|
+
model.setPoint(point, true);
|
|
545
|
+
}
|
|
454
546
|
|
|
455
547
|
class EdgeTemplateDirective {
|
|
456
548
|
constructor() {
|
|
@@ -1247,12 +1339,11 @@ class NodesChangeService {
|
|
|
1247
1339
|
// Check for nodes list change and watch for specific node from this list change its position
|
|
1248
1340
|
switchMap((nodes) => merge(...nodes.map(node => node.point$.pipe(
|
|
1249
1341
|
// skip initial position from signal
|
|
1250
|
-
skip(1), map(() => node))))),
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
]));
|
|
1342
|
+
skip(1), map(() => node))))), map((changedNode) => {
|
|
1343
|
+
return this.entitiesService.nodes()
|
|
1344
|
+
.filter(node => node === changedNode || node.selected())
|
|
1345
|
+
.map(node => ({ type: 'position', id: node.node.id, point: node.point() }));
|
|
1346
|
+
}));
|
|
1256
1347
|
this.nodeSizeChange$ = toObservable(this.entitiesService.nodes)
|
|
1257
1348
|
.pipe(switchMap((nodes) => merge(...nodes.map(node => node.size$.pipe(skip(1), map(() => node))))), map(changedNode => [
|
|
1258
1349
|
{ type: 'size', id: changedNode.node.id, size: changedNode.size() }
|
|
@@ -1587,6 +1678,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1587
1678
|
args: [{ selector: 'g[spacePointContext]' }]
|
|
1588
1679
|
}] });
|
|
1589
1680
|
|
|
1681
|
+
function transformBackground(background) {
|
|
1682
|
+
return typeof background === 'string'
|
|
1683
|
+
? { type: 'solid', color: background }
|
|
1684
|
+
: background;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1590
1687
|
function Microtask(target, key, descriptor) {
|
|
1591
1688
|
const originalMethod = descriptor.value;
|
|
1592
1689
|
descriptor.value = function (...args) {
|
|
@@ -1665,6 +1762,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1665
1762
|
type: Injectable
|
|
1666
1763
|
}] });
|
|
1667
1764
|
|
|
1765
|
+
class DefaultNodeComponent {
|
|
1766
|
+
constructor() {
|
|
1767
|
+
this.selected = false;
|
|
1768
|
+
}
|
|
1769
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1770
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DefaultNodeComponent, selector: "default-node", inputs: { selected: "selected" }, host: { properties: { "class.selected": "selected" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }); }
|
|
1771
|
+
}
|
|
1772
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
|
|
1773
|
+
type: Component,
|
|
1774
|
+
args: [{ selector: 'default-node', host: {
|
|
1775
|
+
'[class.selected]': 'selected'
|
|
1776
|
+
}, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
|
|
1777
|
+
}], propDecorators: { selected: [{
|
|
1778
|
+
type: Input
|
|
1779
|
+
}] } });
|
|
1780
|
+
|
|
1668
1781
|
class HandleModel {
|
|
1669
1782
|
constructor(rawHandle, parentNode) {
|
|
1670
1783
|
this.rawHandle = rawHandle;
|
|
@@ -1878,6 +1991,7 @@ class ResizableComponent {
|
|
|
1878
1991
|
this.nodeAccessor = inject(NodeAccessorService);
|
|
1879
1992
|
this.rootPointer = inject(RootPointerDirective);
|
|
1880
1993
|
this.viewportService = inject(ViewportService);
|
|
1994
|
+
this.spacePointContext = inject(SpacePointContextDirective);
|
|
1881
1995
|
this.hostRef = inject(ElementRef);
|
|
1882
1996
|
this.resizerColor = '#2e414c';
|
|
1883
1997
|
this.gap = 1.5;
|
|
@@ -1889,7 +2003,7 @@ class ResizableComponent {
|
|
|
1889
2003
|
this.minHeight = 0;
|
|
1890
2004
|
// TODO: allow reszie beside the flow
|
|
1891
2005
|
this.resizeOnGlobalMouseMove = this.rootPointer.pointerMovement$
|
|
1892
|
-
.pipe(filter(() => this.resizeSide !== null), tap((event) => this.resize(event)), takeUntilDestroyed())
|
|
2006
|
+
.pipe(filter(() => this.resizeSide !== null), filter((event) => event.movementX !== 0 || event.movementY !== 0), tap((event) => this.resize(event)), takeUntilDestroyed())
|
|
1893
2007
|
.subscribe();
|
|
1894
2008
|
this.endResizeOnGlobalMouseUp = this.rootPointer.documentPointerEnd$
|
|
1895
2009
|
.pipe(tap(() => this.endResize()), takeUntilDestroyed())
|
|
@@ -1918,193 +2032,55 @@ class ResizableComponent {
|
|
|
1918
2032
|
this.resizeSide = side;
|
|
1919
2033
|
this.model.resizing.set(true);
|
|
1920
2034
|
}
|
|
1921
|
-
resize(
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
if (x === this.getMinX() || x === this.getMaxX()) {
|
|
1931
|
-
return;
|
|
1932
|
-
}
|
|
1933
|
-
this.model.setPoint({ x, y: this.model.point().y }, false);
|
|
1934
|
-
this.model.size.update(({ height, width }) => {
|
|
1935
|
-
width -= offsetX;
|
|
1936
|
-
width = Math.max(width, this.minWidth);
|
|
1937
|
-
width = Math.min(width, this.getMaxWidth());
|
|
1938
|
-
return { height, width: width };
|
|
1939
|
-
});
|
|
1940
|
-
return;
|
|
1941
|
-
case 'right':
|
|
1942
|
-
this.model.size.update(({ height, width }) => {
|
|
1943
|
-
width += offsetX;
|
|
1944
|
-
width = Math.max(width, this.minWidth);
|
|
1945
|
-
width = Math.min(width, this.getMaxWidth());
|
|
1946
|
-
const bounds = getNodesBounds(this.model.children());
|
|
1947
|
-
width = Math.max(width, bounds.x + bounds.width);
|
|
1948
|
-
return { height, width };
|
|
1949
|
-
});
|
|
1950
|
-
return;
|
|
1951
|
-
case 'top':
|
|
1952
|
-
let y = this.model.point().y + offsetY;
|
|
1953
|
-
y = Math.max(y, this.getMinY());
|
|
1954
|
-
y = Math.min(y, this.getMaxY());
|
|
1955
|
-
if (y === this.getMinY() || y === this.getMaxY()) {
|
|
1956
|
-
return;
|
|
1957
|
-
}
|
|
1958
|
-
this.model.setPoint({ x: this.model.point().x, y }, false);
|
|
1959
|
-
this.model.size.update(({ height, width }) => {
|
|
1960
|
-
height -= offsetY;
|
|
1961
|
-
height = Math.max(height, this.minHeight);
|
|
1962
|
-
height = Math.min(height, this.getMaxHeight());
|
|
1963
|
-
return { width, height };
|
|
1964
|
-
});
|
|
1965
|
-
return;
|
|
1966
|
-
case 'bottom':
|
|
1967
|
-
this.model.size.update(({ height, width }) => {
|
|
1968
|
-
height += offsetY;
|
|
1969
|
-
height = Math.max(height, this.minHeight);
|
|
1970
|
-
height = Math.min(height, this.getMaxHeight());
|
|
1971
|
-
const bounds = getNodesBounds(this.model.children());
|
|
1972
|
-
height = Math.max(height, bounds.y + bounds.height);
|
|
1973
|
-
return { width, height };
|
|
1974
|
-
});
|
|
1975
|
-
return;
|
|
1976
|
-
case 'top-left': {
|
|
1977
|
-
let x = this.model.point().x + offsetX;
|
|
1978
|
-
x = Math.max(x, this.getMinX());
|
|
1979
|
-
x = Math.min(x, this.getMaxX());
|
|
1980
|
-
let y = this.model.point().y + offsetY;
|
|
1981
|
-
y = Math.max(y, this.getMinY());
|
|
1982
|
-
y = Math.min(y, this.getMaxY());
|
|
1983
|
-
if (x === this.getMinX() || y === this.getMinY() ||
|
|
1984
|
-
x === this.getMaxX() || y === this.getMaxY()) {
|
|
1985
|
-
return;
|
|
1986
|
-
}
|
|
1987
|
-
this.model.setPoint({ x, y }, false);
|
|
1988
|
-
this.model.size.update(({ height, width }) => {
|
|
1989
|
-
width -= offsetX;
|
|
1990
|
-
width = Math.max(width, this.minWidth);
|
|
1991
|
-
width = Math.min(width, this.getMaxWidth());
|
|
1992
|
-
height -= offsetY;
|
|
1993
|
-
height = Math.max(height, this.minHeight);
|
|
1994
|
-
height = Math.min(height, this.getMaxHeight());
|
|
1995
|
-
return { height, width };
|
|
1996
|
-
});
|
|
1997
|
-
return;
|
|
1998
|
-
}
|
|
1999
|
-
case 'top-right': {
|
|
2000
|
-
let y = this.model.point().y + offsetY;
|
|
2001
|
-
y = Math.max(y, this.getMinY());
|
|
2002
|
-
y = Math.min(y, this.getMaxY());
|
|
2003
|
-
if (y === this.getMinX() || y === this.getMaxY()) {
|
|
2004
|
-
return;
|
|
2005
|
-
}
|
|
2006
|
-
this.model.setPoint({ x: this.model.point().x, y }, false);
|
|
2007
|
-
this.model.size.update(({ height, width }) => {
|
|
2008
|
-
const bounds = getNodesBounds(this.model.children());
|
|
2009
|
-
width += offsetX;
|
|
2010
|
-
width = Math.max(width, this.minWidth);
|
|
2011
|
-
width = Math.min(width, this.getMaxWidth());
|
|
2012
|
-
width = Math.max(width, bounds.x + bounds.width);
|
|
2013
|
-
height -= offsetY;
|
|
2014
|
-
height = Math.max(height, this.minHeight);
|
|
2015
|
-
height = Math.min(height, this.getMaxHeight());
|
|
2016
|
-
return { height, width };
|
|
2017
|
-
});
|
|
2018
|
-
return;
|
|
2019
|
-
}
|
|
2020
|
-
case 'bottom-left': {
|
|
2021
|
-
let x = this.model.point().x + offsetX;
|
|
2022
|
-
x = Math.max(x, this.getMinX());
|
|
2023
|
-
x = Math.min(x, this.getMaxX());
|
|
2024
|
-
if (x === this.getMinX() || x === this.getMaxX()) {
|
|
2025
|
-
return;
|
|
2026
|
-
}
|
|
2027
|
-
this.model.setPoint({ x, y: this.model.point().y }, false);
|
|
2028
|
-
this.model.size.update(({ height, width }) => {
|
|
2029
|
-
width -= offsetX;
|
|
2030
|
-
width = Math.max(width, this.minWidth);
|
|
2031
|
-
width = Math.min(width, this.getMaxWidth());
|
|
2032
|
-
height += offsetY;
|
|
2033
|
-
height = Math.max(height, this.minHeight);
|
|
2034
|
-
height = Math.min(height, this.getMaxHeight());
|
|
2035
|
-
const bounds = getNodesBounds(this.model.children());
|
|
2036
|
-
height = Math.max(height, bounds.y + bounds.height);
|
|
2037
|
-
return { height, width };
|
|
2038
|
-
});
|
|
2039
|
-
return;
|
|
2040
|
-
}
|
|
2041
|
-
case 'bottom-right': {
|
|
2042
|
-
this.model.size.update(({ height, width }) => {
|
|
2043
|
-
const bounds = getNodesBounds(this.model.children());
|
|
2044
|
-
width += offsetX;
|
|
2045
|
-
width = Math.max(width, this.minWidth);
|
|
2046
|
-
width = Math.min(width, this.getMaxWidth());
|
|
2047
|
-
width = Math.max(width, bounds.x + bounds.width);
|
|
2048
|
-
height += offsetY;
|
|
2049
|
-
height = Math.max(height, this.minHeight);
|
|
2050
|
-
height = Math.min(height, this.getMaxHeight());
|
|
2051
|
-
height = Math.max(height, bounds.y + bounds.height);
|
|
2052
|
-
return { height, width };
|
|
2053
|
-
});
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2035
|
+
resize(event) {
|
|
2036
|
+
if (!this.resizeSide)
|
|
2037
|
+
return;
|
|
2038
|
+
if (this.isResizeConstrained(event))
|
|
2039
|
+
return;
|
|
2040
|
+
const offset = calcOffset(event.movementX, event.movementY, this.zoom());
|
|
2041
|
+
const { x, y, width, height } = constrainRect(applyResize(this.resizeSide, this.model, offset), this.model, this.resizeSide, this.minWidth, this.minHeight);
|
|
2042
|
+
this.model.setPoint({ x, y }, false);
|
|
2043
|
+
this.model.size.set({ width, height });
|
|
2056
2044
|
}
|
|
2057
2045
|
endResize() {
|
|
2058
2046
|
this.resizeSide = null;
|
|
2059
2047
|
this.model.resizing.set(false);
|
|
2060
2048
|
}
|
|
2061
|
-
|
|
2062
|
-
const
|
|
2063
|
-
if (
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
if (parent) {
|
|
2071
|
-
return parent.size().height - this.model.point().y;
|
|
2072
|
-
}
|
|
2073
|
-
return Infinity;
|
|
2074
|
-
}
|
|
2075
|
-
getMinX() {
|
|
2076
|
-
const parent = this.model.parent();
|
|
2077
|
-
if (parent) {
|
|
2078
|
-
return 0;
|
|
2049
|
+
isResizeConstrained({ x, y, movementX, movementY }) {
|
|
2050
|
+
const flowPoint = this.spacePointContext.documentPointToFlowPoint({ x, y });
|
|
2051
|
+
if (this.resizeSide?.includes('right')) {
|
|
2052
|
+
if (movementX > 0 && flowPoint.x < (this.model.point().x + this.model.size().width)) {
|
|
2053
|
+
return true;
|
|
2054
|
+
}
|
|
2055
|
+
if (movementX < 0 && flowPoint.x > this.model.point().x + this.model.size().width) {
|
|
2056
|
+
return true;
|
|
2057
|
+
}
|
|
2079
2058
|
}
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2059
|
+
if (this.resizeSide?.includes('left')) {
|
|
2060
|
+
if (movementX < 0 && flowPoint.x > this.model.point().x) {
|
|
2061
|
+
return true;
|
|
2062
|
+
}
|
|
2063
|
+
if (movementX > 0 && flowPoint.x < this.model.point().x) {
|
|
2064
|
+
return true;
|
|
2065
|
+
}
|
|
2086
2066
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
const bounds = getNodesBounds(children);
|
|
2095
|
-
return x + (bounds.x + bounds.width) >= x + width ? x : (width - this.minWidth) + x;
|
|
2067
|
+
if (this.resizeSide?.includes('bottom')) {
|
|
2068
|
+
if (movementY > 0 && flowPoint.y < (this.model.point().y + this.model.size().height)) {
|
|
2069
|
+
return true;
|
|
2070
|
+
}
|
|
2071
|
+
if (movementY < 0 && flowPoint.y > this.model.point().y + this.model.size().height) {
|
|
2072
|
+
return true;
|
|
2073
|
+
}
|
|
2096
2074
|
}
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
const bounds = getNodesBounds(children);
|
|
2105
|
-
return y + (bounds.y + bounds.height) >= y + height ? y : (height - this.minHeight) + y;
|
|
2075
|
+
if (this.resizeSide?.includes('top')) {
|
|
2076
|
+
if (movementY < 0 && flowPoint.y > this.model.point().y) {
|
|
2077
|
+
return true;
|
|
2078
|
+
}
|
|
2079
|
+
if (movementY > 0 && flowPoint.y < this.model.point().y) {
|
|
2080
|
+
return true;
|
|
2081
|
+
}
|
|
2106
2082
|
}
|
|
2107
|
-
return
|
|
2083
|
+
return false;
|
|
2108
2084
|
}
|
|
2109
2085
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2110
2086
|
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"] }] }); }
|
|
@@ -2125,6 +2101,86 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2125
2101
|
type: ViewChild,
|
|
2126
2102
|
args: ['resizer', { static: true }]
|
|
2127
2103
|
}], ngAfterViewInit: [] } });
|
|
2104
|
+
function calcOffset(movementX, movementY, zoom) {
|
|
2105
|
+
return {
|
|
2106
|
+
offsetX: round(movementX / zoom),
|
|
2107
|
+
offsetY: round(movementY / zoom)
|
|
2108
|
+
};
|
|
2109
|
+
}
|
|
2110
|
+
function applyResize(side, model, offset) {
|
|
2111
|
+
const { offsetX, offsetY } = offset;
|
|
2112
|
+
const { x, y } = model.point();
|
|
2113
|
+
const { width, height } = model.size();
|
|
2114
|
+
// Handle each case of resizing (top, bottom, left, right, corners)
|
|
2115
|
+
switch (side) {
|
|
2116
|
+
case 'left':
|
|
2117
|
+
return { x: x + offsetX, y, width: width - offsetX, height };
|
|
2118
|
+
case 'right':
|
|
2119
|
+
return { x, y, width: width + offsetX, height };
|
|
2120
|
+
case 'top':
|
|
2121
|
+
return { x, y: y + offsetY, width, height: height - offsetY };
|
|
2122
|
+
case 'bottom':
|
|
2123
|
+
return { x, y, width, height: height + offsetY };
|
|
2124
|
+
case 'top-left':
|
|
2125
|
+
return { x: x + offsetX, y: y + offsetY, width: width - offsetX, height: height - offsetY };
|
|
2126
|
+
case 'top-right':
|
|
2127
|
+
return { x, y: y + offsetY, width: width + offsetX, height: height - offsetY };
|
|
2128
|
+
case 'bottom-left':
|
|
2129
|
+
return { x: x + offsetX, y, width: width - offsetX, height: height + offsetY };
|
|
2130
|
+
case 'bottom-right':
|
|
2131
|
+
return { x, y, width: width + offsetX, height: height + offsetY };
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
function constrainRect(rect, model, side, minWidth, minHeight) {
|
|
2135
|
+
let { x, y, width, height } = rect;
|
|
2136
|
+
// 1. Prevent negative dimensions
|
|
2137
|
+
width = Math.max(width, 0);
|
|
2138
|
+
height = Math.max(height, 0);
|
|
2139
|
+
// 2. Apply minimum size constraints
|
|
2140
|
+
width = Math.max(minWidth, width);
|
|
2141
|
+
height = Math.max(minHeight, height);
|
|
2142
|
+
// Apply left/top constraints based on minimum size
|
|
2143
|
+
x = Math.min(x, model.point().x + model.size().width - minWidth);
|
|
2144
|
+
y = Math.min(y, model.point().y + model.size().height - minHeight);
|
|
2145
|
+
const parent = model.parent();
|
|
2146
|
+
// 3. Apply maximum size constraints based on parent size (if exists)
|
|
2147
|
+
if (parent) {
|
|
2148
|
+
x = Math.max(x, 0); // Left boundary of the parent
|
|
2149
|
+
y = Math.max(y, 0); // Top boundary of the parent
|
|
2150
|
+
if (x === 0) {
|
|
2151
|
+
width = model.point().x + model.size().width;
|
|
2152
|
+
}
|
|
2153
|
+
if (y === 0) {
|
|
2154
|
+
height = model.point().y + model.size().height;
|
|
2155
|
+
}
|
|
2156
|
+
width = Math.min(width, parent.size().width - model.point().x);
|
|
2157
|
+
height = Math.min(height, parent.size().height - model.point().y);
|
|
2158
|
+
}
|
|
2159
|
+
const bounds = getNodesBounds(model.children());
|
|
2160
|
+
// 4. Apply child node constraints (if children exist)
|
|
2161
|
+
if (bounds) {
|
|
2162
|
+
if (side.includes('left')) {
|
|
2163
|
+
x = Math.min(x, (model.point().x + model.size().width) - (bounds.x + bounds.width));
|
|
2164
|
+
width = Math.max(width, bounds.x + bounds.width);
|
|
2165
|
+
}
|
|
2166
|
+
if (side.includes('right')) {
|
|
2167
|
+
width = Math.max(width, bounds.x + bounds.width);
|
|
2168
|
+
}
|
|
2169
|
+
if (side.includes('bottom')) {
|
|
2170
|
+
height = Math.max(height, bounds.y + bounds.height);
|
|
2171
|
+
}
|
|
2172
|
+
if (side.includes('top')) {
|
|
2173
|
+
y = Math.min(y, (model.point().y + model.size().height) - (bounds.y + bounds.height));
|
|
2174
|
+
height = Math.max(height, bounds.y + bounds.height);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
return {
|
|
2178
|
+
x,
|
|
2179
|
+
y,
|
|
2180
|
+
width,
|
|
2181
|
+
height
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2128
2184
|
|
|
2129
2185
|
class HandleSizeControllerDirective {
|
|
2130
2186
|
constructor() {
|
|
@@ -2236,7 +2292,7 @@ class NodeComponent {
|
|
|
2236
2292
|
}
|
|
2237
2293
|
}
|
|
2238
2294
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2239
|
-
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 (
|
|
2295
|
+
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 (pointerStart)=\"pullNode(); selectNode()\"\n>\n <default-node\n #htmlWrapper\n [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 </default-node>\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 (pointerStart)=\"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 (pointerStart)=\"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 (pointerStart)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (pointerStart)=\"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-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: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }, { 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 }); }
|
|
2240
2296
|
}
|
|
2241
2297
|
__decorate([
|
|
2242
2298
|
InjectionContext
|
|
@@ -2246,7 +2302,7 @@ __decorate([
|
|
|
2246
2302
|
], NodeComponent.prototype, "ngAfterViewInit", null);
|
|
2247
2303
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, decorators: [{
|
|
2248
2304
|
type: Component,
|
|
2249
|
-
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 (
|
|
2305
|
+
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 (pointerStart)=\"pullNode(); selectNode()\"\n>\n <default-node\n #htmlWrapper\n [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 </default-node>\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 (pointerStart)=\"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 (pointerStart)=\"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 (pointerStart)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (pointerStart)=\"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-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
|
|
2250
2306
|
}], propDecorators: { nodeModel: [{
|
|
2251
2307
|
type: Input
|
|
2252
2308
|
}], nodeTemplate: [{
|
|
@@ -2502,13 +2558,11 @@ const defaultGap = 20;
|
|
|
2502
2558
|
const defaultDotSize = 2;
|
|
2503
2559
|
const defaultDotColor = 'rgb(177, 177, 183)';
|
|
2504
2560
|
class BackgroundComponent {
|
|
2505
|
-
set background(value) {
|
|
2506
|
-
this.backgroundSignal.set(value);
|
|
2507
|
-
}
|
|
2508
2561
|
constructor() {
|
|
2509
2562
|
this.viewportService = inject(ViewportService);
|
|
2510
2563
|
this.rootSvg = inject(RootSvgReferenceDirective).element;
|
|
2511
|
-
this.
|
|
2564
|
+
this.settingsService = inject(FlowSettingsService);
|
|
2565
|
+
this.backgroundSignal = this.settingsService.background;
|
|
2512
2566
|
this.scaledGap = computed(() => {
|
|
2513
2567
|
const background = this.backgroundSignal();
|
|
2514
2568
|
if (background.type === 'dots') {
|
|
@@ -2542,20 +2596,12 @@ class BackgroundComponent {
|
|
|
2542
2596
|
});
|
|
2543
2597
|
}
|
|
2544
2598
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2545
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2599
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BackgroundComponent, selector: "g[background]", ngImport: i0, template: "<ng-container *ngIf=\"backgroundSignal().type === 'dots'\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n</ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2546
2600
|
}
|
|
2547
2601
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, decorators: [{
|
|
2548
2602
|
type: Component,
|
|
2549
2603
|
args: [{ selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"backgroundSignal().type === 'dots'\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n</ng-container>\n" }]
|
|
2550
|
-
}], ctorParameters: function () { return []; }
|
|
2551
|
-
type: Input,
|
|
2552
|
-
args: [{ required: true, transform }]
|
|
2553
|
-
}] } });
|
|
2554
|
-
function transform(background) {
|
|
2555
|
-
return typeof background === 'string'
|
|
2556
|
-
? { type: 'solid', color: background }
|
|
2557
|
-
: background;
|
|
2558
|
-
}
|
|
2604
|
+
}], ctorParameters: function () { return []; } });
|
|
2559
2605
|
|
|
2560
2606
|
// TODO: too general purpose nane
|
|
2561
2607
|
class RootSvgContextDirective {
|
|
@@ -2662,11 +2708,8 @@ class VflowComponent {
|
|
|
2662
2708
|
this.nodeRenderingService = inject(NodeRenderingService);
|
|
2663
2709
|
this.flowSettingsService = inject(FlowSettingsService);
|
|
2664
2710
|
this.componentEventBusService = inject(ComponentEventBusService);
|
|
2711
|
+
this.keyboardService = inject(KeyboardService);
|
|
2665
2712
|
this.injector = inject(Injector);
|
|
2666
|
-
/**
|
|
2667
|
-
* Background for flow
|
|
2668
|
-
*/
|
|
2669
|
-
this.background = '#fff';
|
|
2670
2713
|
this.optimization = {
|
|
2671
2714
|
computeLayersOnInit: true
|
|
2672
2715
|
};
|
|
@@ -2711,6 +2754,7 @@ class VflowComponent {
|
|
|
2711
2754
|
this.edgesChange$ = this.edgesChangeService.changes$;
|
|
2712
2755
|
// #endregion
|
|
2713
2756
|
this.markers = this.flowEntitiesService.markers;
|
|
2757
|
+
this.minimap = this.flowEntitiesService.minimap;
|
|
2714
2758
|
}
|
|
2715
2759
|
// #endregion
|
|
2716
2760
|
// #region SETTINGS
|
|
@@ -2747,12 +2791,21 @@ class VflowComponent {
|
|
|
2747
2791
|
set handlePositions(handlePositions) {
|
|
2748
2792
|
this.flowSettingsService.handlePositions.set(handlePositions);
|
|
2749
2793
|
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Background for flow
|
|
2796
|
+
*/
|
|
2797
|
+
set background(value) {
|
|
2798
|
+
this.flowSettingsService.background.set(transformBackground(value));
|
|
2799
|
+
}
|
|
2750
2800
|
/**
|
|
2751
2801
|
* Global rule if you can or can't select entities
|
|
2752
2802
|
*/
|
|
2753
2803
|
set entitiesSelectable(value) {
|
|
2754
2804
|
this.flowSettingsService.entitiesSelectable.set(value);
|
|
2755
2805
|
}
|
|
2806
|
+
set keyboardShortcuts(value) {
|
|
2807
|
+
this.keyboardService.setShortcuts(value);
|
|
2808
|
+
}
|
|
2756
2809
|
/**
|
|
2757
2810
|
* Settings for connection (it renders when user tries to create edge between nodes)
|
|
2758
2811
|
*
|
|
@@ -2851,7 +2904,7 @@ class VflowComponent {
|
|
|
2851
2904
|
}
|
|
2852
2905
|
}
|
|
2853
2906
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2854
|
-
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: [
|
|
2907
|
+
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", keyboardShortcuts: "keyboardShortcuts", connection: ["connection", "connection", (settings) => new ConnectionModel(settings)], nodes: "nodes", edges: "edges" }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
2855
2908
|
DraggableService,
|
|
2856
2909
|
ViewportService,
|
|
2857
2910
|
FlowStatusService,
|
|
@@ -2861,8 +2914,9 @@ class VflowComponent {
|
|
|
2861
2914
|
NodeRenderingService,
|
|
2862
2915
|
SelectionService,
|
|
2863
2916
|
FlowSettingsService,
|
|
2864
|
-
ComponentEventBusService
|
|
2865
|
-
|
|
2917
|
+
ComponentEventBusService,
|
|
2918
|
+
KeyboardService
|
|
2919
|
+
], 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 />\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 <!-- Minimap -->\n <ng-container *ngIf=\"minimap() as minimap\">\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n </ng-container>\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: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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]" }, { 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 }); }
|
|
2866
2920
|
}
|
|
2867
2921
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, decorators: [{
|
|
2868
2922
|
type: Component,
|
|
@@ -2876,11 +2930,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2876
2930
|
NodeRenderingService,
|
|
2877
2931
|
SelectionService,
|
|
2878
2932
|
FlowSettingsService,
|
|
2879
|
-
ComponentEventBusService
|
|
2933
|
+
ComponentEventBusService,
|
|
2934
|
+
KeyboardService
|
|
2880
2935
|
], hostDirectives: [
|
|
2881
2936
|
connectionControllerHostDirective,
|
|
2882
2937
|
changesControllerHostDirective
|
|
2883
|
-
], 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
|
|
2938
|
+
], 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 />\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 <!-- Minimap -->\n <ng-container *ngIf=\"minimap() as minimap\">\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n </ng-container>\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"] }]
|
|
2884
2939
|
}], propDecorators: { view: [{
|
|
2885
2940
|
type: Input
|
|
2886
2941
|
}], minZoom: [{
|
|
@@ -2895,6 +2950,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2895
2950
|
type: Input
|
|
2896
2951
|
}], entitiesSelectable: [{
|
|
2897
2952
|
type: Input
|
|
2953
|
+
}], keyboardShortcuts: [{
|
|
2954
|
+
type: Input
|
|
2898
2955
|
}], connection: [{
|
|
2899
2956
|
type: Input,
|
|
2900
2957
|
args: [{ transform: (settings) => new ConnectionModel(settings) }]
|
|
@@ -2951,7 +3008,7 @@ class SelectableDirective {
|
|
|
2951
3008
|
return null;
|
|
2952
3009
|
}
|
|
2953
3010
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2954
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SelectableDirective, selector: "[selectable]", host: { listeners: { "mousedown": "onMousedown()" } }, ngImport: i0 }); }
|
|
3011
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SelectableDirective, selector: "[selectable]", host: { listeners: { "mousedown": "onMousedown()", "touchstart": "onMousedown()" } }, ngImport: i0 }); }
|
|
2955
3012
|
}
|
|
2956
3013
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, decorators: [{
|
|
2957
3014
|
type: Directive,
|
|
@@ -2959,11 +3016,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2959
3016
|
}], propDecorators: { onMousedown: [{
|
|
2960
3017
|
type: HostListener,
|
|
2961
3018
|
args: ['mousedown']
|
|
3019
|
+
}, {
|
|
3020
|
+
type: HostListener,
|
|
3021
|
+
args: ['touchstart']
|
|
3022
|
+
}] } });
|
|
3023
|
+
|
|
3024
|
+
class MinimapModel {
|
|
3025
|
+
constructor() {
|
|
3026
|
+
this.template = signal(null);
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
|
|
3030
|
+
class MiniMapComponent {
|
|
3031
|
+
constructor() {
|
|
3032
|
+
this.entitiesService = inject(FlowEntitiesService);
|
|
3033
|
+
this.flowSettingsService = inject(FlowSettingsService);
|
|
3034
|
+
this.viewportService = inject(ViewportService);
|
|
3035
|
+
this.injector = inject(Injector);
|
|
3036
|
+
/**
|
|
3037
|
+
* The color outside the viewport (invisible area)
|
|
3038
|
+
*/
|
|
3039
|
+
this.maskColor = `rgba(215, 215, 215, 0.6)`;
|
|
3040
|
+
/**
|
|
3041
|
+
* The minimap stroke color
|
|
3042
|
+
*/
|
|
3043
|
+
this.strokeColor = `rgb(200, 200, 200)`;
|
|
3044
|
+
this.minimapOffset = 10;
|
|
3045
|
+
this.minimapScale = computed(() => {
|
|
3046
|
+
if (this.scaleOnHoverSignal()) {
|
|
3047
|
+
return this.hovered() ? 0.4 : 0.2;
|
|
3048
|
+
}
|
|
3049
|
+
return 0.2;
|
|
3050
|
+
});
|
|
3051
|
+
this.viewportColor = computed(() => this.flowSettingsService.background().color ?? '#fff');
|
|
3052
|
+
this.hovered = signal(false);
|
|
3053
|
+
this.minimapPoint = computed(() => {
|
|
3054
|
+
switch (this.minimapPosition()) {
|
|
3055
|
+
case 'top-left':
|
|
3056
|
+
return { x: this.minimapOffset, y: this.minimapOffset };
|
|
3057
|
+
case 'top-right':
|
|
3058
|
+
return {
|
|
3059
|
+
x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
|
|
3060
|
+
y: this.minimapOffset
|
|
3061
|
+
};
|
|
3062
|
+
case 'bottom-left':
|
|
3063
|
+
return {
|
|
3064
|
+
x: this.minimapOffset,
|
|
3065
|
+
y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
|
|
3066
|
+
};
|
|
3067
|
+
case 'bottom-right':
|
|
3068
|
+
return {
|
|
3069
|
+
x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
|
|
3070
|
+
y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
3073
|
+
});
|
|
3074
|
+
this.minimapWidth = computed(() => this.flowSettingsService.computedFlowWidth() * this.minimapScale());
|
|
3075
|
+
this.minimapHeight = computed(() => this.flowSettingsService.computedFlowHeight() * this.minimapScale());
|
|
3076
|
+
this.viewportTransform = computed(() => {
|
|
3077
|
+
const viewport = this.viewportService.readableViewport();
|
|
3078
|
+
let scale = 1 / viewport.zoom;
|
|
3079
|
+
let x = -(viewport.x * this.minimapScale()) * scale;
|
|
3080
|
+
x /= this.minimapScale();
|
|
3081
|
+
let y = -(viewport.y * this.minimapScale()) * scale;
|
|
3082
|
+
y /= this.minimapScale();
|
|
3083
|
+
scale /= this.minimapScale();
|
|
3084
|
+
return `translate(${x}, ${y}) scale(${scale})`;
|
|
3085
|
+
});
|
|
3086
|
+
this.boundsViewport = computed(() => {
|
|
3087
|
+
const nodes = this.entitiesService.nodes();
|
|
3088
|
+
return getViewportForBounds(getNodesBounds(nodes), this.flowSettingsService.computedFlowWidth(), this.flowSettingsService.computedFlowHeight(), -Infinity, 1.5, 0);
|
|
3089
|
+
});
|
|
3090
|
+
this.minimapTransform = computed(() => {
|
|
3091
|
+
const vport = this.boundsViewport();
|
|
3092
|
+
const x = vport.x * this.minimapScale();
|
|
3093
|
+
const y = vport.y * this.minimapScale();
|
|
3094
|
+
const scale = vport.zoom * this.minimapScale();
|
|
3095
|
+
return `translate(${x} ${y}) scale(${scale})`;
|
|
3096
|
+
});
|
|
3097
|
+
this.minimapPosition = signal('bottom-right');
|
|
3098
|
+
this.scaleOnHoverSignal = signal(false);
|
|
3099
|
+
}
|
|
3100
|
+
/**
|
|
3101
|
+
* The corner of the flow where to render a mini-map
|
|
3102
|
+
*/
|
|
3103
|
+
set position(value) {
|
|
3104
|
+
this.minimapPosition.set(value);
|
|
3105
|
+
}
|
|
3106
|
+
/**
|
|
3107
|
+
* Make a minimap bigger on hover
|
|
3108
|
+
*/
|
|
3109
|
+
set scaleOnHover(value) {
|
|
3110
|
+
this.scaleOnHoverSignal.set(value);
|
|
3111
|
+
}
|
|
3112
|
+
ngOnInit() {
|
|
3113
|
+
const model = new MinimapModel();
|
|
3114
|
+
model.template.set(this.minimap);
|
|
3115
|
+
this.entitiesService.minimap.set(model);
|
|
3116
|
+
}
|
|
3117
|
+
trackNodes(idx, { node }) {
|
|
3118
|
+
return node;
|
|
3119
|
+
}
|
|
3120
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3121
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MiniMapComponent, selector: "mini-map", inputs: { position: "position", maskColor: "maskColor", strokeColor: "strokeColor", scaleOnHover: "scaleOnHover" }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n <ng-container\n *ngFor=\"let model of entitiesService.nodes(); trackBy: trackNodes\"\n >\n <svg:foreignObject\n *ngIf=\"model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType\"\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n\n <svg:rect\n *ngIf=\"model.node.type === 'default-group' || model.node.type === 'template-group'\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n\n </ng-container>\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }] }); }
|
|
3122
|
+
}
|
|
3123
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, decorators: [{
|
|
3124
|
+
type: Component,
|
|
3125
|
+
args: [{ selector: 'mini-map', template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n <ng-container\n *ngFor=\"let model of entitiesService.nodes(); trackBy: trackNodes\"\n >\n <svg:foreignObject\n *ngIf=\"model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType\"\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n\n <svg:rect\n *ngIf=\"model.node.type === 'default-group' || model.node.type === 'template-group'\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n\n </ng-container>\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
|
|
3126
|
+
}], propDecorators: { position: [{
|
|
3127
|
+
type: Input
|
|
3128
|
+
}], maskColor: [{
|
|
3129
|
+
type: Input
|
|
3130
|
+
}], strokeColor: [{
|
|
3131
|
+
type: Input
|
|
3132
|
+
}], scaleOnHover: [{
|
|
3133
|
+
type: Input
|
|
3134
|
+
}], minimap: [{
|
|
3135
|
+
type: ViewChild,
|
|
3136
|
+
args: ['minimap', { static: true }]
|
|
2962
3137
|
}] } });
|
|
2963
3138
|
|
|
2964
3139
|
const components = [
|
|
2965
3140
|
VflowComponent,
|
|
2966
3141
|
NodeComponent,
|
|
3142
|
+
DefaultNodeComponent,
|
|
2967
3143
|
EdgeComponent,
|
|
2968
3144
|
EdgeLabelComponent,
|
|
2969
3145
|
ConnectionComponent,
|
|
@@ -2971,6 +3147,7 @@ const components = [
|
|
|
2971
3147
|
DefsComponent,
|
|
2972
3148
|
BackgroundComponent,
|
|
2973
3149
|
ResizableComponent,
|
|
3150
|
+
MiniMapComponent
|
|
2974
3151
|
];
|
|
2975
3152
|
const directives = [
|
|
2976
3153
|
SpacePointContextDirective,
|
|
@@ -2995,13 +3172,15 @@ class VflowModule {
|
|
|
2995
3172
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2996
3173
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, declarations: [VflowComponent,
|
|
2997
3174
|
NodeComponent,
|
|
3175
|
+
DefaultNodeComponent,
|
|
2998
3176
|
EdgeComponent,
|
|
2999
3177
|
EdgeLabelComponent,
|
|
3000
3178
|
ConnectionComponent,
|
|
3001
3179
|
HandleComponent,
|
|
3002
3180
|
DefsComponent,
|
|
3003
3181
|
BackgroundComponent,
|
|
3004
|
-
ResizableComponent,
|
|
3182
|
+
ResizableComponent,
|
|
3183
|
+
MiniMapComponent, SpacePointContextDirective,
|
|
3005
3184
|
MapContextDirective,
|
|
3006
3185
|
RootSvgReferenceDirective,
|
|
3007
3186
|
RootSvgContextDirective,
|
|
@@ -3017,7 +3196,8 @@ class VflowModule {
|
|
|
3017
3196
|
HandleTemplateDirective], imports: [CommonModule], exports: [VflowComponent,
|
|
3018
3197
|
HandleComponent,
|
|
3019
3198
|
ResizableComponent,
|
|
3020
|
-
SelectableDirective,
|
|
3199
|
+
SelectableDirective,
|
|
3200
|
+
MiniMapComponent, NodeHtmlTemplateDirective,
|
|
3021
3201
|
GroupNodeTemplateDirective,
|
|
3022
3202
|
EdgeLabelHtmlTemplateDirective,
|
|
3023
3203
|
EdgeTemplateDirective,
|
|
@@ -3034,6 +3214,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
3034
3214
|
HandleComponent,
|
|
3035
3215
|
ResizableComponent,
|
|
3036
3216
|
SelectableDirective,
|
|
3217
|
+
MiniMapComponent,
|
|
3037
3218
|
...templateDirectives
|
|
3038
3219
|
],
|
|
3039
3220
|
declarations: [...components, ...directives, ...templateDirectives],
|
|
@@ -3046,5 +3227,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
3046
3227
|
* Generated bundle index. Do not edit.
|
|
3047
3228
|
*/
|
|
3048
3229
|
|
|
3049
|
-
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 };
|
|
3230
|
+
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, ResizableComponent, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode };
|
|
3050
3231
|
//# sourceMappingURL=ngx-vflow.mjs.map
|