Skip to content

Commit af1c44c

Browse files
Feature/shuzarevich/optimize node rect calculation (#231)
* feat: implement connectable side calculation for connectors based on connected positions
1 parent 60223f7 commit af1c44c

File tree

88 files changed

+1085
-868
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1085
-868
lines changed
Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
<f-flow fDraggable (fLoaded)="onLoaded()" (fCreateConnection)="addConnection($event)">
22
<f-canvas>
3-
<f-connection-for-create></f-connection-for-create>
3+
<f-connection-for-create />
44

5-
@for (connection of connections; track connection.inputId) {
6-
<f-connection [fReassignDisabled]="true"
7-
[fOutputId]="connection.outputId" [fInputId]="connection.inputId">
8-
</f-connection>
5+
@for (connection of connections; track connection.inputId) {
6+
<f-connection
7+
[fReassignDisabled]="true"
8+
[fOutputId]="connection.outputId"
9+
[fInputId]="connection.inputId"
10+
/>
911
}
1012

11-
<div fNode fDragHandle [fNodePosition]="{ x: 24, y: 24 }" fNodeOutput fOutputConnectableSide="right">drag me</div>
12-
<div fNode fDragHandle [fNodePosition]="{ x: 244, y: 24 }" fNodeInput fInputConnectableSide="left">to me</div>
13-
13+
<div
14+
fNode
15+
fDragHandle
16+
[fNodePosition]="{ x: 24, y: 24 }"
17+
fNodeOutput
18+
fOutputConnectableSide="right"
19+
>
20+
drag me
21+
</div>
22+
<div
23+
fNode
24+
fDragHandle
25+
[fNodePosition]="{ x: 244, y: 24 }"
26+
fNodeInput
27+
fInputConnectableSide="left"
28+
>
29+
to me
30+
</div>
1431
</f-canvas>
1532
</f-flow>

projects/f-examples/connections/drag-to-reassign/drag-to-reassign.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</f-flow>
1919

2020
<div class="examples-toolbar">
21-
<f-checkbox (change)="reassignStartChange()" [checked]="reassignableStart()"
22-
>Enable Reassign Start</f-checkbox
23-
>
21+
<f-checkbox (change)="reassignStartChange()" [checked]="reassignableStart()">
22+
Enable Reassign Start
23+
</f-checkbox>
2424
</div>

projects/f-flow/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@foblex/flow",
3-
"version": "17.8.3",
3+
"version": "17.8.5",
44
"description": "An Angular library designed to simplify the creation and manipulation of dynamic flow. Provides components for flows, nodes, and connections, automating node manipulation and inter-node connections.",
55
"main": "index.js",
66
"types": "index.d.ts",
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1+
/* eslint-disable */
12
export const F_CSS_CLASS = {
2-
33
DRAG_AND_DROP: {
4-
54
DRAGGING: 'f-dragging',
65

76
CONNECTIONS_DRAGGING: 'f-connections-dragging',
87
},
98

109
GROUPING: {
11-
1210
OVER_BOUNDARY: 'f-grouping-over-boundary',
1311

1412
DROP_ACTIVE: 'f-grouping-drop-active',
1513
},
1614

1715
CONNECTOR: {
18-
1916
OUTPUT_CONNECTED: 'f-node-output-connected',
2017

2118
OUTPUT_NOT_CONNECTABLE: 'f-node-output-not-connectable',
@@ -28,7 +25,6 @@ export const F_CSS_CLASS = {
2825
},
2926

3027
CONNECTION: {
31-
3228
DRAG_HANDLE: 'f-connection-drag-handle',
3329
},
34-
}
30+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FNodeInputBase } from '../../../f-connectors';
2+
import { IPoint } from '@foblex/2d';
3+
4+
export class CalculateSourceConnectorsToConnectRequest {
5+
static readonly fToken = Symbol('CalculateSourceConnectorsToConnectRequest');
6+
7+
constructor(
8+
public readonly targetConnector: FNodeInputBase,
9+
public readonly pointerPosition: IPoint,
10+
) {}
11+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { CalculateSourceConnectorsToConnectRequest } from './calculate-source-connectors-to-connect-request';
2+
import { inject, Injectable } from '@angular/core';
3+
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
4+
import {
5+
EFConnectableSide,
6+
FConnectorBase,
7+
FNodeInputBase,
8+
FNodeOutputBase,
9+
} from '../../../f-connectors';
10+
import { FComponentsStore } from '../../../f-storage';
11+
import { IConnectorAndRect } from '../i-connector-and-rect';
12+
import { GetConnectorAndRectRequest } from '../get-connector-and-rect';
13+
import { IPoint } from '@foblex/2d';
14+
import { CalculateConnectableSideByConnectedPositionsRequest, isCalculateMode } from '../../f-node';
15+
16+
/**
17+
* Execution that retrieves all source connectors that can be connected to a given target connector,
18+
* along with their rectangles.
19+
* Source - Output or Outlet connectors.
20+
*/
21+
@Injectable()
22+
@FExecutionRegister(CalculateSourceConnectorsToConnectRequest)
23+
export class CalculateSourceConnectorsToConnect
24+
implements IExecution<CalculateSourceConnectorsToConnectRequest, IConnectorAndRect[]>
25+
{
26+
private readonly _mediator = inject(FMediator);
27+
private readonly _store = inject(FComponentsStore);
28+
29+
private get _sourceConnectors(): FNodeOutputBase[] {
30+
return this._store.fOutputs as FNodeOutputBase[];
31+
}
32+
33+
public handle({
34+
targetConnector,
35+
pointerPosition,
36+
}: CalculateSourceConnectorsToConnectRequest): IConnectorAndRect[] {
37+
const result = this._getConnectableSources(targetConnector).map((x) => {
38+
return this._mediator.execute<IConnectorAndRect>(new GetConnectorAndRectRequest(x));
39+
});
40+
41+
setTimeout(() => {
42+
this._calculateConnectableSides(result, pointerPosition);
43+
});
44+
45+
return result;
46+
}
47+
48+
private _getConnectableSources(targetConnector: FNodeInputBase): FConnectorBase[] {
49+
return this._sourceConnectors.filter((x) => {
50+
let result = x.canBeConnected;
51+
if (result && x.hasConnectionLimits) {
52+
result = x.canConnectTo(targetConnector);
53+
}
54+
55+
return result;
56+
});
57+
}
58+
59+
private _calculateConnectableSides(
60+
connectors: IConnectorAndRect[],
61+
pointerPosition: IPoint,
62+
): void {
63+
connectors.forEach((x) => {
64+
if (isCalculateMode(x.fConnector.userFConnectableSide)) {
65+
x.fConnector.fConnectableSide = this._calculateByConnectedPositions(
66+
x.fConnector,
67+
pointerPosition,
68+
);
69+
}
70+
});
71+
}
72+
73+
/** Delegates to the connected-positions calculation execution. */
74+
private _calculateByConnectedPositions(
75+
connector: FConnectorBase,
76+
pointerPosition: IPoint,
77+
): EFConnectableSide {
78+
return this._mediator.execute(
79+
new CalculateConnectableSideByConnectedPositionsRequest(connector, pointerPosition),
80+
);
81+
}
82+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './calculate-source-connectors-to-connect-request';
2+
3+
export * from './calculate-source-connectors-to-connect';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { FNodeOutletBase, FNodeOutputBase } from '../../../f-connectors';
2+
import { IPoint } from '@foblex/2d';
3+
4+
export class CalculateTargetConnectorsToConnectRequest {
5+
static readonly fToken = Symbol('CalculateTargetConnectorsToConnectRequest');
6+
constructor(
7+
public readonly sourceConnector: FNodeOutputBase | FNodeOutletBase,
8+
public readonly pointerPosition: IPoint,
9+
) {}
10+
}
Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { GetAllCanBeConnectedInputsAndRectsRequest } from './get-all-can-be-connected-inputs-and-rects.request';
1+
import { CalculateTargetConnectorsToConnectRequest } from './calculate-target-connectors-to-connect-request';
22
import { inject, Injectable } from '@angular/core';
33
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
44
import {
5+
EFConnectableSide,
56
FConnectorBase,
67
FNodeInputBase,
78
FNodeOutletBase,
@@ -10,14 +11,16 @@ import {
1011
import { FComponentsStore } from '../../../f-storage';
1112
import { IConnectorAndRect } from '../i-connector-and-rect';
1213
import { GetConnectorAndRectRequest } from '../get-connector-and-rect';
14+
import { CalculateConnectableSideByConnectedPositionsRequest, isCalculateMode } from '../../f-node';
15+
import { IPoint } from '@foblex/2d';
1316

1417
/**
1518
* Execution that retrieves all input connectors that can be connected to a given output or outlet connector,
1619
*/
1720
@Injectable()
18-
@FExecutionRegister(GetAllCanBeConnectedInputsAndRectsRequest)
19-
export class GetAllCanBeConnectedInputsAndRectsExecution
20-
implements IExecution<GetAllCanBeConnectedInputsAndRectsRequest, IConnectorAndRect[]>
21+
@FExecutionRegister(CalculateTargetConnectorsToConnectRequest)
22+
export class CalculateTargetConnectorsToConnect
23+
implements IExecution<CalculateTargetConnectorsToConnectRequest, IConnectorAndRect[]>
2124
{
2225
private readonly _mediator = inject(FMediator);
2326
private readonly _store = inject(FComponentsStore);
@@ -27,11 +30,18 @@ export class GetAllCanBeConnectedInputsAndRectsExecution
2730
}
2831

2932
public handle({
30-
outputOrOutlet,
31-
}: GetAllCanBeConnectedInputsAndRectsRequest): IConnectorAndRect[] {
32-
return this._getCanBeConnectedInputs(outputOrOutlet).map((x) => {
33-
return this._mediator.execute(new GetConnectorAndRectRequest(x));
33+
sourceConnector,
34+
pointerPosition,
35+
}: CalculateTargetConnectorsToConnectRequest): IConnectorAndRect[] {
36+
const result = this._getCanBeConnectedInputs(sourceConnector).map((x) => {
37+
return this._mediator.execute<IConnectorAndRect>(new GetConnectorAndRectRequest(x));
3438
});
39+
40+
setTimeout(() => {
41+
this._calculateConnectableSides(result, pointerPosition);
42+
});
43+
44+
return result;
3545
}
3646

3747
private _getCanBeConnectedInputs(
@@ -59,4 +69,28 @@ export class GetAllCanBeConnectedInputsAndRectsExecution
5969
): FConnectorBase[] {
6070
return targetConnectors.filter(({ fNodeId }) => outputOrOutlet.fNodeId !== fNodeId);
6171
}
72+
73+
private _calculateConnectableSides(
74+
connectors: IConnectorAndRect[],
75+
pointerPosition: IPoint,
76+
): void {
77+
connectors.forEach((x) => {
78+
if (isCalculateMode(x.fConnector.userFConnectableSide)) {
79+
x.fConnector.fConnectableSide = this._calculateByConnectedPositions(
80+
x.fConnector,
81+
pointerPosition,
82+
);
83+
}
84+
});
85+
}
86+
87+
/** Delegates to the connected-positions calculation execution. */
88+
private _calculateByConnectedPositions(
89+
connector: FConnectorBase,
90+
pointerPosition: IPoint,
91+
): EFConnectableSide {
92+
return this._mediator.execute(
93+
new CalculateConnectableSideByConnectedPositionsRequest(connector, pointerPosition),
94+
);
95+
}
6296
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './calculate-target-connectors-to-connect-request';
2+
3+
export * from './calculate-target-connectors-to-connect';

0 commit comments

Comments
 (0)