@rdbms-erd/core 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -67
- package/package.json +19 -11
- package/src/__tests__/alignment.test.ts +19 -19
- package/src/__tests__/benchmark.test.ts +14 -14
- package/src/__tests__/db-meta-adapter.test.ts +166 -0
- package/src/__tests__/ddl-diagnostics.test.ts +52 -52
- package/src/__tests__/ddl-snapshot.test.ts +91 -91
- package/src/__tests__/designDocument.test.ts +129 -78
- package/src/__tests__/logical-physical.test.ts +110 -37
- package/src/alignment.ts +71 -71
- package/src/index.ts +1386 -506
package/src/alignment.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
export type AlignCommand =
|
|
2
|
-
| "left"
|
|
3
|
-
| "h-center"
|
|
4
|
-
| "right"
|
|
5
|
-
| "top"
|
|
6
|
-
| "v-center"
|
|
7
|
-
| "bottom"
|
|
8
|
-
| "h-gap"
|
|
9
|
-
| "v-gap";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 멀티 선택된 노드 위치를 bounding box 기준으로 정렬/분배한다.
|
|
13
|
-
* positions는 id -> 좌표 맵이며, 반환값은 동일 키에 갱신된 좌표만 포함한다.
|
|
14
|
-
*/
|
|
15
|
-
export function alignNodePositions(
|
|
16
|
-
selectedIds: string[],
|
|
17
|
-
positions: Record<string, { x: number; y: number }>,
|
|
18
|
-
command: AlignCommand
|
|
19
|
-
): Record<string, { x: number; y: number }> {
|
|
20
|
-
const entries = selectedIds
|
|
21
|
-
.map((id) => {
|
|
22
|
-
const pos = positions[id];
|
|
23
|
-
return pos ? { id, pos: { ...pos } } : null;
|
|
24
|
-
})
|
|
25
|
-
.filter((e): e is { id: string; pos: { x: number; y: number } } => Boolean(e));
|
|
26
|
-
|
|
27
|
-
if (entries.length < 2) {
|
|
28
|
-
return {};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const xs = entries.map((e) => e.pos.x);
|
|
32
|
-
const ys = entries.map((e) => e.pos.y);
|
|
33
|
-
const minX = Math.min(...xs);
|
|
34
|
-
const maxX = Math.max(...xs);
|
|
35
|
-
const minY = Math.min(...ys);
|
|
36
|
-
const maxY = Math.max(...ys);
|
|
37
|
-
const centerX = (minX + maxX) / 2;
|
|
38
|
-
const centerY = (minY + maxY) / 2;
|
|
39
|
-
|
|
40
|
-
const sortByX = [...entries].sort((a, b) => a.pos.x - b.pos.x);
|
|
41
|
-
const sortByY = [...entries].sort((a, b) => a.pos.y - b.pos.y);
|
|
42
|
-
|
|
43
|
-
const out: Record<string, { x: number; y: number }> = {};
|
|
44
|
-
|
|
45
|
-
for (const e of entries) {
|
|
46
|
-
const next = { ...e.pos };
|
|
47
|
-
if (command === "left") next.x = minX;
|
|
48
|
-
if (command === "h-center") next.x = centerX;
|
|
49
|
-
if (command === "right") next.x = maxX;
|
|
50
|
-
if (command === "top") next.y = minY;
|
|
51
|
-
if (command === "v-center") next.y = centerY;
|
|
52
|
-
if (command === "bottom") next.y = maxY;
|
|
53
|
-
out[e.id] = next;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (command === "h-gap") {
|
|
57
|
-
const gap = entries.length > 1 ? (maxX - minX) / (entries.length - 1) : 0;
|
|
58
|
-
sortByX.forEach((e, index) => {
|
|
59
|
-
out[e.id] = { ...e.pos, x: minX + gap * index };
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (command === "v-gap") {
|
|
64
|
-
const gap = entries.length > 1 ? (maxY - minY) / (entries.length - 1) : 0;
|
|
65
|
-
sortByY.forEach((e, index) => {
|
|
66
|
-
out[e.id] = { ...e.pos, y: minY + gap * index };
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return out;
|
|
71
|
-
}
|
|
1
|
+
export type AlignCommand =
|
|
2
|
+
| "left"
|
|
3
|
+
| "h-center"
|
|
4
|
+
| "right"
|
|
5
|
+
| "top"
|
|
6
|
+
| "v-center"
|
|
7
|
+
| "bottom"
|
|
8
|
+
| "h-gap"
|
|
9
|
+
| "v-gap";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 멀티 선택된 노드 위치를 bounding box 기준으로 정렬/분배한다.
|
|
13
|
+
* positions는 id -> 좌표 맵이며, 반환값은 동일 키에 갱신된 좌표만 포함한다.
|
|
14
|
+
*/
|
|
15
|
+
export function alignNodePositions(
|
|
16
|
+
selectedIds: string[],
|
|
17
|
+
positions: Record<string, { x: number; y: number }>,
|
|
18
|
+
command: AlignCommand
|
|
19
|
+
): Record<string, { x: number; y: number }> {
|
|
20
|
+
const entries = selectedIds
|
|
21
|
+
.map((id) => {
|
|
22
|
+
const pos = positions[id];
|
|
23
|
+
return pos ? { id, pos: { ...pos } } : null;
|
|
24
|
+
})
|
|
25
|
+
.filter((e): e is { id: string; pos: { x: number; y: number } } => Boolean(e));
|
|
26
|
+
|
|
27
|
+
if (entries.length < 2) {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const xs = entries.map((e) => e.pos.x);
|
|
32
|
+
const ys = entries.map((e) => e.pos.y);
|
|
33
|
+
const minX = Math.min(...xs);
|
|
34
|
+
const maxX = Math.max(...xs);
|
|
35
|
+
const minY = Math.min(...ys);
|
|
36
|
+
const maxY = Math.max(...ys);
|
|
37
|
+
const centerX = (minX + maxX) / 2;
|
|
38
|
+
const centerY = (minY + maxY) / 2;
|
|
39
|
+
|
|
40
|
+
const sortByX = [...entries].sort((a, b) => a.pos.x - b.pos.x);
|
|
41
|
+
const sortByY = [...entries].sort((a, b) => a.pos.y - b.pos.y);
|
|
42
|
+
|
|
43
|
+
const out: Record<string, { x: number; y: number }> = {};
|
|
44
|
+
|
|
45
|
+
for (const e of entries) {
|
|
46
|
+
const next = { ...e.pos };
|
|
47
|
+
if (command === "left") next.x = minX;
|
|
48
|
+
if (command === "h-center") next.x = centerX;
|
|
49
|
+
if (command === "right") next.x = maxX;
|
|
50
|
+
if (command === "top") next.y = minY;
|
|
51
|
+
if (command === "v-center") next.y = centerY;
|
|
52
|
+
if (command === "bottom") next.y = maxY;
|
|
53
|
+
out[e.id] = next;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (command === "h-gap") {
|
|
57
|
+
const gap = entries.length > 1 ? (maxX - minX) / (entries.length - 1) : 0;
|
|
58
|
+
sortByX.forEach((e, index) => {
|
|
59
|
+
out[e.id] = { ...e.pos, x: minX + gap * index };
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (command === "v-gap") {
|
|
64
|
+
const gap = entries.length > 1 ? (maxY - minY) / (entries.length - 1) : 0;
|
|
65
|
+
sortByY.forEach((e, index) => {
|
|
66
|
+
out[e.id] = { ...e.pos, y: minY + gap * index };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return out;
|
|
71
|
+
}
|