v0.2.63
v0.2.63 — "도시형(2D 전용)" 레이아웃을 계획도시 블록 패킹으로 재작성
변경 사항
- *사용자 요청**: "레이아웃에서 '도시형(2D 전용)' 레이아웃의 노드 배치 로직을, 촘촘하게 계획도시가 개발된 듯하게 보이도록 배치되게 알고리즘을 구현해줘".
기존 한계 (v0.2.62 이전)
- 4 방향 (E/W/S/N) 분기 패턴 — root 주변에 십자가형으로 펼쳐졌음.
- 폴더가 늘어나면 단순 누적 stack → 한 방향이 끝없이 길어지고 직선처럼 보임.
- "도시" 보다는 "4-quadrant 캔틸레버" 느낌.
v0.2.63 신규 알고리즘 — 재귀 블록 패킹 (Recursive Block Packing)
- *컨셉: Manhattan-style 격자 도시**
- 각 폴더 = 한 개의 "city block" (사각형 격자 영역).
- 폴더 내 파일 = 그 블록의 row-major grid (촘촘한 sqrt(N) 열).
- 서브폴더 = 자기만의 블록 (재귀 packBlock) + 부모 안에서 다른 sub-block 들과 row-fill bin-packing.
- 블록 사이 = STREET (도로, 48 px). 셀 사이 = 골목 (24/12 px).
- root 노드 = packed 블록 top-center 위 (CELL_H + ROOT_GAP) 위치 → "중앙 광장".
- *상수**:
const CITY_CELL_W = NODE_W_2D + 24; // 224
const CITY_CELL_H = NODE_H_2D + 12; // 48
const CITY_STREET = 48; // 블록 사이 도로
const CITY_ROOT_GAP = 56; // root - 첫 블록 row gap- *
packBlock(folderId)(재귀)**:
- 파일 패킹 —
cols = max(1, min(8, ceil(sqrt(N)))). cap=8 이라 파일 많은 폴더도 너무 wide 하지 않게 → 부모 row-fill 시 옆 블록과 같은 행 공유 가능. Files →{ x: (i%cols)*CELL_W, y: floor(i/cols)*CELL_H }row-major grid. - 서브폴더 재귀 — 각 서브폴더
packBlock호출 →{ width, height, positions }받음. - Items 리스트 — 파일 블록 1 개 + 서브폴더 블록들 (헤더 1 셀 + content). 각 item 은
place(cx, cy)callback 으로 자기 자식 좌표를 global 로 commit. - Row-fill bin-packing —
targetW = max(CELL_W*3, sqrt(totalArea) * 1.8). 1.8 배수는 실험치 — 4~7 개 블록 시 2~3 블록 per row 로 자연스러움. - Cursor 이동:
cx += it.width + STREET, row 가득 차면cy += rowH + STREET; cx=0.
- *root 배치**:
- 직속 자식들을
packBlock('')으로 한 큰 블록으로 묶음. - root 노드 (id='') 는 그 블록의 top-center 위
y = -(CELL_H + ROOT_GAP)에 배치. - 모든 top-level 폴더 블록이 root 아래에 grid 로 펼쳐짐.
- *비겹침 보장**:
- 같은 블록 내 파일 = grid cell 좌표라 안 겹침.
- 다른 블록 = row-fill cursor 가 right-bottom 으로만 이동 + STREET gap.
- 재귀 서브블록도 마찬가지.
시각 효과
- 작은 폴더 = 작은 블록 (촘촘함). 큰 폴더 = 큰 블록 + 내부 sub-block 들이 다시 grid.
- 직사각형 위주 → 계획도시 (block grid) 느낌.
- root 가 north plaza, 모든 블록이 그 남쪽으로 grid 펼침 → 명확한 hierarchy.
- 폴더가 깊을수록 nested grid → fractal city.
시뮬레이션 검증
- 7 개 폴더 (각각 3~30 파일, 일부 서브폴더 포함) 가상 입력:
- 첫 row 에 3 개 블록, 둘째 row 에 2 개, 셋째 row 에 2 개 형태로 자동 packing.
- 한 row 안 블록들이 서로 다른 height 라도 STREET 으로 vertical gap 보장.
- 서브폴더 깊이 2 단계까지 안정적 packing — 내부 grid 가 부모 cell 안에 깔끔하게 자리.
변경 파일
src/utils/layoutAlgorithm.ts—compute2DCityLayout함수 완전 재작성. 기존 4 방향 코드 삭제 +packBlock재귀 알고리즘 도입. 590~770 라인 영역.- 함수 시그니처 (
(nodes, externals, options) => Layout2DResult) 와 외부 호출자 (compute2DLayoutswitch case'city') 는 그대로 유지 — 호환성 보존. package.json0.2.62 → 0.2.63.
검증
npx tsc --noEmitexit=0.npm run build성공 — renderer 8.22s, 번들 3,492.41 kB.
핸드오프 메모
- 도시형 레이아웃은
2D 전용— 3D 씬에서는 force-directed 또는 hierarchical 사용. Layout2DOptions.folderIndent는 도시형에서 무시 (void folderIndent) — grid 정렬이라 indent 의미 없음.languageSort/groupByRole은 sibling 정렬에 그대로 영향 → 같은 폴더 안 row-major grid 순서가 그에 따라 바뀜.- --
📦 GitHub 릴리스 노트: v0.2.63