Skip to content

Commit 70e6bee

Browse files
authored
feature/COMPASS-9432 Use measured heights or calculate (#72)
1 parent 38508af commit 70e6bee

File tree

2 files changed

+124
-21
lines changed

2 files changed

+124
-21
lines changed

src/utilities/apply-layout.test.ts

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { applyLayout } from '@/utilities/apply-layout';
2-
import { EdgeProps, NodeProps } from '@/types';
2+
import { BaseNode, EdgeProps, NodeProps } from '@/types';
33

44
describe('apply-layout', () => {
55
const nodes: NodeProps[] = [
@@ -50,37 +50,121 @@ describe('apply-layout', () => {
5050
edges: [],
5151
});
5252
});
53-
it('With nodes', async () => {
53+
it('With nodes (not measured, 0 fields)', async () => {
5454
const result = await applyLayout<NodeProps, EdgeProps>(nodes, [], 'TOP_BOTTOM');
5555
expect(result.nodes).toEqual([
5656
expect.objectContaining({
57-
title: 'orders',
58-
fields: [],
59-
type: 'collection',
60-
id: '1',
57+
...nodes[0],
6158
position: {
6259
x: 12,
6360
y: 12,
6461
},
6562
}),
6663
expect.objectContaining({
67-
title: 'customers',
68-
fields: [],
69-
type: 'collection',
70-
id: '2',
64+
...nodes[1],
7165
position: {
7266
x: 12,
73-
y: 32,
67+
y: 76, // 12 + 44 (0 fields height) + 2*10 (padding)
7468
},
7569
}),
7670
expect.objectContaining({
77-
title: 'products',
78-
fields: [],
79-
type: 'collection',
80-
id: '3',
71+
...nodes[2],
72+
position: {
73+
x: 12,
74+
y: 140, // 76 + 44 (0 fields height) + 2*10 (padding)
75+
},
76+
}),
77+
]);
78+
});
79+
it('With nodes (not measured, 1 field)', async () => {
80+
const nodesWithOneField = nodes.map(node => ({
81+
...node,
82+
fields: [{ name: 'field1', type: 'string' }],
83+
}));
84+
const result = await applyLayout<NodeProps, EdgeProps>(nodesWithOneField, [], 'TOP_BOTTOM');
85+
expect(result.nodes).toEqual([
86+
expect.objectContaining({
87+
...nodesWithOneField[0],
88+
position: {
89+
x: 12,
90+
y: 12,
91+
},
92+
}),
93+
expect.objectContaining({
94+
...nodesWithOneField[1],
95+
position: {
96+
x: 12,
97+
y: 94, // 12 + 62 (1 field height) + 2*10 (padding)
98+
},
99+
}),
100+
expect.objectContaining({
101+
...nodesWithOneField[2],
102+
position: {
103+
x: 12,
104+
y: 176, // 94 + 62 (1 field height) + 2*10 (padding)
105+
},
106+
}),
107+
]);
108+
});
109+
it('With nodes (not measured, undefined fields)', async () => {
110+
const baseNodes = nodes.map(node => ({
111+
...node,
112+
fields: undefined,
113+
}));
114+
const result = await applyLayout<BaseNode, EdgeProps>(baseNodes, [], 'TOP_BOTTOM');
115+
expect(result.nodes).toEqual([
116+
expect.objectContaining({
117+
...baseNodes[0],
118+
position: {
119+
x: 12,
120+
y: 12,
121+
},
122+
}),
123+
expect.objectContaining({
124+
...baseNodes[1],
125+
position: {
126+
x: 12,
127+
y: 94, // 12 + 62 (default height) + 2*10 (padding)
128+
},
129+
}),
130+
expect.objectContaining({
131+
...baseNodes[2],
132+
position: {
133+
x: 12,
134+
y: 176, // 94 + 62 (default height) + 2*10 (padding)
135+
},
136+
}),
137+
]);
138+
});
139+
it('With nodes (measured)', async () => {
140+
const measuredNodes = nodes.map(node => ({
141+
...node,
142+
measured: {
143+
width: 100,
144+
height: 50,
145+
},
146+
}));
147+
const result = await applyLayout<NodeProps, EdgeProps>(measuredNodes, [], 'TOP_BOTTOM');
148+
expect(result.nodes).toEqual([
149+
expect.objectContaining({
150+
...measuredNodes[0],
151+
position: {
152+
x: 12,
153+
y: 12,
154+
},
155+
}),
156+
expect.objectContaining({
157+
...measuredNodes[1],
81158
position: {
82159
x: 12,
83-
y: 52,
160+
y: 82, // 12 + 50 (measured node height) + 2*10 (padding)
161+
},
162+
}),
163+
expect.objectContaining({
164+
...measuredNodes[2],
165+
position: {
166+
x: 12,
167+
y: 152, // 82 + 50 (measured node height) + 2*10 (padding)
84168
},
85169
}),
86170
]);
@@ -104,7 +188,7 @@ describe('apply-layout', () => {
104188
id: '1',
105189
position: {
106190
x: 12,
107-
y: 12,
191+
y: 76,
108192
},
109193
}),
110194
expect.objectContaining({
@@ -114,7 +198,7 @@ describe('apply-layout', () => {
114198
id: '2',
115199
position: {
116200
x: 12,
117-
y: 132,
201+
y: 12,
118202
},
119203
}),
120204
expect.objectContaining({
@@ -124,7 +208,7 @@ describe('apply-layout', () => {
124208
id: '3',
125209
position: {
126210
x: 12,
127-
y: 112,
211+
y: 220,
128212
},
129213
}),
130214
]);

src/utilities/apply-layout.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { ElkExtendedEdge } from 'elkjs';
22
import ELK from 'elkjs/lib/elk.bundled';
33

4-
import { DEFAULT_NODE_SPACING, DEFAULT_NODE_STAR_SPACING } from '@/utilities/constants';
4+
import {
5+
DEFAULT_FIELD_HEIGHT,
6+
DEFAULT_FIELD_PADDING,
7+
DEFAULT_NODE_HEADER_HEIGHT,
8+
DEFAULT_NODE_SPACING,
9+
DEFAULT_NODE_STAR_SPACING,
10+
DEFAULT_NODE_WIDTH,
11+
} from '@/utilities/constants';
512
import { ApplyLayout, BaseEdge, BaseNode, LayoutDirection } from '@/types/layout';
613

714
const TOP_BOTTOM = {
@@ -35,6 +42,11 @@ const getLayoutOptions = (direction: LayoutDirection) => {
3542
}
3643
};
3744

45+
const getNodeHeight = <N extends BaseNode>(node: N) => {
46+
const fieldCount = !('fields' in node) || !Array.isArray(node.fields) ? 1 : node.fields.length;
47+
return DEFAULT_NODE_HEADER_HEIGHT + DEFAULT_FIELD_PADDING * 2 + fieldCount * DEFAULT_FIELD_HEIGHT;
48+
};
49+
3850
/**
3951
* Applies a layout to a graph of nodes and edges using the ELK layout engine.
4052
*
@@ -51,6 +63,13 @@ export const applyLayout = <N extends BaseNode, E extends BaseEdge>(
5163
edges: E[],
5264
direction: LayoutDirection = 'TOP_BOTTOM',
5365
): Promise<ApplyLayout<N, E>> => {
66+
const transformedNodes = nodes.map<N>(node => ({
67+
...node,
68+
height:
69+
'height' in node && typeof node.height === 'number' ? node.height : node.measured?.height ?? getNodeHeight(node),
70+
width: 'width' in node && typeof node.width === 'number' ? node.width : node.measured?.width ?? DEFAULT_NODE_WIDTH,
71+
}));
72+
5473
const transformedEdges = edges.map<ElkExtendedEdge>(edge => ({
5574
...edge,
5675
id: edge.id,
@@ -66,7 +85,7 @@ export const applyLayout = <N extends BaseNode, E extends BaseEdge>(
6685
return elk
6786
.layout({
6887
id: 'root',
69-
children: nodes,
88+
children: transformedNodes,
7089
layoutOptions: getLayoutOptions(direction),
7190
edges: transformedEdges,
7291
})

0 commit comments

Comments
 (0)