diff --git a/cypress/e2e/drag-to-connect.component.cy.ts b/cypress/e2e/drag-to-connect.component.cy.ts
index 3718d23..6ab2b55 100644
--- a/cypress/e2e/drag-to-connect.component.cy.ts
+++ b/cypress/e2e/drag-to-connect.component.cy.ts
@@ -4,6 +4,7 @@ describe('DragToConnectComponent', () => {
})
it('should start creating a connection and show connection-for-create element', function () {
+ cy.get('f-flow').scrollIntoView();
cy.get('.f-connection-for-create').should('exist')
.invoke('css', 'display').should('equal', 'none');
diff --git a/cypress/e2e/drag-to-reassign.component.cy.ts b/cypress/e2e/drag-to-reassign.component.cy.ts
index 9aa8f8c..01132c5 100644
--- a/cypress/e2e/drag-to-reassign.component.cy.ts
+++ b/cypress/e2e/drag-to-reassign.component.cy.ts
@@ -3,19 +3,27 @@ describe('DragToReassignComponent', () => {
cy.visit('http://localhost:4200/examples/drag-to-reassign')
})
- it('should drag from input to anoyher input and reassign the connection', function() {
- cy.get('#connection_f-connection-012').should('exist');
-
- cy.get('.f-connection-drag-handle')
- .trigger('mousedown', { button: 0, force: true })
- .trigger('mousemove', { clientX: 0, clientY: 0 })
- .trigger('mousemove', { clientX: 20, clientY: 10 })
- .get('div[data-f-input-id=\'f-node-input-1\']')
- .trigger('mousemove', { clientX: 20, clientY: 10 })
- .trigger('mouseup');
-
- cy.get('#connection_f-connection-012').should('not.exist');
- cy.get('#connection_for_selection_f-connection-11f-node-input-1').should('exist');
+ it('should drag from input to anoyher input and reassign the connection', function () {
+ cy.get('f-flow').scrollIntoView();
+
+ cy.get('#connection_f-connection-01input-1').should('exist');
+ cy.get('div[data-f-input-id=\'input-1\']').should('exist');
+ cy.get('div[data-f-input-id=\'input-2\']').should('exist');
+
+ cy.get('div[data-f-input-id="input-2"]').then(($target) => {
+ const targetRect = $target[ 0 ].getBoundingClientRect();
+ const endY = targetRect.y + targetRect.height / 2;
+
+ cy.get('.f-connection-drag-handle')
+ .trigger('mousedown', { button: 0, force: true })
+ .trigger('mousemove', { clientY: 0, force: true })
+ .get('div[data-f-input-id=\'input-2\']')
+ .trigger('mousemove', { clientY: endY, force: true })
+ .trigger('mouseup', { force: true });
+
+ cy.get('#connection_f-connection-01input-1').should('not.exist');
+ cy.get('#connection_for_selection_f-connection-11input-2').should('exist');
+ });
});
})
diff --git a/cypress/e2e/remove-connection-on-drop.component.cy.ts b/cypress/e2e/remove-connection-on-drop.component.cy.ts
index f266e54..d7e95d5 100644
--- a/cypress/e2e/remove-connection-on-drop.component.cy.ts
+++ b/cypress/e2e/remove-connection-on-drop.component.cy.ts
@@ -4,14 +4,17 @@ describe('RemoveConnectionOnDropComponent', () => {
})
it('should drag connection from input to any place and remove the connection', function () {
+ cy.get('f-flow').scrollIntoView();
cy.get('#connection_f-connection-012').should('exist');
cy.get('.f-connection').should('have.length', 2);
- cy.get('.f-connection-drag-handle').first()
+ cy.get('.f-connection-drag-handle')
+ .first()
.trigger('mousedown', { button: 0, force: true })
- .trigger('mousemove', { clientX: 0, clientY: 0 })
- .trigger('mousemove', { clientX: 420, clientY: 110 })
- .trigger('mouseup');
+ .trigger('mousemove', { clientY: 0, force: true })
+ .trigger('mousemove', { clientY: 200, clientX: 0, force: true })
+ .trigger('mouseup', { force: true });
+
cy.get('#connection_f-connection-012').should('not.exist');
cy.get('.f-connection').should('have.length', 1);
diff --git a/cypress/screenshots/remove-connection-on-drop.component.cy.ts/RemoveConnectionOnDropComponent -- should drag connection from input to any place and remove the connection (failed).png b/cypress/screenshots/remove-connection-on-drop.component.cy.ts/RemoveConnectionOnDropComponent -- should drag connection from input to any place and remove the connection (failed).png
deleted file mode 100644
index ecc752c..0000000
Binary files a/cypress/screenshots/remove-connection-on-drop.component.cy.ts/RemoveConnectionOnDropComponent -- should drag connection from input to any place and remove the connection (failed).png and /dev/null differ
diff --git a/package-lock.json b/package-lock.json
index 0bd4cfa..105083b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
"@angular/router": "^18.2.0",
"@angular/ssr": "^18.2.3",
"@cypress/angular": "^2.1.0",
- "@foblex/2d": "1.1.0",
+ "@foblex/2d": "1.1.4",
"@foblex/drag-toolkit": "1.1.0",
"@foblex/f-docs": "1.4.9",
"@foblex/mediator": "1.1.0",
@@ -2846,9 +2846,9 @@
}
},
"node_modules/@foblex/2d": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@foblex/2d/-/2d-1.1.0.tgz",
- "integrity": "sha512-Fd6jIL9dM6NuqDx5Zn4lLGH2wEtdKoLsR/8iURqw8wIheUcyoQsHAZk07InLxP4yHnGuuspmf7jPelemafMLEw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@foblex/2d/-/2d-1.1.4.tgz",
+ "integrity": "sha512-GRuxnVwZj/g9oZSBvEtAVb7HduFsI54AajtM3HnJw58NPRTRPJYOJ0fO2JmHNklQuqoQhqCeOUrt8RFyRz1yRQ==",
"dependencies": {
"tslib": "^2.3.0"
},
diff --git a/package.json b/package.json
index d5323ec..29e5b61 100644
--- a/package.json
+++ b/package.json
@@ -67,7 +67,7 @@
"@angular/router": "^18.2.0",
"@angular/ssr": "^18.2.3",
"@cypress/angular": "^2.1.0",
- "@foblex/2d": "1.1.0",
+ "@foblex/2d": "1.1.4",
"@foblex/drag-toolkit": "1.1.0",
"@foblex/f-docs": "1.4.9",
"@foblex/mediator": "1.1.0",
diff --git a/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.html b/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.html
index eb5a651..613cf51 100644
--- a/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.html
+++ b/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.html
@@ -8,8 +8,8 @@
}
Output
- Input
- Input
+ Input
+ Input
diff --git a/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.ts b/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.ts
index ec4294d..d6347a7 100644
--- a/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.ts
+++ b/projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.ts
@@ -1,4 +1,9 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild } from '@angular/core';
+import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component, ElementRef, inject,
+ ViewChild
+} from '@angular/core';
import { FCanvasComponent, FFlowModule, FReassignConnectionEvent } from '@foblex/flow';
@Component({
@@ -13,24 +18,22 @@ import { FCanvasComponent, FFlowModule, FReassignConnectionEvent } from '@foblex
})
export class DragToReassignComponent {
+ private _elementReference = inject(ElementRef);
+ private _changeDetectorRef = inject(ChangeDetectorRef);
+
@ViewChild(FCanvasComponent, { static: true })
public fCanvas!: FCanvasComponent;
public connections: { outputId: string, inputId: string }[] = [
- { outputId: '1', inputId: '2' },
+ { outputId: '1', inputId: 'input-1' },
];
- constructor(
- private changeDetectorRef: ChangeDetectorRef
- ) {
- }
-
public reassignConnection(event: FReassignConnectionEvent): void {
- if(!event.newFInputId) {
+ if (!event.newFInputId) {
return;
}
this.connections = [ { outputId: event.fOutputId, inputId: event.newFInputId } ];
- this.changeDetectorRef.detectChanges();
+ this._changeDetectorRef.detectChanges();
}
public onLoaded(): void {
diff --git a/projects/f-examples/connections/remove-connection-on-drop/remove-connection-on-drop.component.ts b/projects/f-examples/connections/remove-connection-on-drop/remove-connection-on-drop.component.ts
index de502ca..25fed51 100644
--- a/projects/f-examples/connections/remove-connection-on-drop/remove-connection-on-drop.component.ts
+++ b/projects/f-examples/connections/remove-connection-on-drop/remove-connection-on-drop.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, inject, ViewChild } from '@angular/core';
import {
FCanvasComponent,
FFlowComponent,
@@ -19,6 +19,9 @@ import { IPoint } from '@foblex/2d';
})
export class RemoveConnectionOnDropComponent {
+ private _elementReference = inject(ElementRef);
+ private _changeDetectorRef = inject(ChangeDetectorRef);
+
@ViewChild(FCanvasComponent, { static: true })
public fCanvas!: FCanvasComponent;
@@ -41,18 +44,13 @@ export class RemoveConnectionOnDropComponent {
{ outputId: this.nodes[1].id, inputId: this.nodes[2].id }
];
- constructor(
- private changeDetectorRef: ChangeDetectorRef
- ) {
- }
-
public onConnectionDropped(event: FReassignConnectionEvent): void {
if (!event.newFInputId) {
this.removeConnection(event);
} else {
this.reassignConnection(event);
}
- this.changeDetectorRef.detectChanges();
+ this._changeDetectorRef.detectChanges();
}
private removeConnection(event: FReassignConnectionEvent): void {
diff --git a/projects/f-flow/package.json b/projects/f-flow/package.json
index 98a1f99..389bbe1 100644
--- a/projects/f-flow/package.json
+++ b/projects/f-flow/package.json
@@ -33,7 +33,7 @@
"@angular/core": ">=15.0.0",
"@foblex/platform": "1.0.4",
"@foblex/mediator": "1.1.0",
- "@foblex/2d": "1.1.0",
+ "@foblex/2d": "1.1.4",
"@foblex/drag-toolkit": "1.1.0",
"@foblex/utils": "1.1.0"
},
diff --git a/projects/f-flow/src/domain/f-canvas/fit-to-flow/fit-to-flow.execution.ts b/projects/f-flow/src/domain/f-canvas/fit-to-flow/fit-to-flow.execution.ts
index a1543bb..9065023 100644
--- a/projects/f-flow/src/domain/f-canvas/fit-to-flow/fit-to-flow.execution.ts
+++ b/projects/f-flow/src/domain/f-canvas/fit-to-flow/fit-to-flow.execution.ts
@@ -3,7 +3,7 @@ import { FitToFlowRequest } from './fit-to-flow-request';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { IPoint, IRect, ITransformModel, PointExtensions, RectExtensions } from '@foblex/2d';
import { FComponentsStore } from '../../../f-storage';
-import { GetNodesRectRequest, RedrawCanvasWithAnimationRequest } from '../../../domain';
+import { CalculateNodesBoundingBoxRequest, RedrawCanvasWithAnimationRequest } from '../../../domain';
@Injectable()
@FExecutionRegister(FitToFlowRequest)
@@ -18,7 +18,7 @@ export class FitToFlowExecution implements IExecution {
private _fMediator = inject(FMediator);
public handle(request: FitToFlowRequest): void {
- const fNodesRect = this._fMediator.send(new GetNodesRectRequest()) || RectExtensions.initialize();
+ const fNodesRect = this._fMediator.send(new CalculateNodesBoundingBoxRequest()) || RectExtensions.initialize();
if (fNodesRect.width === 0 || fNodesRect.height === 0) {
return;
}
diff --git a/projects/f-flow/src/domain/f-canvas/reset-scale-and-center/reset-scale-and-center.execution.ts b/projects/f-flow/src/domain/f-canvas/reset-scale-and-center/reset-scale-and-center.execution.ts
index cd5c64a..40b1d02 100644
--- a/projects/f-flow/src/domain/f-canvas/reset-scale-and-center/reset-scale-and-center.execution.ts
+++ b/projects/f-flow/src/domain/f-canvas/reset-scale-and-center/reset-scale-and-center.execution.ts
@@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { ResetScaleAndCenterRequest } from './reset-scale-and-center-request';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { IPoint, IRect, ITransformModel, PointExtensions, RectExtensions } from '@foblex/2d';
-import { GetNodesRectRequest, RedrawCanvasWithAnimationRequest } from '../../../domain';
+import { CalculateNodesBoundingBoxRequest, RedrawCanvasWithAnimationRequest } from '../../../domain';
import { FComponentsStore } from '../../../f-storage';
@Injectable()
@@ -18,7 +18,7 @@ export class ResetScaleAndCenterExecution implements IExecution(new GetNodesRectRequest()) || RectExtensions.initialize();
+ const fNodesRect = this._fMediator.send(new CalculateNodesBoundingBoxRequest()) || RectExtensions.initialize();
if (fNodesRect.width === 0 || fNodesRect.height === 0) {
return;
}
diff --git a/projects/f-flow/src/domain/f-flow/get-flow/get-flow-request.ts b/projects/f-flow/src/domain/f-flow/get-flow/get-flow-request.ts
new file mode 100644
index 0000000..6194779
--- /dev/null
+++ b/projects/f-flow/src/domain/f-flow/get-flow/get-flow-request.ts
@@ -0,0 +1,3 @@
+export class GetFlowRequest {
+
+}
diff --git a/projects/f-flow/src/domain/f-flow/get-flow/get-flow.execution.ts b/projects/f-flow/src/domain/f-flow/get-flow/get-flow.execution.ts
new file mode 100644
index 0000000..27376c1
--- /dev/null
+++ b/projects/f-flow/src/domain/f-flow/get-flow/get-flow.execution.ts
@@ -0,0 +1,20 @@
+import { inject, Injectable } from '@angular/core';
+import { FExecutionRegister, IExecution } from '@foblex/mediator';
+import { GetFlowRequest } from './get-flow-request';
+import { FComponentsStore } from '../../../f-storage';
+import { FFlowBase } from '../../../f-flow';
+
+@Injectable()
+@FExecutionRegister(GetFlowRequest)
+export class GetFlowExecution implements IExecution {
+
+ private _fComponentsStore = inject(FComponentsStore);
+
+ public handle(request: GetFlowRequest): FFlowBase {
+ const result = this._fComponentsStore.fFlow;
+ if (!result) {
+ throw new Error(`Flow not found in store`);
+ }
+ return result;
+ }
+}
diff --git a/projects/f-flow/src/domain/f-flow/get-flow/index.ts b/projects/f-flow/src/domain/f-flow/get-flow/index.ts
new file mode 100644
index 0000000..8cde4ff
--- /dev/null
+++ b/projects/f-flow/src/domain/f-flow/get-flow/index.ts
@@ -0,0 +1,3 @@
+export * from './get-flow.execution';
+
+export * from './get-flow-request';
diff --git a/projects/f-flow/src/domain/f-flow/index.ts b/projects/f-flow/src/domain/f-flow/index.ts
index 405bed7..02870ff 100644
--- a/projects/f-flow/src/domain/f-flow/index.ts
+++ b/projects/f-flow/src/domain/f-flow/index.ts
@@ -1,5 +1,7 @@
export * from './add-flow-to-store';
+export * from './get-flow';
+
export * from './get-flow-host-element';
export * from './remove-flow-from-store';
diff --git a/projects/f-flow/src/domain/f-flow/providers.ts b/projects/f-flow/src/domain/f-flow/providers.ts
index 4e746fd..3550a17 100644
--- a/projects/f-flow/src/domain/f-flow/providers.ts
+++ b/projects/f-flow/src/domain/f-flow/providers.ts
@@ -1,11 +1,14 @@
import { GetFlowHostElementExecution } from './get-flow-host-element';
import { AddFlowToStoreExecution } from './add-flow-to-store';
import { RemoveFlowFromStoreExecution } from './remove-flow-from-store';
+import { GetFlowExecution } from './get-flow';
export const F_FLOW_FEATURES = [
AddFlowToStoreExecution,
+ GetFlowExecution,
+
GetFlowHostElementExecution,
RemoveFlowFromStoreExecution
diff --git a/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.execution.ts b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.execution.ts
new file mode 100644
index 0000000..db2a58f
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.execution.ts
@@ -0,0 +1,24 @@
+import { IRect, RectExtensions } from '@foblex/2d';
+import { CalculateNodesBoundingBoxRequest } from './calculate-nodes-bounding-box.request';
+import { inject, Injectable } from '@angular/core';
+import { FComponentsStore } from '../../../f-storage';
+import { FExecutionRegister, IExecution } from '@foblex/mediator';
+
+@Injectable()
+@FExecutionRegister(CalculateNodesBoundingBoxRequest)
+export class CalculateNodesBoundingBoxExecution implements IExecution {
+
+ private _fComponentsStore = inject(FComponentsStore);
+
+ public handle(request: CalculateNodesBoundingBoxRequest): IRect | null {
+ return RectExtensions.union(this._getNodesRects());
+ }
+
+ private _getNodesRects(): IRect[] {
+ return this._fComponentsStore.fNodes.map((x) => this._getElementRect(x.hostElement));
+ }
+
+ private _getElementRect(element: HTMLElement): IRect {
+ return RectExtensions.fromElement(element);
+ }
+}
diff --git a/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.request.ts b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.request.ts
new file mode 100644
index 0000000..52a739f
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/calculate-nodes-bounding-box.request.ts
@@ -0,0 +1,3 @@
+export class CalculateNodesBoundingBoxRequest {
+
+}
diff --git a/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/index.ts b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/index.ts
new file mode 100644
index 0000000..c9d1306
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/calculate-nodes-bounding-box/index.ts
@@ -0,0 +1,3 @@
+export * from './calculate-nodes-bounding-box.execution';
+
+export * from './calculate-nodes-bounding-box.request';
diff --git a/projects/f-flow/src/domain/f-node/get-nodes/get-nodes-request.ts b/projects/f-flow/src/domain/f-node/get-nodes/get-nodes-request.ts
new file mode 100644
index 0000000..2607646
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/get-nodes/get-nodes-request.ts
@@ -0,0 +1,3 @@
+export class GetNodesRequest {
+
+}
diff --git a/projects/f-flow/src/domain/f-node/get-nodes/get-nodes.execution.ts b/projects/f-flow/src/domain/f-node/get-nodes/get-nodes.execution.ts
new file mode 100644
index 0000000..dc2b858
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/get-nodes/get-nodes.execution.ts
@@ -0,0 +1,16 @@
+import { inject, Injectable } from '@angular/core';
+import { FExecutionRegister, IExecution } from '@foblex/mediator';
+import { GetNodesRequest } from './get-nodes-request';
+import { FComponentsStore } from '../../../f-storage';
+import { FNodeBase } from '../../../f-node';
+
+@Injectable()
+@FExecutionRegister(GetNodesRequest)
+export class GetNodesExecution implements IExecution {
+
+ private _fComponentsStore = inject(FComponentsStore);
+
+ public handle(request: GetNodesRequest): FNodeBase[] {
+ return this._fComponentsStore.fNodes;
+ }
+}
diff --git a/projects/f-flow/src/domain/f-node/get-nodes/index.ts b/projects/f-flow/src/domain/f-node/get-nodes/index.ts
new file mode 100644
index 0000000..ad51769
--- /dev/null
+++ b/projects/f-flow/src/domain/f-node/get-nodes/index.ts
@@ -0,0 +1,3 @@
+export * from './get-nodes.execution';
+
+export * from './get-nodes-request';
diff --git a/projects/f-flow/src/domain/f-node/index.ts b/projects/f-flow/src/domain/f-node/index.ts
index 2b76a4e..ca4cc6c 100644
--- a/projects/f-flow/src/domain/f-node/index.ts
+++ b/projects/f-flow/src/domain/f-node/index.ts
@@ -1,5 +1,9 @@
export * from './add-node-to-store';
+export * from './calculate-nodes-bounding-box';
+
+export * from './get-nodes';
+
export * from './update-node-when-state-or-size-changed';
export * from './remove-node-from-store';
diff --git a/projects/f-flow/src/domain/f-node/providers.ts b/projects/f-flow/src/domain/f-node/providers.ts
index a38eb5d..3ab8602 100644
--- a/projects/f-flow/src/domain/f-node/providers.ts
+++ b/projects/f-flow/src/domain/f-node/providers.ts
@@ -1,11 +1,17 @@
import { AddNodeToStoreExecution } from './add-node-to-store';
import { RemoveNodeFromStoreExecution } from './remove-node-from-store';
import { UpdateNodeWhenStateOrSizeChangedExecution } from './update-node-when-state-or-size-changed';
+import { GetNodesExecution } from './get-nodes';
+import { CalculateNodesBoundingBoxExecution } from './calculate-nodes-bounding-box';
export const F_NODE_FEATURES = [
AddNodeToStoreExecution,
+ CalculateNodesBoundingBoxExecution,
+
+ GetNodesExecution,
+
UpdateNodeWhenStateOrSizeChangedExecution,
RemoveNodeFromStoreExecution
diff --git a/projects/f-flow/src/domain/f-node/update-node-when-state-or-size-changed/update-node-when-state-or-size-changed.execution.ts b/projects/f-flow/src/domain/f-node/update-node-when-state-or-size-changed/update-node-when-state-or-size-changed.execution.ts
index 3db0d2f..b152656 100644
--- a/projects/f-flow/src/domain/f-node/update-node-when-state-or-size-changed/update-node-when-state-or-size-changed.execution.ts
+++ b/projects/f-flow/src/domain/f-node/update-node-when-state-or-size-changed/update-node-when-state-or-size-changed.execution.ts
@@ -12,7 +12,8 @@ import { FResizeChannel } from '../../../reactivity';
@Injectable()
@FExecutionRegister(UpdateNodeWhenStateOrSizeChangedRequest)
-export class UpdateNodeWhenStateOrSizeChangedExecution implements IExecution {
+export class UpdateNodeWhenStateOrSizeChangedExecution
+ implements IExecution {
private _fMediator = inject(FMediator);
diff --git a/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.execution.ts b/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.execution.ts
deleted file mode 100644
index a9a069d..0000000
--- a/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.execution.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { IRect, RectExtensions } from '@foblex/2d';
-import { GetNodesRectRequest } from './get-nodes-rect.request';
-import { Injectable } from '@angular/core';
-import { FComponentsStore } from '../../f-storage';
-import { FExecutionRegister, IExecution } from '@foblex/mediator';
-import { FNodeBase } from '../../f-node';
-
-@Injectable()
-@FExecutionRegister(GetNodesRectRequest)
-export class GetNodesRectExecution implements IExecution {
-
- constructor(
- private fComponentsStore: FComponentsStore,
- ) {
- }
-
- public handle(request: GetNodesRectRequest): IRect | null {
- return RectExtensions.union(this.getNodesRects());
- }
-
- private getNodesRects(): IRect[] {
- return this.getNodes().map((x) => RectExtensions.fromElement(x.hostElement));
- }
-
- private getNodes(): FNodeBase[] {
- return this.fComponentsStore.fNodes;
- }
-}
diff --git a/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.request.ts b/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.request.ts
deleted file mode 100644
index 7883e63..0000000
--- a/projects/f-flow/src/domain/get-nodes-rect/get-nodes-rect.request.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export class GetNodesRectRequest {
-
-}
diff --git a/projects/f-flow/src/domain/get-nodes-rect/index.ts b/projects/f-flow/src/domain/get-nodes-rect/index.ts
deleted file mode 100644
index 3871659..0000000
--- a/projects/f-flow/src/domain/get-nodes-rect/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './get-nodes-rect.execution';
-
-export * from './get-nodes-rect.request';
diff --git a/projects/f-flow/src/domain/index.ts b/projects/f-flow/src/domain/index.ts
index 9eb0978..d43c793 100644
--- a/projects/f-flow/src/domain/index.ts
+++ b/projects/f-flow/src/domain/index.ts
@@ -30,14 +30,10 @@ export * from './get-flow-state';
export * from './get-scaled-node-rects-with-flow-position';
-export * from './get-nodes-rect';
-
export * from './get-position-in-flow';
export * from './is-connection-under-node';
-export * from './f-connection/redraw-connections';
-
export * from './sort-item-layers';
export * from './update-item-and-children-layers';
diff --git a/projects/f-flow/src/domain/providers.ts b/projects/f-flow/src/domain/providers.ts
index a40a757..65dcdc8 100644
--- a/projects/f-flow/src/domain/providers.ts
+++ b/projects/f-flow/src/domain/providers.ts
@@ -1,5 +1,4 @@
import { GetConnectionLineExecution } from './get-connection-line';
-import { GetNodesRectExecution } from './get-nodes-rect';
import { GetElementRectInFlowExecution } from './get-element-rect-in-flow';
import {
MoveFrontElementsBeforeTargetElementExecution,
@@ -57,8 +56,6 @@ export const COMMON_PROVIDERS = [
GetScaledNodeRectsWithFlowPositionExecution,
- GetNodesRectExecution,
-
GetPositionInFlowExecution,
IsConnectionUnderNodeExecution,
diff --git a/projects/f-flow/src/f-flow/f-flow.component.ts b/projects/f-flow/src/f-flow/f-flow.component.ts
index 515bdf2..8134d09 100644
--- a/projects/f-flow/src/f-flow/f-flow.component.ts
+++ b/projects/f-flow/src/f-flow/f-flow.component.ts
@@ -106,13 +106,17 @@ export class FFlowComponent extends FFlowBase implements OnInit, AfterContentIni
).listen(this._destroyRef,() => {
this._fMediator.send(new RedrawConnectionsRequest());
- if (!this._isLoaded) {
- this._isLoaded = true;
- this.fLoaded.emit();
- }
+ this._emitLoaded();
});
}
+ private _emitLoaded(): void {
+ if (!this._isLoaded) {
+ this._isLoaded = true;
+ this.fLoaded.emit();
+ }
+ }
+
public redraw(): void {
this._fMediator.send(new NotifyDataChangedRequest());
}
diff --git a/projects/f-flow/src/f-minimap/domain/check-rect-is-finite.ts b/projects/f-flow/src/f-minimap/domain/check-rect-is-finite.ts
deleted file mode 100644
index 64e75c3..0000000
--- a/projects/f-flow/src/f-minimap/domain/check-rect-is-finite.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { IRect, RectExtensions } from '@foblex/2d';
-
-export function checkRectIsFinite(rect: IRect): IRect {
- if (!Number.isFinite(rect.width) || !Number.isFinite(rect.height) || !Number.isFinite(rect.x) || !Number.isFinite(rect.y)) {
- return RectExtensions.initialize(0, 0, 0, 0);
- }
- return rect;
-}
diff --git a/projects/f-flow/src/f-minimap/domain/index.ts b/projects/f-flow/src/f-minimap/domain/index.ts
index 8c70a6b..6e4e47b 100644
--- a/projects/f-flow/src/f-minimap/domain/index.ts
+++ b/projects/f-flow/src/f-minimap/domain/index.ts
@@ -4,7 +4,11 @@ export * from './minimap-drag-finalize';
export * from './minimap-drag-preparation';
-export * from './check-rect-is-finite';
+export * from './minimap-draw-nodes';
+
+export * from './minimap-calculate-svg-scale-and-view-box';
+
+export * from './minimap-calculate-view-box';
export * from './f-minimap.drag-handler';
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/i-f-minimap-scale-and-view-box.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/i-f-minimap-scale-and-view-box.ts
new file mode 100644
index 0000000..caed834
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/i-f-minimap-scale-and-view-box.ts
@@ -0,0 +1,8 @@
+import { IRect } from '@foblex/2d';
+
+export interface IFMinimapScaleAndViewBox {
+
+ scale: number;
+
+ viewBox: IRect;
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/index.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/index.ts
new file mode 100644
index 0000000..647140f
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/index.ts
@@ -0,0 +1,6 @@
+export * from './i-f-minimap-scale-and-view-box';
+
+export * from './minimap-calculate-svg-scale-and-view-box.execution';
+
+export * from './minimap-calculate-svg-scale-and-view-box.request';
+
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.execution.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.execution.ts
new file mode 100644
index 0000000..829c41d
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.execution.ts
@@ -0,0 +1,80 @@
+import { inject, Injectable } from '@angular/core';
+import { MinimapCalculateSvgScaleAndViewBoxRequest } from './minimap-calculate-svg-scale-and-view-box.request';
+import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
+import { adjustRectToMinSize, IRect, ISize, RectExtensions, SizeExtensions } from '@foblex/2d';
+import { FComponentsStore } from '../../../f-storage';
+import { FCanvasBase } from '../../../f-canvas';
+import { FFlowBase } from '../../../f-flow';
+import { CalculateNodesBoundingBoxRequest } from '../../../domain';
+import { IFMinimapScaleAndViewBox } from './i-f-minimap-scale-and-view-box';
+
+@Injectable()
+@FExecutionRegister(MinimapCalculateSvgScaleAndViewBoxRequest)
+export class MinimapCalculateSvgScaleAndViewBoxExecution
+ implements IExecution {
+
+ private _fMediator = inject(FMediator);
+
+ private _fComponentStore = inject(FComponentsStore);
+
+ private get _fFlow(): FFlowBase {
+ return this._fComponentStore.fFlow!;
+ }
+
+ private get _fCanvas(): FCanvasBase {
+ return this._fComponentStore.fCanvas!;
+ }
+
+ public handle(request: MinimapCalculateSvgScaleAndViewBoxRequest): IFMinimapScaleAndViewBox {
+ const nodesRect = this._getScaledNodesBoundingBox(request.minSize);
+ const minimapRect = this._getMinimapRect(request.element);
+ const scale = this._calculateViewScale(nodesRect, minimapRect);
+
+ return {
+ scale,
+ viewBox: this._calculateViewBox(nodesRect, minimapRect, scale)
+ }
+ }
+
+ private _getScaledNodesBoundingBox(minSize: number): IRect {
+ const globalRect = this._calculateNodesBoundingBox();
+ const flowRect = this._convertFromGlobalToFlowRect(globalRect);
+ const scaledRect = this._convertRectToMinimapScale(flowRect);
+ return adjustRectToMinSize(scaledRect, minSize);
+ }
+
+ private _calculateNodesBoundingBox(): IRect {
+ return this._fMediator.send(new CalculateNodesBoundingBoxRequest())
+ || RectExtensions.initialize(0, 0, 0, 0);
+ }
+
+ private _convertFromGlobalToFlowRect(rect: IRect): IRect {
+ return RectExtensions.elementTransform(rect, this._fFlow!.hostElement)
+ }
+
+ private _convertRectToMinimapScale(rect: IRect): IRect {
+ return RectExtensions.div(rect, this._fCanvas.transform.scale);
+ }
+
+ private _getMinimapRect(element: SVGSVGElement): IRect {
+ return RectExtensions.elementTransform(RectExtensions.fromElement(element), this._fFlow.hostElement);
+ }
+
+ private _calculateViewScale(nodesRect: IRect, minimapRect: IRect): number {
+ return Math.max(nodesRect.width / minimapRect.width, nodesRect.height / minimapRect.height);
+ }
+
+ private _calculateViewBox(nodesRect: IRect, minimapRect: IRect, scale: number): IRect {
+ return this._calculateCenteredViewBox(nodesRect, this._calculateViewSize(minimapRect, scale));
+ }
+
+ private _calculateViewSize(minimapRect: IRect, scale: number): ISize {
+ return SizeExtensions.initialize(minimapRect.width * scale || 0, minimapRect.height * scale || 0);
+ }
+
+ private _calculateCenteredViewBox(nodesRect: IRect, viewSize: ISize): IRect {
+ const centeredX = nodesRect.x - (viewSize.width - nodesRect.width) / 2;
+ const centeredY = nodesRect.y - (viewSize.height - nodesRect.height) / 2;
+ return RectExtensions.initialize(centeredX, centeredY, viewSize.width, viewSize.height);
+ }
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.request.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.request.ts
new file mode 100644
index 0000000..a2a7499
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-svg-scale-and-view-box/minimap-calculate-svg-scale-and-view-box.request.ts
@@ -0,0 +1,8 @@
+export class MinimapCalculateSvgScaleAndViewBoxRequest {
+
+ constructor(
+ public element: SVGSVGElement,
+ public minSize: number,
+ ) {
+ }
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/index.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/index.ts
new file mode 100644
index 0000000..506e46f
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/index.ts
@@ -0,0 +1,4 @@
+export * from './minimap-calculate-view-box.execution';
+
+export * from './minimap-calculate-view-box.request';
+
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.execution.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.execution.ts
new file mode 100644
index 0000000..79e718b
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.execution.ts
@@ -0,0 +1,37 @@
+import { inject, Injectable } from '@angular/core';
+import { MinimapCalculateViewBoxRequest } from './minimap-calculate-view-box.request';
+import { FExecutionRegister, IExecution } from '@foblex/mediator';
+import { IRect, RectExtensions } from '@foblex/2d';
+import { FComponentsStore } from '../../../f-storage';
+import { FCanvasBase } from '../../../f-canvas';
+import { FFlowBase } from '../../../f-flow';
+
+@Injectable()
+@FExecutionRegister(MinimapCalculateViewBoxRequest)
+export class MinimapCalculateViewBoxExecution implements IExecution {
+
+ private _fComponentStore = inject(FComponentsStore);
+
+ private get _fFlow(): FFlowBase | undefined {
+ return this._fComponentStore.fFlow;
+ }
+
+ private get _fCanvas(): FCanvasBase {
+ return this._fComponentStore.fCanvas!;
+ }
+
+ public handle(request: MinimapCalculateViewBoxRequest): IRect {
+ return this._getRectForMinimapView();
+ }
+
+ private _getRectForMinimapView(): IRect {
+ const result = this._calculateViewBox();
+ result.x = 0;
+ result.y = 0;
+ return result;
+ }
+
+ private _calculateViewBox(): IRect {
+ return RectExtensions.div(RectExtensions.fromElement(this._fFlow!.hostElement), this._fCanvas.transform.scale);
+ }
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.request.ts b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.request.ts
new file mode 100644
index 0000000..e0f6934
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-calculate-view-box/minimap-calculate-view-box.request.ts
@@ -0,0 +1,3 @@
+export class MinimapCalculateViewBoxRequest {
+
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/index.ts b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/index.ts
new file mode 100644
index 0000000..7701e84
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/index.ts
@@ -0,0 +1,4 @@
+export * from './minimap-draw-nodes.execution';
+
+export * from './minimap-draw-nodes.request';
+
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.execution.ts b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.execution.ts
new file mode 100644
index 0000000..72eb130
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.execution.ts
@@ -0,0 +1,62 @@
+import { inject, Injectable } from '@angular/core';
+import { MinimapDrawNodesRequest } from './minimap-draw-nodes.request';
+import { FExecutionRegister, IExecution } from '@foblex/mediator';
+import { createSVGElement } from '../../../domain';
+import { FNodeBase, FNodeDirective } from '../../../f-node';
+import { IRect, RectExtensions, setRectToElement } from '@foblex/2d';
+import { FComponentsStore } from '../../../f-storage';
+import { BrowserService } from '@foblex/platform';
+import { FCanvasBase } from '../../../f-canvas';
+import { FFlowBase } from '../../../f-flow';
+
+@Injectable()
+@FExecutionRegister(MinimapDrawNodesRequest)
+export class MinimapDrawNodesExecution implements IExecution {
+
+ private _fBrowser = inject(BrowserService);
+ private _fComponentStore = inject(FComponentsStore);
+
+ private get _fFlow(): FFlowBase | undefined {
+ return this._fComponentStore.fFlow;
+ }
+
+ private get _fNodes(): FNodeBase[] {
+ return this._fComponentStore.fNodes;
+ }
+
+ private get _fCanvas(): FCanvasBase {
+ return this._fComponentStore.fCanvas!;
+ }
+
+ public handle(request: MinimapDrawNodesRequest): SVGRectElement[] {
+ return this._createMinimapNodeElements(request);
+ }
+
+ private _createMinimapNodeElements(request: MinimapDrawNodesRequest): SVGRectElement[] {
+ return this._fNodes.map((x) => {
+ const element = this._createNodeElement();
+ setRectToElement(this._getNodeRect(x), element);
+ this._applyClassList(element, x, x instanceof FNodeDirective);
+ return element;
+ });
+ }
+
+ private _createNodeElement(): SVGRectElement {
+ return createSVGElement('rect', this._fBrowser);
+ }
+
+ private _getNodeRect(node: FNodeBase): IRect {
+ return RectExtensions.div(this._getNodeRectInFlow(node), this._fCanvas.transform.scale);
+ }
+
+ private _getNodeRectInFlow(node: FNodeBase): IRect {
+ return RectExtensions.elementTransform(RectExtensions.fromElement(node.hostElement), this._fFlow!.hostElement);
+ }
+
+ private _applyClassList(element: SVGRectElement, node: FNodeBase, isNode: boolean): void {
+ element.classList.add('f-component', isNode ? 'f-minimap-node' : 'f-minimap-group');
+ if (node.isSelected()) {
+ element.classList.add('f-selected');
+ }
+ }
+}
diff --git a/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.request.ts b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.request.ts
new file mode 100644
index 0000000..877868a
--- /dev/null
+++ b/projects/f-flow/src/f-minimap/domain/minimap-draw-nodes/minimap-draw-nodes.request.ts
@@ -0,0 +1,3 @@
+export class MinimapDrawNodesRequest {
+
+}
diff --git a/projects/f-flow/src/f-minimap/domain/providers.ts b/projects/f-flow/src/f-minimap/domain/providers.ts
index 0cb821b..6128591 100644
--- a/projects/f-flow/src/f-minimap/domain/providers.ts
+++ b/projects/f-flow/src/f-minimap/domain/providers.ts
@@ -1,6 +1,9 @@
import { MINIMAP_DRAG_PREPARATION_PROVIDERS } from './minimap-drag-preparation';
import { MINIMAP_DRAG_FINALIZE_PROVIDERS } from './minimap-drag-finalize';
import { CalculateFlowPointFromMinimapPointExecution } from './calculate-flow-point-from-minimap-point';
+import { MinimapDrawNodesExecution } from './minimap-draw-nodes';
+import { MinimapCalculateViewBoxExecution } from './minimap-calculate-view-box';
+import { MinimapCalculateSvgScaleAndViewBoxExecution } from './minimap-calculate-svg-scale-and-view-box';
export const F_MINIMAP_DRAG_AND_DROP_PROVIDERS = [
@@ -9,4 +12,10 @@ export const F_MINIMAP_DRAG_AND_DROP_PROVIDERS = [
...MINIMAP_DRAG_FINALIZE_PROVIDERS,
...MINIMAP_DRAG_PREPARATION_PROVIDERS,
+
+ MinimapDrawNodesExecution,
+
+ MinimapCalculateSvgScaleAndViewBoxExecution,
+
+ MinimapCalculateViewBoxExecution,
];
diff --git a/projects/f-flow/src/f-minimap/f-minimap-canvas.directive.ts b/projects/f-flow/src/f-minimap/f-minimap-canvas.directive.ts
index dfb8d0d..cbb3992 100644
--- a/projects/f-flow/src/f-minimap/f-minimap-canvas.directive.ts
+++ b/projects/f-flow/src/f-minimap/f-minimap-canvas.directive.ts
@@ -1,77 +1,32 @@
import {
- Directive, ElementRef,
+ Directive, ElementRef, inject,
} from "@angular/core";
-import { FComponentsStore } from '../f-storage';
-import {
- IRect,
- RectExtensions
-} from '@foblex/2d';
-import { FNodeBase, FNodeDirective } from '../f-node';
-import { BrowserService } from '@foblex/platform';
-import { createSVGElement } from '../domain';
-import { checkRectIsFinite } from './domain';
+import { FMediator } from '@foblex/mediator';
+import { MinimapDrawNodesRequest } from './domain';
@Directive({
selector: 'g[fMinimapCanvas]'
})
export class FMinimapCanvasDirective {
- public get hostElement(): SVGGElement {
- return this.elementReference.nativeElement;
- }
+ private _fMediator = inject(FMediator);
- private get flowHost(): HTMLElement {
- return this.fComponentsStore.flowHost;
- }
+ private _elementReference = inject(ElementRef);
- private get flowScale(): number {
- return this.fComponentsStore.fCanvas!.transform.scale;
- }
-
- constructor(
- private elementReference: ElementRef,
- private fComponentsStore: FComponentsStore,
- private fBrowser: BrowserService
- ) {
+ public get hostElement(): SVGGElement {
+ return this._elementReference.nativeElement;
}
public redraw(): void {
- this.clearCanvas();
- this.fComponentsStore.fNodes.forEach((x) => this.renderNode(x));
- }
-
- private clearCanvas(): void {
- this.hostElement.innerHTML = '';
- }
+ this._clearCanvas();
- private renderNode(node: FNodeBase): void {
- const element = createSVGElement('rect', this.fBrowser);
- this.configureNodeElement(element, node);
- this.hostElement.appendChild(element);
+ this._fMediator.send(new MinimapDrawNodesRequest())
+ .forEach((x) => {
+ this.hostElement.appendChild(x);
+ });
}
- private configureNodeElement(element: SVGRectElement, node: FNodeBase): void {
- this.setElementAttributes(element, this.getNodeRect(node));
- this.applyClassList(element, node, node instanceof FNodeDirective);
- }
-
- private getNodeRect(node: FNodeBase): IRect {
- const nodeRectInFlow = RectExtensions.elementTransform(RectExtensions.fromElement(node.hostElement), this.flowHost);
- return RectExtensions.div(nodeRectInFlow, this.flowScale);
- }
-
- private setElementAttributes(element: SVGRectElement, rect: IRect): void {
- rect = checkRectIsFinite(rect);
- element.setAttribute('x', rect.x.toString());
- element.setAttribute('y', rect.y.toString());
- element.setAttribute('width', rect.width.toString());
- element.setAttribute('height', rect.height.toString());
- }
-
- private applyClassList(element: SVGRectElement, node: FNodeBase, isNode: boolean): void {
- element.classList.add('f-component', isNode ? 'f-minimap-node' : 'f-minimap-group');
- if (node.isSelected()) {
- element.classList.add('f-selected');
- }
+ private _clearCanvas(): void {
+ this.hostElement.innerHTML = '';
}
}
diff --git a/projects/f-flow/src/f-minimap/f-minimap-flow.directive.ts b/projects/f-flow/src/f-minimap/f-minimap-flow.directive.ts
index 04cce11..b6f62c7 100644
--- a/projects/f-flow/src/f-minimap/f-minimap-flow.directive.ts
+++ b/projects/f-flow/src/f-minimap/f-minimap-flow.directive.ts
@@ -1,95 +1,34 @@
import {
- Directive, ElementRef, Input,
+ Directive, ElementRef, inject, Input, OnInit,
} from "@angular/core";
-import { FComponentsStore } from '../f-storage';
-import { IRect, ISize, RectExtensions, SizeExtensions } from '@foblex/2d';
+import { setRectToViewBox } from '@foblex/2d';
import { FMediator } from '@foblex/mediator';
-import { checkRectIsFinite, FMinimapData } from './domain';
-import { GetNodesRectRequest } from '../domain';
+import { FMinimapData, IFMinimapScaleAndViewBox, MinimapCalculateSvgScaleAndViewBoxRequest } from './domain';
@Directive({
selector: 'svg[fMinimapFlow]'
})
export class FMinimapFlowDirective {
- public model: FMinimapData;
-
@Input()
public fMinSize: number = 1000;
- private get flowHost(): HTMLElement {
- return this.fComponentsStore.flowHost;
- }
-
- public get hostElement(): SVGSVGElement {
- return this.elementReference.nativeElement;
- }
-
- constructor(
- private elementReference: ElementRef,
- private fMediator: FMediator,
- private fComponentsStore: FComponentsStore
- ) {
- this.model = new FMinimapData(this.hostElement);
- }
-
- public update(): void {
- const nodesRect = this.getProcessedNodesRect();
- const minimapRect = this.getMinimapRect();
-
- const scale = this.calculateViewScale(nodesRect, minimapRect);
- const viewBox = this.calculateViewBox(nodesRect, minimapRect, scale);
- this.model = new FMinimapData(this.hostElement, scale, viewBox);
- this.setViewBox(viewBox);
- }
-
- private getProcessedNodesRect(): IRect {
- const normalizedRect = this.normalizeRect(this.getNodesRect());
- return this.ensureMinimumSize(normalizedRect);
- }
+ private _fMediator = inject(FMediator);
- private getNodesRect(): IRect {
- const rect = this.fMediator.send(new GetNodesRectRequest()) || RectExtensions.initialize(0, 0, 0, 0);
- return RectExtensions.elementTransform(rect, this.flowHost)
- }
+ private _elementReference = inject(ElementRef);
- private getMinimapRect(): IRect {
- return RectExtensions.elementTransform(RectExtensions.fromElement(this.hostElement), this.flowHost);
+ public get hostElement(): SVGSVGElement {
+ return this._elementReference.nativeElement;
}
- private normalizeRect(rect: IRect): IRect {
- return RectExtensions.div(rect, this.fComponentsStore.fCanvas!.transform.scale);
- }
+ public model: FMinimapData = new FMinimapData(this.hostElement);
- private ensureMinimumSize(rect: IRect): IRect {
- return RectExtensions.initialize(
- rect.x - (Math.max(rect.width, this.fMinSize) - rect.width) / 2,
- rect.y - (Math.max(rect.height, this.fMinSize) - rect.height) / 2,
- Math.max(rect.width, this.fMinSize),
- Math.max(rect.height, this.fMinSize)
+ public redraw(): void {
+ const { scale, viewBox} = this._fMediator.send(
+ new MinimapCalculateSvgScaleAndViewBoxRequest(this.hostElement, this.fMinSize)
);
- }
-
- private calculateViewScale(nodesRect: IRect, minimapRect: IRect): number {
- return Math.max(nodesRect.width / minimapRect.width, nodesRect.height / minimapRect.height);
- }
-
- private calculateViewBox(nodesRect: IRect, minimapRect: IRect, scale: number): IRect {
- return this.calculateCenteredViewBox(nodesRect, this.calculateViewSize(minimapRect, scale));
- }
-
- private calculateViewSize(minimapRect: IRect, scale: number): ISize {
- return SizeExtensions.initialize(minimapRect.width * scale || 0, minimapRect.height * scale || 0);
- }
-
- private calculateCenteredViewBox(nodesRect: IRect, viewSize: ISize): IRect {
- const centeredX = nodesRect.x - (viewSize.width - nodesRect.width) / 2;
- const centeredY = nodesRect.y - (viewSize.height - nodesRect.height) / 2;
- return RectExtensions.initialize(centeredX, centeredY, viewSize.width, viewSize.height);
- }
+ this.model = new FMinimapData(this.hostElement, scale, viewBox);
- private setViewBox(viewBox: IRect): void {
- viewBox = checkRectIsFinite(viewBox);
- this.hostElement.setAttribute('viewBox', `${ viewBox.x } ${ viewBox.y } ${ viewBox.width } ${ viewBox.height }`);
+ setRectToViewBox(viewBox, this.hostElement);
}
}
diff --git a/projects/f-flow/src/f-minimap/f-minimap-view.directive.ts b/projects/f-flow/src/f-minimap/f-minimap-view.directive.ts
index cdffc1e..579d027 100644
--- a/projects/f-flow/src/f-minimap/f-minimap-view.directive.ts
+++ b/projects/f-flow/src/f-minimap/f-minimap-view.directive.ts
@@ -1,7 +1,7 @@
-import { Directive, ElementRef } from "@angular/core";
-import { FComponentsStore } from '../f-storage';
-import { IRect, RectExtensions } from '@foblex/2d';
-import { checkRectIsFinite } from './domain';
+import { Directive, ElementRef, inject } from "@angular/core";
+import { IRect, setRectToElement } from '@foblex/2d';
+import { FMediator } from '@foblex/mediator';
+import { MinimapCalculateViewBoxRequest } from './domain';
@Directive({
selector: 'rect[fMinimapView]',
@@ -11,33 +11,18 @@ import { checkRectIsFinite } from './domain';
})
export class FMinimapViewDirective {
- public get hostElement(): SVGRectElement {
- return this.elementReference.nativeElement;
- }
-
- private get flowScale(): number {
- return this.fComponentsStore!.fCanvas!.transform.scale!;
- }
+ private _fMediator = inject(FMediator);
- constructor(
- private elementReference: ElementRef,
- private fComponentsStore: FComponentsStore
- ) {
- }
-
- public update(): void {
- this._setAttributes(this._calculateViewBox());
- }
+ private _elementReference = inject(ElementRef);
- private _calculateViewBox(): IRect {
- return RectExtensions.div(RectExtensions.fromElement(this.fComponentsStore.flowHost), this.flowScale);
+ public get hostElement(): SVGGElement {
+ return this._elementReference.nativeElement;
}
- private _setAttributes(viewBox: IRect): void {
- viewBox = checkRectIsFinite(viewBox);
- this.hostElement.setAttribute('x', '0');
- this.hostElement.setAttribute('y', '0');
- this.hostElement.setAttribute('width', viewBox.width.toString());
- this.hostElement.setAttribute('height', viewBox.height.toString());
+ public redraw(): void {
+ setRectToElement(
+ this._fMediator.send(new MinimapCalculateViewBoxRequest()),
+ this.hostElement
+ );
}
}
diff --git a/projects/f-flow/src/f-minimap/f-minimap.component.ts b/projects/f-flow/src/f-minimap/f-minimap.component.ts
index 6c5648e..424ea1f 100644
--- a/projects/f-flow/src/f-minimap/f-minimap.component.ts
+++ b/projects/f-flow/src/f-minimap/f-minimap.component.ts
@@ -58,8 +58,8 @@ export class FMinimapComponent implements AfterViewInit, IFDragAndDropPlugin {
if (!this._fBrowser.isBrowser()) {
return;
}
- this.fMinimapFlow.update();
- this.fMinimapView.update();
+ this.fMinimapFlow.redraw();
+ this.fMinimapView.redraw();
this.fMinimapCanvas.redraw();
}