Skip to content

Commit 53fce94

Browse files
Merge pull request #234 from Foblex/feature/shuzarevich/optimize-node-rect-calculation
This pull request introduces significant functionality enhancements including connection connectable side features, a new AdaptiveCurveBuilder for improved connection rendering, layout engine optimizations, and performance improvements through caching mechanisms. Key changes include: Added connection connectable side functionality with new enum EFConnectionConnectableSide allowing manual or calculated side determination Implemented AdaptiveCurveBuilder for smoother, context-aware connection curves Introduced rectangle caching with rect-extensions.cache.ts and DragRectCache for performance optimization
2 parents af1c44c + 22a0d91 commit 53fce94

File tree

74 files changed

+1422
-382
lines changed

Some content is hidden

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

74 files changed

+1422
-382
lines changed

commitlint.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ module.exports = {
22
extends: ['@commitlint/config-conventional'],
33
rules: {
44
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
5-
'header-max-length': [2, 'always', 100],
5+
'header-max-length': [0, 'always', Infinity],
6+
'body-max-line-length': [0, 'always', Infinity],
67
'type-enum': [
78
2,
89
'always',
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<f-flow fDraggable (fLoaded)="loaded()">
2+
<f-canvas>
3+
<f-connection
4+
fOutputId="1"
5+
fInputId="2"
6+
fBehavior="fixed"
7+
fType="bezier"
8+
[fOutputSide]="connection1SourceSide()"
9+
[fInputSide]="connection1TargetSide()"
10+
>
11+
<div fConnectionContent position="0.2" align="along">{{ connection1SourceSide()}}</div>
12+
<div fConnectionContent position="0.8" align="along">{{ connection1TargetSide()}}</div>
13+
</f-connection>
14+
<f-connection
15+
fOutputId="1"
16+
fInputId="3"
17+
fBehavior="fixed"
18+
fType="bezier"
19+
[fOutputSide]="connection2SourceSide()"
20+
[fInputSide]="connection2TargetSide()"
21+
>
22+
<div fConnectionContent position="0.2" align="along">{{ connection2SourceSide()}}</div>
23+
<div fConnectionContent position="0.8" align="along">{{ connection2TargetSide()}}</div>
24+
</f-connection>
25+
<f-connection
26+
fOutputId="1"
27+
fInputId="4"
28+
fBehavior="fixed"
29+
fType="bezier"
30+
[fOutputSide]="connection3SourceSide()"
31+
[fInputSide]="connection3TargetSide()"
32+
>
33+
<div fConnectionContent position="0.2" align="along">{{ connection3SourceSide()}}</div>
34+
<div fConnectionContent position="0.8" align="along">{{ connection3TargetSide()}}</div>
35+
</f-connection>
36+
37+
<div fNode fDragHandle [fNodePosition]="{ x: 250, y: 0 }" fNodeOutput fOutputId="1">Node1</div>
38+
39+
<div fNode fDragHandle [fNodePosition]="{ x: 0, y: 150 }" fNodeInput fInputId="2">Node2</div>
40+
<div fNode fDragHandle [fNodePosition]="{ x: 250, y: 300 }" fNodeInput fInputId="3">Node3</div>
41+
<div fNode fDragHandle [fNodePosition]="{ x: 500, y: 150 }" fNodeInput fInputId="4">Node4</div>
42+
</f-canvas>
43+
</f-flow>
44+
<div class="examples-toolbar">
45+
<button class="f-button" (click)="switchSides()" [disabled]="calculateSides()">
46+
Switch Sides
47+
</button>
48+
</div>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@use '../../flow-common';
2+
3+
::ng-deep f-flow {
4+
@include flow-common.connection;
5+
6+
.f-connection-content {
7+
font-size: 13px;
8+
padding: 2px 8px;
9+
background: var(--node-background-color);
10+
border-radius: var(--node-border-radius);
11+
border: 0.2px solid var(--node-border-color);
12+
}
13+
}
14+
15+
.f-node {
16+
@include flow-common.node;
17+
}
18+
19+
@include flow-common.examples-toolbar;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { ChangeDetectionStrategy, Component, signal, viewChild } from '@angular/core';
2+
import {
3+
EFConnectionConnectableSide,
4+
FCanvasComponent,
5+
FConnectionContent,
6+
FFlowModule,
7+
} from '@foblex/flow';
8+
9+
@Component({
10+
selector: 'connectable-connectable-side',
11+
styleUrls: ['./connection-connectable-side.scss'],
12+
templateUrl: './connection-connectable-side.html',
13+
changeDetection: ChangeDetectionStrategy.OnPush,
14+
standalone: true,
15+
imports: [FFlowModule, FConnectionContent],
16+
})
17+
export class ConnectionConnectableSide {
18+
private readonly _canvas = viewChild.required(FCanvasComponent);
19+
20+
protected readonly calculateSides = signal(false);
21+
22+
protected readonly connection1SourceSide = signal(EFConnectionConnectableSide.TOP);
23+
protected readonly connection1TargetSide = signal(EFConnectionConnectableSide.RIGHT);
24+
protected readonly connection2SourceSide = signal(EFConnectionConnectableSide.BOTTOM);
25+
protected readonly connection2TargetSide = signal(EFConnectionConnectableSide.LEFT);
26+
protected readonly connection3SourceSide = signal(EFConnectionConnectableSide.CALCULATE);
27+
protected readonly connection3TargetSide = signal(EFConnectionConnectableSide.CALCULATE_VERTICAL);
28+
29+
protected loaded(): void {
30+
this._canvas()?.resetScaleAndCenter(false);
31+
}
32+
33+
protected switchSides(): void {
34+
this.connection1SourceSide.update((x) => this._updateSide(x));
35+
this.connection1TargetSide.update((x) => this._updateSide(x));
36+
this.connection2SourceSide.update((x) => this._updateSide(x));
37+
this.connection2TargetSide.update((x) => this._updateSide(x));
38+
this.connection3SourceSide.update((x) => this._updateSide(x));
39+
this.connection3TargetSide.update((x) => this._updateSide(x));
40+
}
41+
42+
private _updateSide(currentSide: EFConnectionConnectableSide): EFConnectionConnectableSide {
43+
const sides = Object.values(EFConnectionConnectableSide);
44+
const index = sides.indexOf(currentSide);
45+
46+
return sides[(index + 1) % sides.length];
47+
}
48+
}

projects/f-examples/connections/connection-types/connection-types.component.html

Lines changed: 0 additions & 30 deletions
This file was deleted.

projects/f-examples/connections/connection-types/connection-types.component.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<f-flow fDraggable (fLoaded)="loaded()">
2+
<f-canvas>
3+
<f-connection [fReassignDisabled]="true" fType="straight" fOutputId="1" fInputId="2" />
4+
<div
5+
fNode
6+
fDragHandle
7+
[fNodePosition]="{ x: 0, y: 0 }"
8+
fNodeOutput
9+
fOutputId="1"
10+
fOutputConnectableSide="right"
11+
>
12+
Node
13+
</div>
14+
<div
15+
fNode
16+
fDragHandle
17+
[fNodePosition]="{ x: 200, y: 50 }"
18+
fNodeInput
19+
fInputId="2"
20+
fInputConnectableSide="left"
21+
>
22+
Node
23+
</div>
24+
25+
<f-connection [fReassignDisabled]="true" fType="segment" fOutputId="3" fInputId="4" />
26+
<div
27+
fNode
28+
fDragHandle
29+
[fNodePosition]="{ x: 0, y: 150 }"
30+
fNodeOutput
31+
fOutputId="3"
32+
fOutputConnectableSide="right"
33+
>
34+
Node
35+
</div>
36+
<div
37+
fNode
38+
fDragHandle
39+
[fNodePosition]="{ x: 200, y: 200 }"
40+
fNodeInput
41+
fInputId="4"
42+
fInputConnectableSide="left"
43+
>
44+
Node
45+
</div>
46+
47+
<f-connection [fReassignDisabled]="true" fType="bezier" fOutputId="5" fInputId="6" />
48+
<div
49+
fNode
50+
fDragHandle
51+
[fNodePosition]="{ x: 0, y: 300 }"
52+
fNodeOutput
53+
fOutputId="5"
54+
fOutputConnectableSide="right"
55+
>
56+
Node
57+
</div>
58+
<div
59+
fNode
60+
fDragHandle
61+
[fNodePosition]="{ x: 200, y: 350 }"
62+
fNodeInput
63+
fInputId="6"
64+
fInputConnectableSide="left"
65+
>
66+
Node
67+
</div>
68+
<f-connection [fReassignDisabled]="true" fType="adaptive-curve" fOutputId="7" fInputId="8" />
69+
<div
70+
fNode
71+
fDragHandle
72+
[fNodePosition]="{ x: 0, y: 450 }"
73+
fNodeOutput
74+
fOutputId="7"
75+
fOutputConnectableSide="right"
76+
>
77+
Node
78+
</div>
79+
<div
80+
fNode
81+
fDragHandle
82+
[fNodePosition]="{ x: 200, y: 500 }"
83+
fNodeInput
84+
fInputId="8"
85+
fInputConnectableSide="left"
86+
>
87+
Node
88+
</div>
89+
</f-canvas>
90+
</f-flow>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@use "../../flow-common";
1+
@use '../../flow-common';
22

33
::ng-deep f-flow {
44
@include flow-common.connection;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ChangeDetectionStrategy, Component, viewChild } from '@angular/core';
2+
import { FCanvasComponent, FFlowModule } from '@foblex/flow';
3+
4+
@Component({
5+
selector: 'connection-types',
6+
styleUrls: ['./connection-types.scss'],
7+
templateUrl: './connection-types.html',
8+
changeDetection: ChangeDetectionStrategy.OnPush,
9+
standalone: true,
10+
imports: [FFlowModule],
11+
})
12+
export class ConnectionTypes {
13+
private readonly _canvas = viewChild.required(FCanvasComponent);
14+
15+
protected loaded(): void {
16+
this._canvas()?.resetScaleAndCenter(false);
17+
}
18+
}

projects/f-examples/connectors/connectable-side/connectable-side.html

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<f-flow fDraggable (fLoaded)="loaded()">
22
<f-canvas>
33
<f-connection fOutputId="1" fInputId="2" fBehavior="fixed" fType="segment" />
4+
<f-connection fOutputId="1" fInputId="3" fBehavior="fixed" fType="segment" />
5+
<f-connection fOutputId="1" fInputId="4" fBehavior="fixed" fType="segment" />
46

57
<div
68
fNode
79
fDragHandle
8-
[fNodePosition]="{ x: 0, y: 0 }"
10+
[fNodePosition]="{ x: 250, y: 0 }"
911
fNodeOutput
1012
fOutputId="1"
1113
[fOutputConnectableSide]="node1Side()"
@@ -16,13 +18,33 @@
1618
<div
1719
fNode
1820
fDragHandle
19-
[fNodePosition]="{ x: 150, y: 150 }"
21+
[fNodePosition]="{ x: 0, y: 150 }"
2022
fNodeInput
2123
fInputId="2"
2224
[fInputConnectableSide]="node2Side()"
2325
>
2426
<b>{{ node2Side() }}</b> connectable side
2527
</div>
28+
<div
29+
fNode
30+
fDragHandle
31+
[fNodePosition]="{ x: 250, y: 300 }"
32+
fNodeInput
33+
fInputId="3"
34+
[fInputConnectableSide]="node3Side()"
35+
>
36+
<b>{{ node3Side() }}</b> connectable side
37+
</div>
38+
<div
39+
fNode
40+
fDragHandle
41+
[fNodePosition]="{ x: 500, y: 150 }"
42+
fNodeInput
43+
fInputId="4"
44+
[fInputConnectableSide]="node4Side()"
45+
>
46+
<b>{{ node4Side() }}</b> connectable side
47+
</div>
2648
</f-canvas>
2749
</f-flow>
2850
<div class="examples-toolbar">

0 commit comments

Comments
 (0)