# HMDesign OrgChart — Chart Only 구현 보고서 (2026-10-13) RESULT: **PASS** (Auto/Expanded · React · Vanilla). Fixed Chart Only는 지원하지 않으며 제약으로 구분한다. Commit·Push·Merge는 하지 않았다. ## 1. 작업 위치 - Worktree: `D:\디자인시스템\HMDesign-OrgChart-ChartOnly-Impl`, 브랜치 `feature/orgchart-chart-only-implementation`, 기준 HEAD `0a8daf7ee7ac026952a2e1d3d5f25a922dab07cf`(변경은 미커밋). - 의존성은 이 Worktree에서 `npm ci --ignore-scripts`(lockfile 그대로)로 설치했다. 버전 변경 없음. ## 2. UI 소유 위치 (STEP 1) | UI | 소유 | Chart Only 처리 | |---|---|---| | 제목·기준일(`createHeading`) | Core `expanded-content.ts` | 생성하지 않음 | | 선택 회사 수·인원 요약 | Core `index.ts` | 생성하지 않음 | | 확대/축소/100%/Fit 버튼·배율·조작 안내 | Core `expanded-viewport.ts` | toolbar 없이 같은 viewport 컨트롤러 사용 | | Drag & Drop 상태 문구 | Core `index.ts` | 요소는 유지(aria-live·aria-describedby), 화면에서는 시각적으로 숨김 | | 회색 패딩·테두리 외곽 | Core CSS `.hm-orgchart-expanded` | chart-only에서 흰색·패딩 0·테두리 0 | | Storybook 필터바·페이지 제목·설명 | Storybook Preview | 변경 없음(사용하지 않음) | | React Wrapper | 컨테이너 div와 선택형 Popup Adapter만 | 변경 없음 | 기존 API만으로는 Vanilla `fitToView()` 호출까지 가능했고, 내장 UI 제거·React 초기 Fit·직접 휠 Zoom은 불가능했다. ## 3. 추가한 공개 API (Core 옵션, React Props로 그대로 전달) - `presentationMode?: 'default' | 'chart-only'` — 기본 `'default'`. Auto 전용. Fixed와 함께 쓰면 `TypeError`. - `initialView?: 'center' | 'fit'` — chart-only 기본 `'fit'`, 그 외 `'center'`(기존 동작). - `wheelZoom?: 'modifier' | 'direct'` — chart-only 기본 `'direct'`, 그 외 `'modifier'`(기존 Ctrl/⌘ + 휠). - 타입 export: `OrgChartPresentationMode`, `OrgChartInitialView`, `OrgChartWheelZoom`. - React Wrapper: 세 옵션 전달, 객체 옵션(`autoLayout`·`interactions`·`selectedCompanyIds`·`zoom`·`companyTopNodes`·`employeeConnections`·`organizationLinks`·`aggregationPolicy`)을 값으로 비교해 같은 값의 inline 객체 리렌더링이 재마운트·재Fit을 일으키지 않게 했다. 마운트 직후 중복 `setSelectedCompanies` 호출도 사라졌다. - JSON Contract, `/hm-dialog`, `employeePopupAdapter`, 기본 Entry 의존성, 카드 SVG, 회사 컬러는 변경하지 않았다. ## 4. 동작 - 초기 Fit: 실제 Forest Bounds(조직·연결선 path 포함) 기준, 16px 여백, 최대 100%, 가로·세로 중앙. 측정 전에는 forest를 `visibility: hidden`으로 두어 첫 프레임이 튀지 않는다. 캔버스 크기 0이면 실행하지 않고 ResizeObserver/레이아웃 완료 경로에서 실행한다. - 재Fit: 최초 렌더링, `update`/`reload`/React `dataSource` 교체, 회사 선택·layout 변경. Zoom·Pan·팝업·그룹 접기·Drag & Drop 전환·단순 리렌더링에서는 재Fit하지 않는다. - 휠: 캔버스 안에서만 `preventDefault` 후 포인터 기준 Zoom. delta 정규화(line/page)와 이벤트당 ±120 제한. 캔버스 밖은 페이지 스크롤. `interactions.zoom=false`이면 휠을 가로채지 않는다. - Fit 배율이 `zoom.min`보다 작으면 휠 축소는 Fit 배율에서 멈춘다(`initialView: 'fit'`일 때만). ## 5. 브라우저 검증 (실제 Chrome 155, Playwright 1.64) [`examples/org-chart-chart-only/verify.mjs`](../../examples/org-chart-chart-only/verify.mjs) **46/46 PASS, 콘솔 오류 0**. 증거: `test-results/org-chart-chart-only/`(ignored). | 데이터 (1440×900) | 배율 | 중앙 오차 X/Y | 상하좌우 여백 | |---|---|---|---| | 20명·3개 회사 | 1.0000 | 0 / 0 px | 174 / 29.75 px | | 100명·5개 회사 | 0.5135 | 0 / 0 px | 16 / 89.66 px | | 500명·삼안 6본부 17팀 | 0.3254 | 0 / 0 px | 231.58 / 16 px | | 100명 LR / Hybrid | 0.1819 / 0.5309 | 0 / 0 px | — | | 모바일 390×844 (20/100/500) | 0.3278 / 0.1306 / 0.1193 | 0 / 0 px | 페이지 가로 넘침 없음 | - React와 Vanilla의 배율·여백·휠·Pan 수치가 동일하다. - 일반 휠 위/아래 Zoom(0.3254→0.3974→0.3254), 포인터 아래 지점 화면 이동 0.14px, 최대 3·최소 0.05, Zoom 후 Pan 정확히 (120, −80)px, 600ms 뒤 재Fit 없음, Ctrl+휠도 캔버스 안에서만 동작(페이지 확대 없음). - 임베드 페이지: 캔버스 밖 휠은 페이지 스크롤(180px), 안쪽 휠은 스크롤 없이 Zoom. - 직원 팝업(Core·`/hm-dialog` HM Dialog) 열기/닫기, 그룹 접기·펼치기(500→472→500명) 후 배율·위치 유지. Drag & Drop 기본 OFF, 카드 드래그 후 소속 불변. - 데이터 전체 교체(500→100명) 후 다시 Fit·중앙(오차 0px). React 단순 리렌더링 후 사용자 뷰 유지. - 모바일 터치 Pan(CDP touch) 동작. 모바일에서 휠은 검증 대상이 아니다. ## 6. 기존 화면 보호 [`verify-storybook.mjs`](../../examples/org-chart-chart-only/verify-storybook.mjs) **9/9 PASS, 콘솔 오류 0**. 이 Worktree의 Storybook(6044)을 기존 Feature Storybook(6024, 같은 HEAD)과 비교했다. - 공개 OrgChart 메뉴 4개 유지(Overview, Department Colors, Full Composition, Expanded OrgChart). - 4개 페이지 모두 DOM 동일, 스크린샷 픽셀 동일. Full Composition은 한 실행에서 5픽셀 ±1 래스터 오차가 있었고 재실행에서 픽셀 동일이었다. - Expanded: 제목·기준일·요약·툴바 4버튼·배율·`드래그·방향키 이동 · Ctrl/⌘ + 휠 확대` 안내·Drag & Drop 문구 유지. 일반 휠은 Zoom하지 않고(페이지 스크롤), Ctrl+휠은 Zoom, Fit to View 버튼 동작. - 그 외: Core 단위 테스트 86/86, Guard 테스트 94/94(기준 HEAD와 동일), 루트 `tsc -b`, Core·React typecheck/build, Theme defaults check 통과. - 기존 `examples/org-chart-react/verify-boundaries.mjs`: 8 PASS / 1 FAIL이며 기준 HEAD 임시 Worktree에서도 같은 항목이 같은 결과로 실패한다(Fixed 390px 내부 가로 스크롤 검사, 기존 실패). ## 7. 제약 · NOT VERIFIED - **Fixed Chart Only 미지원**: Workdesk 구성(제목·요약·아트워크·비례 축소)이 서로 묶여 있어 일부만 제거하면 승인 디자인이 바뀐다. 옵션을 함께 쓰면 오류로 알린다. Fixed에는 Auto의 휠 Zoom/Pan이 없다. - NOT VERIFIED: Safari/Firefox, macOS 트랙패드 핀치, 실제 모바일 기기, 스크린리더 낭독, 2,100명 전체 회귀(요청대로 반복하지 않음), `examples/org-chart-react/verify.mjs`(storybook-static 빌드 필요)·기존 P9.x 개별 스크립트. - React imperative ref는 추가하지 않았다(초기 Fit을 옵션으로 해결).