Skip to content

Commit 613fbe6

Browse files
committed
fix: review fixes
1 parent fe2651b commit 613fbe6

File tree

7 files changed

+80
-66
lines changed

7 files changed

+80
-66
lines changed

src/components/Graph/BlockComponents/StageBlockComponent.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {Text} from '@gravity-ui/uikit';
22

33
import {TooltipComponent} from '../TooltipComponent';
4+
import i18n from '../i18n';
45
import type {ExtendedTBlock} from '../types';
56

67
type Props = {
@@ -16,7 +17,7 @@ export const StageBlockComponent = ({className, block}: Props) => {
1617
: block.name}
1718
{block.tables ? (
1819
<div>
19-
<Text color="secondary">Tables: </Text>
20+
<Text color="secondary">{i18n('label_tables')}: </Text>
2021
{block.tables.join(', ')}
2122
</div>
2223
) : null}

src/components/Graph/GraphControls.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {useCallback} from 'react';
2+
13
import type {Graph} from '@gravity-ui/graph';
24
import {Button, Icon} from '@gravity-ui/uikit';
35

@@ -15,19 +17,19 @@ interface Props {
1517
}
1618

1719
export const GraphControls = ({graph}: Props) => {
18-
const onZoomInClick = () => {
20+
const onZoomInClick = useCallback(() => {
1921
const cameraScale = graph.cameraService.getCameraScale();
2022
graph.zoom({scale: cameraScale * ZOOM_STEP});
21-
};
23+
}, [graph]);
2224

23-
const onZoomOutClick = () => {
25+
const onZoomOutClick = useCallback(() => {
2426
const cameraScale = graph.cameraService.getCameraScale();
2527
graph.zoom({scale: cameraScale / ZOOM_STEP});
26-
};
28+
}, [graph]);
2729

28-
const onResetZoomClick = () => {
30+
const onResetZoomClick = useCallback(() => {
2931
graph.zoom({scale: 1});
30-
};
32+
}, [graph]);
3133

3234
return (
3335
<div className={b('zoom-controls')}>

src/components/Graph/GravityGraph.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function GravityGraph<T>({data, theme}: Props<T>) {
6666
const {graph, start} = useGraph(config);
6767

6868
React.useEffect(() => {
69-
// на всякий случай, хотя маунт больше времени занимает, чем расчёт
69+
// Just in case, although mounting takes more time than calculation
7070
const worker = new Worker(new URL('./treeLayout', import.meta.url));
7171
worker.postMessage({
7272
nodes: data.nodes,

src/components/Graph/TooltipComponent.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useState} from 'react';
1+
import React, {useMemo, useState} from 'react';
22

33
import {Popover, Tab, TabList, TabPanel, TabProvider} from '@gravity-ui/uikit';
44

@@ -43,21 +43,24 @@ const useTooltipContent = (block: ExtendedTBlock) => {
4343
const firstTab = block?.stats?.[0]?.group || '';
4444
const [activeTab, setActiveTab] = useState(firstTab);
4545

46-
return (
47-
<TabProvider value={activeTab} onUpdate={setActiveTab}>
48-
<TabList className={b('tooltip-tabs')}>
46+
return useMemo(
47+
() => (
48+
<TabProvider value={activeTab} onUpdate={setActiveTab}>
49+
<TabList className={b('tooltip-tabs')}>
50+
{block?.stats?.map((item) => (
51+
<Tab value={item.group} key={item.group}>
52+
{item.group}
53+
</Tab>
54+
))}
55+
</TabList>
4956
{block?.stats?.map((item) => (
50-
<Tab value={item.group} key={item.group}>
51-
{item.group}
52-
</Tab>
57+
<TabPanel value={item.group} key={item.group}>
58+
{item.stats?.map(getStatsContent)}
59+
</TabPanel>
5360
))}
54-
</TabList>
55-
{block?.stats?.map((item) => (
56-
<TabPanel value={item.group} key={item.group}>
57-
{item.stats?.map(getStatsContent)}
58-
</TabPanel>
59-
))}
60-
</TabProvider>
61+
</TabProvider>
62+
),
63+
[block?.stats, activeTab],
6164
);
6265
};
6366

src/components/Graph/i18n/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"label_tables": "Tables"
3+
}

src/components/Graph/i18n/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {registerKeysets} from '../../../utils/i18n';
2+
3+
import en from './en.json';
4+
5+
const COMPONENT = 'ydb-gravity-graph';
6+
7+
export default registerKeysets(COMPONENT, {en});

src/components/Graph/treeLayout.ts

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,27 @@ class TreeLayoutEngine {
1414
this.blocks = new Map(blocks.map((block: any) => [block.id, {...block}]));
1515
this.connections = connections;
1616

17-
// Настройки отступов
17+
// Layout settings
1818
this.options = {
19-
horizontalSpacing: options.horizontalSpacing || 40, // расстояние между блоками по горизонтали
20-
verticalSpacing: options.verticalSpacing || 20, // расстояние между уровнями
19+
horizontalSpacing: options.horizontalSpacing || 40, // horizontal distance between blocks
20+
verticalSpacing: options.verticalSpacing || 20, // vertical distance between levels
2121
...options,
2222
};
2323

2424
this.tree = null;
2525
this.levels = [];
2626
}
2727

28-
// Построение структуры дерева
28+
// Building a tree structure
2929
buildTree() {
30-
// Создаем карты родителей и детей
3130
const childrenMap = new Map();
3231
const parentMap = new Map();
3332

34-
// Инициализируем карты
3533
for (const block of this.blocks.values()) {
3634
childrenMap.set(block.id, []);
3735
}
3836

39-
// Заполняем связи
37+
// Setting connections
4038
for (const connection of this.connections) {
4139
const parent = connection.sourceBlockId;
4240
const child = connection.targetBlockId;
@@ -45,14 +43,14 @@ class TreeLayoutEngine {
4543
parentMap.set(child, parent);
4644
}
4745

48-
// Находим корневой узел (узел без родителя)
46+
// Find root (a node without a parent)
4947
const rootId = Array.from(this.blocks.keys()).find((id) => !parentMap.has(id));
5048

5149
if (!rootId) {
5250
throw new Error('Root node not found');
5351
}
5452

55-
// Рекурсивно строим дерево
53+
// Recursively building a tree
5654
const buildNode = (nodeId: string, level = 0): TreeNode => {
5755
const block = this.blocks.get(nodeId);
5856
const children = childrenMap
@@ -74,7 +72,7 @@ class TreeLayoutEngine {
7472
return this.tree;
7573
}
7674

77-
// Группировка узлов по уровням
75+
// Grouping nodes by levels
7876
groupByLevels(node: TreeNode | null = this.tree, levels: TreeNode[][] = []): TreeNode[][] {
7977
if (!node) {
8078
return levels;
@@ -93,65 +91,65 @@ class TreeLayoutEngine {
9391
return levels;
9492
}
9593

96-
// Вычисление ширины поддерева для каждого узла
94+
// Calculating the width of the subtree for each node
9795
calculateSubtreeWidths(node: TreeNode = this.tree!): number {
9896
if (node.children.length === 0) {
99-
// Листовой узел - ширина равна ширине блока
97+
// Leaf node - width is equal to the width of the block
10098
node.subtreeWidth = node.block.width;
10199
} else {
102-
// Рекурсивно вычисляем ширину для детей
100+
// Recursively calculating the width for children
103101
for (const child of node.children) {
104102
this.calculateSubtreeWidths(child);
105103
}
106104

107-
// Ширина поддерева = сумма ширин поддеревьев детей + отступы между ними
105+
// Subtree width = sum of the widths of the children's subtrees + the margins between them
108106
const childrenWidth = node.children.reduce(
109107
(sum: number, child: TreeNode) => sum + child.subtreeWidth,
110108
0,
111109
);
112110
const spacingWidth = (node.children.length - 1) * this.options.horizontalSpacing;
113111
const totalChildrenWidth = childrenWidth + spacingWidth;
114112

115-
// Ширина поддерева = максимум из ширины самого узла и суммарной ширины детей
113+
// Subtree width = the maximum of the width of the node itself and the total width of the children
116114
node.subtreeWidth = Math.max(node.block.width, totalChildrenWidth);
117115
}
118116

119117
return node.subtreeWidth;
120118
}
121119

122-
// Размещение узлов по позициям
120+
// Placement of nodes by position
123121
positionNodes() {
124122
if (!this.tree) {
125123
return;
126124
}
127125

128-
// Вычисляем Y координаты для каждого уровня
126+
// Calculating the Y coordinates for each level
129127
let currentY = 0;
130128
const levelY: number[] = [];
131129

132130
for (let level = 0; level < this.levels.length; level++) {
133131
levelY[level] = currentY;
134132

135-
// Находим максимальную высоту блоков на этом уровне
133+
// We find the maximum height of the blocks at this level
136134
const maxHeight = Math.max(
137135
...this.levels[level].map((node: TreeNode) => node.block.height),
138136
);
139137
currentY += maxHeight + this.options.verticalSpacing;
140138
}
141139

142-
// Рекурсивно размещаем узлы
140+
// Recursively placing nodes
143141
const positionNode = (node: TreeNode, leftX: number): void => {
144-
// Устанавливаем Y координату
142+
// Setting the Y coordinate
145143
node.y = levelY[node.level];
146144

147145
if (node.children.length === 0) {
148-
// Листовой узел - размещаем в текущей позиции
146+
// The leaf node is placed in the current position.
149147
node.x = leftX;
150148
} else {
151-
// Размещаем детей
149+
// Place children
152150
let childX = leftX;
153151

154-
// Если ширина узла больше суммарной ширины детей, добавляем отступ
152+
// If the node width is greater than the total width of the children, add an indentation.
155153
const childrenWidth = node.children.reduce(
156154
(sum: number, child: TreeNode) => sum + child.subtreeWidth,
157155
0,
@@ -164,13 +162,13 @@ class TreeLayoutEngine {
164162
childX += extraSpace;
165163
}
166164

167-
// Размещаем каждого ребенка
165+
// Place each child
168166
for (const child of node.children) {
169167
positionNode(child, childX);
170168
childX += child.subtreeWidth + this.options.horizontalSpacing;
171169
}
172170

173-
// Центрируем родительский узел относительно детей
171+
// Center the parent node relative to the children
174172
const firstChild = node.children[0];
175173
const lastChild = node.children[node.children.length - 1];
176174
const childrenCenter = (firstChild.x + lastChild.x + lastChild.block.width) / 2;
@@ -181,7 +179,7 @@ class TreeLayoutEngine {
181179
positionNode(this.tree, 0);
182180
}
183181

184-
// Нормализация координат (чтобы минимальные координаты были >= 0)
182+
// Normalization of coordinates (so that the minimum coordinates are >= 0)
185183
normalizeCoordinates() {
186184
if (!this.tree) {
187185
return;
@@ -201,7 +199,7 @@ class TreeLayoutEngine {
201199
const minX = Math.min(...allNodes.map((node) => node.x));
202200
const minY = Math.min(...allNodes.map((node) => node.y));
203201

204-
// Сдвигаем все координаты так, чтобы минимальные были равны 0
202+
// Shift all coordinates so that the minimum ones are equal to 0
205203
const offsetX = minX < 0 ? -minX : 0;
206204
const offsetY = minY < 0 ? -minY : 0;
207205

@@ -211,7 +209,7 @@ class TreeLayoutEngine {
211209
}
212210
}
213211

214-
// Основной метод компоновки
212+
// Main method of composition
215213
layout() {
216214
this.buildTree();
217215
this.groupByLevels();
@@ -222,7 +220,7 @@ class TreeLayoutEngine {
222220
return this.getLayoutResult();
223221
}
224222

225-
// Получение результата компоновки
223+
// Getting the result of composition
226224
getLayoutResult(): ExtendedTBlock[] {
227225
if (!this.tree) {
228226
return [];
@@ -252,17 +250,17 @@ class TreeLayoutEngine {
252250
}
253251
}
254252

255-
// Функция для использования алгоритма
253+
// Function for using the algorithm
256254
function calculateTreeLayout(blocks: TBlock[], connections: TConnection[], options = {}) {
257255
const engine = new TreeLayoutEngine(blocks, connections, options);
258256
return engine.layout();
259257
}
260258

261259
function calculateTreeEdges(layoutResult: ExtendedTBlock[], connections: TConnection[]) {
262-
// Создаем карту позиций для удобства поиска
260+
// Create a position map for convenience of search
263261
const positionMap = new Map(layoutResult.map((item) => [item.id, item]));
264262

265-
// Группируем связи по родительскому блоку
263+
// Group connections by parent block
266264
const connectionsByParent = new Map();
267265

268266
for (const connection of connections) {
@@ -280,19 +278,19 @@ function calculateTreeEdges(layoutResult: ExtendedTBlock[], connections: TConnec
280278
points: {x: number; y: number}[];
281279
}[] = [];
282280

283-
// Для каждого родительского блока рассчитываем пути к детям
281+
// For each parent block, we calculate the paths to the children
284282
for (const [parentId, parentConnections] of connectionsByParent) {
285283
const parent = positionMap.get(parentId);
286284
if (!parent) {
287285
continue;
288286
}
289287

290-
// Координаты начальной точки (центр нижней части родителя)
288+
// Coordinates of the initial point (center of the lower part of the parent)
291289
const startX = parent.x + parent.width / 2;
292290
const startY = parent.y + parent.height;
293291

294292
if (parentConnections.length === 1) {
295-
// Один дочерний блок - простая прямая линия
293+
// One child block - simple straight line
296294
const connection = parentConnections[0];
297295
const child = positionMap.get(connection.targetBlockId);
298296

@@ -311,9 +309,9 @@ function calculateTreeEdges(layoutResult: ExtendedTBlock[], connections: TConnec
311309
});
312310
}
313311
} else {
314-
// Несколько дочерних блоков - ломаные линии
312+
// Several child blocks - broken lines
315313

316-
// Находим вертикальное расстояние между родителем и ближайшим ребенком
314+
// We find the vertical distance between the parent and the nearest child
317315
const children = parentConnections
318316
.map((conn: TConnection) => positionMap.get(conn.targetBlockId))
319317
.filter(
@@ -325,13 +323,13 @@ function calculateTreeEdges(layoutResult: ExtendedTBlock[], connections: TConnec
325323
continue;
326324
}
327325

328-
// Находим минимальное расстояние до детей по Y
326+
// We find the minimum distance to the children by Y
329327
const minChildY = Math.min(...children.map((child: ExtendedTBlock) => child.y));
330328

331-
// Точка разветвления - посередине между родителем и детьми
329+
// The point of branching - in the middle between the parent and the children
332330
const branchY = startY + (minChildY - startY) / 2;
333331

334-
// Для каждого дочернего блока создаем ломаную линию
332+
// For each child block, we create a broken line
335333
for (const connection of parentConnections) {
336334
const child = positionMap.get(connection.targetBlockId);
337335
if (!child) {
@@ -342,10 +340,10 @@ function calculateTreeEdges(layoutResult: ExtendedTBlock[], connections: TConnec
342340
const endY = child.y;
343341

344342
const points = [
345-
{x: startX, y: startY}, // Начало - центр нижней части родителя
346-
{x: startX, y: branchY}, // Вертикально вниз до точки разветвления
347-
{x: endX, y: branchY}, // Горизонтально до центра дочернего блока
348-
{x: endX, y: endY}, // Вертикально вниз до центра верхней части дочернего блока
343+
{x: startX, y: startY}, // Start - center of the lower part of the parent
344+
{x: startX, y: branchY}, // Vertically down to the point of branching
345+
{x: endX, y: branchY}, // Horizontally to the center of the child block
346+
{x: endX, y: endY}, // Vertically down to the center of the upper part of the child block
349347
];
350348

351349
connectionPaths.push({

0 commit comments

Comments
 (0)