-
Notifications
You must be signed in to change notification settings - Fork 45
/
layoutBorderNodes.ts
107 lines (101 loc) · 4.74 KB
/
layoutBorderNodes.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*******************************************************************************
* Copyright (c) 2023, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { CoordinateExtent, Node, XYPosition } from 'reactflow';
import { BorderNodePosition, NodeData } from '../DiagramRenderer.types';
import { DiagramNodeType } from '../node/NodeTypes.types';
import { borderNodeOffset, borderNodeReferencePositionRatio } from './layoutParams';
import { GQLReferencePosition } from '../../graphql/subscription/diagramEventSubscription.types';
export const isEastBorderNode = (borderNode: Node<NodeData>): boolean => {
return borderNode.data.isBorderNode && borderNode.data.borderNodePosition === BorderNodePosition.EAST;
};
export const isWestBorderNode = (borderNode: Node<NodeData>): boolean => {
return borderNode.data.isBorderNode && borderNode.data.borderNodePosition === BorderNodePosition.WEST;
};
export const isNorthBorderNode = (borderNode: Node<NodeData>): boolean => {
return borderNode.data.isBorderNode && borderNode.data.borderNodePosition === BorderNodePosition.NORTH;
};
export const isSouthBorderNode = (borderNode: Node<NodeData>): boolean => {
return borderNode.data.isBorderNode && borderNode.data.borderNodePosition === BorderNodePosition.SOUTH;
};
export const getBorderNodeExtent = (
parentNode: Node<NodeData>,
borderNode: Node<NodeData>
): CoordinateExtent | 'parent' => {
let coordinateExtent: CoordinateExtent | 'parent' = 'parent';
if (parentNode.width && parentNode.height && borderNode.height && borderNode.width) {
coordinateExtent = [
[0 - borderNode.width + borderNodeOffset, 0 - borderNode.height + borderNodeOffset],
[parentNode.width - borderNodeOffset, parentNode.height - borderNodeOffset],
];
}
return coordinateExtent;
};
export const computeBorderNodeExtents = (nodes: Node<NodeData, DiagramNodeType>[]): void => {
nodes
.filter((node) => node.data.isBorderNode)
.forEach((borderNode) => {
const parentNode = nodes.find((node) => node.id === borderNode.parentNode);
if (parentNode) {
borderNode.extent = getBorderNodeExtent(parentNode, borderNode);
}
});
};
export const computeBorderNodePositions = (nodes: Node<NodeData, DiagramNodeType>[]): void => {
nodes
.filter((node) => node.data.isBorderNode)
.forEach((borderNode) => {
const parentNode = nodes.find((node) => node.id === borderNode.parentNode);
if (parentNode) {
const newPosition = findBorderNodePosition(borderNode.position, borderNode, parentNode);
borderNode.data.borderNodePosition = newPosition ?? BorderNodePosition.EAST;
}
});
};
export const findBorderNodePosition = (
borderNodePosition: XYPosition | undefined,
borderNode: Node,
parentNode: Node | undefined
): BorderNodePosition | null => {
if (borderNodePosition && borderNode.width && borderNode.height && parentNode?.width && parentNode.height) {
if (Math.trunc(borderNodePosition.x + borderNode.width) - borderNodeOffset === 0) {
return BorderNodePosition.WEST;
}
if (Math.trunc(borderNodePosition.x) + borderNodeOffset === Math.trunc(parentNode.width)) {
return BorderNodePosition.EAST;
}
if (Math.trunc(borderNodePosition.y + borderNode.height) - borderNodeOffset === 0) {
return BorderNodePosition.NORTH;
}
if (Math.trunc(borderNodePosition.y) + borderNodeOffset === Math.trunc(parentNode.height)) {
return BorderNodePosition.SOUTH;
}
}
return null;
};
export const getNewlyAddedBorderNodePosition = (
newlyAddedNode: Node<NodeData, DiagramNodeType>,
parentNode: Node<NodeData, string> | undefined,
referencePosition: GQLReferencePosition
): void => {
if (parentNode) {
if (referencePosition.position.x < (parentNode.width ?? 0) * borderNodeReferencePositionRatio) {
newlyAddedNode.data.borderNodePosition = BorderNodePosition.WEST;
} else if (referencePosition.position.x > (parentNode.width ?? 0) * (1 - borderNodeReferencePositionRatio)) {
newlyAddedNode.data.borderNodePosition = BorderNodePosition.EAST;
} else if (referencePosition.position.y < (parentNode.height ?? 0) * borderNodeReferencePositionRatio) {
newlyAddedNode.data.borderNodePosition = BorderNodePosition.NORTH;
} else if (referencePosition.position.y > (parentNode.height ?? 0) * (1 - borderNodeReferencePositionRatio)) {
newlyAddedNode.data.borderNodePosition = BorderNodePosition.SOUTH;
}
}
};