feat(org-chart): finalize chart features and AI generation rules
This commit is contained in:
1 parent
7614507583
commit
d0828a7ff4
80 files changed
+8152
-221
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# Expanded OrgChart 사용 및 스타일 — P5-4
|
||||
# Expanded OrgChart 사용 및 스타일 — P7
|
||||
|
||||
2026-10-12 사용자 변경 요구사항으로 **현재 확장형 카드 외형과 크기를 유지**한다.
|
||||
`Group 3391.svg`, `Group 1171288761.svg` 검색·재현·용도 배정은 이번 완료 조건에서 제외한다.
|
||||
@@ -42,7 +42,8 @@ console.log(chart.getViewportState(), getCompanyColorPreset('hanmac')?.primary);
|
||||
`JsonOrgChartDataSource`는 인라인 JSON 또는 호스트가 제공하는 HTTP(S)/상대 URL을 받는다.
|
||||
URL을 사용할 경우 `new JsonOrgChartDataSource('./data-expanded-large.json')`처럼 지정한다.
|
||||
file:// Fetch는 지원하지 않는다. 이번 작업에 외부 API·서버·DB 구현은 추가하지 않았다.
|
||||
현재 JSON 예시는 Small 20명/3회사, Medium 100명/5회사, Large 300명/7회사다.
|
||||
기존 JSON 예시는 Small 20명/3회사, Medium 100명/5회사, Large 300명/7회사다.
|
||||
P7의 7회사 합산·회사별 선택은 Large를 기반으로 아래 공개 helper를 사용한다.
|
||||
|
||||
## React
|
||||
|
||||
@@ -72,8 +73,9 @@ export function ExpandedExample() {
|
||||
|
||||
위 native 버튼은 React 계약만 설명하는 최소 예시다. HM 화면에서는 실제 기존
|
||||
`Button`, `Checkbox`, `Label`, `Select`를 조합한다. Expanded Story가 그 사용 예다.
|
||||
Source·옵션 객체를 안정적으로 유지한다. Core 생성 옵션(모드·TopNode·연결 방향·Zoom 설정)을
|
||||
Source·옵션 객체를 안정적으로 유지한다. Core 생성 옵션(layoutMode·TopNode·연결 방향·Zoom 범위)을
|
||||
변경하면 React는 handle을 다시 생성한다. Vanilla는 새 handle을 생성한다.
|
||||
`autoLayout`·`interactions`·회사 선택·팝업 선택은 기존 인스턴스에서 갱신한다.
|
||||
회사 선택은 기존 setter/React prop으로 변경하며 원본 JSON과 parentId를 수정하지 않는다.
|
||||
React에는 별도 레이아웃 알고리즘이나 imperative ref API가 없다.
|
||||
|
||||
@@ -95,7 +97,9 @@ Employee 관계를 유지한다. `companyId` 생성 옵션은 기존 JSON의 회
|
||||
|
||||
표의 값은 기존 `getCompanyColorPreset(companyId)`에서 조회한다. 카드에 중복 하드코딩하지 않는다.
|
||||
타이틀은 조직 회사, 카드 강조색은 알려진 직원 affiliation(미등록 시 조직 회사)의 프리셋을 쓴다.
|
||||
삼안·장헌산업 타이틀은 기존 짙은 중립 텍스트 정책을 유지한다.
|
||||
현재 사용자 확정에 따라 모든 회사 타이틀은 normal/hover/focus/접힘/펼침에서 흰색을 유지한다.
|
||||
이는 P7 시작 전 기존 미커밋 변경을 보존한 결과다. 삼안·장헌산업 흰 글자의 대비 진단은
|
||||
접근성 승인으로 재분류하지 않으며, 이번 기능 확장으로 메인 컬러를 바꾸지 않는다.
|
||||
|
||||
`companyTopNodes`는 `employeeId`, `title`, `name`, `profileImage`, `organizationName`,
|
||||
`display: 'card' | 'titleOnly' | 'hidden'`을 지원한다. 생략 시 Root의 leaderId를 사용하며,
|
||||
@@ -104,7 +108,8 @@ employeeId는 그 Root에 소속된 기존 직원이어야 한다. null은 최
|
||||
|
||||
`employeeConnections`의 지원 값은 `top | left | right`다. Depth를 기준으로 정하지 않는다.
|
||||
직원 연결선의 실제 도착점과 같은 면에만 회사 Border를 표시하며, 조직장은 타이틀 아래
|
||||
상단 연결을 사용한다. 다른 면은 중립, 강조는 inset이라 외형 크기가 변하지 않는다.
|
||||
TB/Hybrid에서는 상단 연결을 사용한다. LR은 조직장·일반 직원 모두 왼쪽에서 연결되며
|
||||
직원별 실제 도착 면과 왼쪽 Border가 일치한다. 다른 면은 중립, 강조는 inset이라 외형 크기가 변하지 않는다.
|
||||
연결 없는 카드에 임의로 accent를 붙이는 별도 `none` API는 없다. 현재 Auto presenter의
|
||||
렌더링된 카드는 모두 타이틀 또는 이전 카드/분기 rail과 연결된다.
|
||||
|
||||
@@ -116,7 +121,7 @@ employeeId는 그 Root에 소속된 기존 직원이어야 한다. null은 최
|
||||
그룹 링크는 별도 아이콘으로 페이지 이동과 토글 동작을 분리한다.
|
||||
공개 프로그래밍 방식 collapse setter는 제공하지 않는다.
|
||||
|
||||
직원 카드는 click·Enter·Space로 공통 직원 정보 dialog를 연다. dialog는 변환 forest 밖의
|
||||
Vanilla 직원 카드는 click·Enter·Space로 공통 직원 정보 dialog를 연다. dialog는 변환 forest 밖의
|
||||
native top layer에 표시되므로 Zoom과 Stage overflow의 영향을 받지 않는다.
|
||||
ESC/닫기 버튼과 focus trap·카드 focus 복귀를 제공한다.
|
||||
`onEmployeeClick(employee, context)` 지정 시 기본 팝업 대신 callback을 호출하며
|
||||
@@ -162,6 +167,129 @@ CSS 자산을 만들고 그 URL을 `stylesheetUrls.core`로 제공할 수 있다
|
||||
|
||||
크기 변경 시 기존 ResizeObserver가 article의 실측 높이와 실제 endpoint를 재계산한다.
|
||||
향후 변경에는 Fit·형제/하위 트리 겹침·텍스트 overflow를 다시 확인해야 한다.
|
||||
이번 P5-4는 기본 geometry를 바꾸지 않으며 대용량 성능의 과거 수치를 재측정하지 않는다.
|
||||
P7도 기본 카드 geometry를 바꾸지 않는다. LR/Hybrid 300명과 2,100명의 실측은
|
||||
과거 P5/P6 성능과 분리하여 P7 보고서에 기록한다.
|
||||
|
||||
검증 범위와 실행 URL·캡처는 [P5-4 보고서](implementation-report-p5-4.md)를 참고한다.
|
||||
과거 검증은 [P5-4 보고서](implementation-report-p5-4.md), P7 변경과 실측은
|
||||
[P7 보고서](implementation-report-p7.md)를 참고한다.
|
||||
|
||||
## P7 데이터·레이아웃·독립 옵션
|
||||
|
||||
```js
|
||||
import { createOrgChartExampleDataset } from '@hm-design/org-chart';
|
||||
import template from './data-expanded-large.json';
|
||||
|
||||
const dataset = createOrgChartExampleDataset(template, {
|
||||
scope: 'per-company', // 'total'이면 전체 7회사 합산 employeeCount
|
||||
employeeCount: 300, // 20 | 100 | 300
|
||||
companyIds: ['hanmac', 'saman'], // 생략하면 7회사, 이 예시는 600명
|
||||
});
|
||||
const chart = createOrgChart({
|
||||
...configuredBaseOptions,
|
||||
dataSource: new JsonOrgChartDataSource(dataset),
|
||||
layoutMode: 'auto',
|
||||
autoLayout: { type: 'lr', initialVisibleDepth: 'all' },
|
||||
interactions: { collapse: false, zoom: true, pan: false },
|
||||
});
|
||||
await chart.mount();
|
||||
await chart.setAutoLayout({ type: 'hybrid', hybridStartDepth: 3 });
|
||||
await chart.setInteractions({ collapse: true }); // 다른 설정은 그대로
|
||||
```
|
||||
|
||||
총량 모드는 회사별 가중 분배 후 선택한 회사만 필터링하며 재분배하지 않는다.
|
||||
회사별 모드는 선택 회사마다 정확히 N명, 전체 7회사 × 300명 = 2,100명이다.
|
||||
ID는 deterministic 가상 namespace로 생성하며 기존 직원 기록·조직 ID·부모 관계를 재사용한다.
|
||||
원본은 변경하지 않고 반환 snapshot은 deep freeze한다. helper의 빈 회사 선택은 유효한
|
||||
조직 데이터가 될 수 없어 거절하며, 화면의 빈 선택은 `setSelectedCompanies([])`로 표시한다.
|
||||
|
||||
| 옵션 | TB | LR | Hybrid | 제약 및 전환 |
|
||||
|---|---|---|---|---|
|
||||
| 레이아웃 `type` | 지원 | 지원 | 지원 | 다른 기능을 켤 필요 없음 |
|
||||
| `hybridStartDepth: 2/3/4` | 적용 안 함 | 적용 안 함 | 지원 | Root=1Depth, 기본 3 |
|
||||
| `hybridOrganizationIds` | 지정 그룹 자손 세로 배치 | 조합 거절 | 조합 거절 | LR/Hybrid 전환 전 목록 해제; Story는 자동 해제·disabled |
|
||||
| `initialVisibleDepth: 1/2/3/'all'` | 지원 | 지원 | 지원 | 기본 all; 값을 바꾸면 접힘 상태를 초기 정책으로 재설정 |
|
||||
| `interactions.collapse/zoom/pan` | 각각 지원 | 각각 지원 | 각각 지원 | 각각 기본 true; false도 다른 기능 사용을 막지 않음 |
|
||||
| 회사 선택·직원 팝업 | 지원 | 지원 | 지원 | 특정 레이아웃·Zoom·Pan·접기 사용을 요구하지 않음 |
|
||||
| Compact | 미지원 | 미지원 | 미지원 | 엔진 compact DOM/140×50 grid가 기존 HM 카드·접기 계약과 충돌 |
|
||||
|
||||
TB는 기존 경로를 유지한다. LR은 실제 dabeng `direction: 'l2r'`와 재귀 hierarchy를 사용한다.
|
||||
원본 `.title/.content` 전용 회전 CSS는 HM 복합 article에 맞지 않아 Auto 범위에서
|
||||
회전을 해제하고 부모 좌측·자식 우측·형제 세로 배치를 구성한다. Hybrid는 실제
|
||||
`verticalLevel`/그룹 `hybrid`를 사용한다. 측정한 부모·자식 좌표로 연결선을 갱신하며
|
||||
Fixed의 CSS·엔진 옵션·기존 native 팝업은 보존한다.
|
||||
|
||||
접기·레이아웃 전환은 유효한 조직 ID의 접힘 상태를 유지한다. 데이터·회사·레이아웃
|
||||
전환은 표시된 카드·타이틀·연결선 전체 경계를 다시 측정하여 가로 중앙을 갱신한다.
|
||||
자동 배치는 현재 배율을 유지하며 큰 조직도를 임의로 축소하지 않는다. 사용자가 Pan·Zoom·
|
||||
100% 복원 또는 화면 밖 focus 노출로 이동한 뒤에는 데이터·회사·레이아웃 전환과 Resize에서도
|
||||
배율·이동 위치를 보존한다. 명시적 Fit to View는 전체 표시 영역을 축소해 담고 가로·세로 중앙에
|
||||
배치하며 자동 중앙 배치를 다시 허용한다. 개별 interaction/popup 변경은 기존 viewport와
|
||||
접힘 상태를 보존한다. Pan을 꺼도 키보드로 화면 밖 카드에 도달하면 배율 유지·focus
|
||||
노출을 제공한다. Fit/100% 복원은 Zoom/Pan 사용 여부와 독립적으로 가능하다.
|
||||
2,100명 전체 Fit은 개요용으로 작게 축소되므로 카드 읽기에는 Zoom 또는 초기 Depth를 사용한다.
|
||||
|
||||
React에서 `employeePopup="hm-dialog"`는 실제 공개 HM Dialog·Avatar·Button을 사용한다.
|
||||
`'core'`가 기본, `'none'`은 카드의 클릭·button 의미를 제거하되 키보드 이동용 초점은 유지한다. `onEmployeeClick`을
|
||||
지정하면 선택 모드와 관계없이 callback이 우선한다. HM 모드는
|
||||
`@hm-design/ui@0.1.0` optional peer와 호스트 `index.css → hm-theme.css` 연결이 필요하다.
|
||||
Core/Vanilla에는 React/HM 의존성을 추가하지 않았다. peer 없는 호스트의 모든 bundler
|
||||
조합 및 fresh install은 별도 미검증이다.
|
||||
|
||||
```tsx
|
||||
<OrgChart dataSource={source} stylesheetUrls={stylesheets} layoutMode="auto"
|
||||
autoLayout={{ type: 'lr', initialVisibleDepth: 2 }}
|
||||
interactions={{ collapse: false, zoom: true, pan: false }}
|
||||
employeePopup="hm-dialog" selectedCompanyIds={['hanmac', 'saman']} />
|
||||
```
|
||||
|
||||
## P9.3 브라우저 소속 변경
|
||||
|
||||
P9.4의 공통 Core/React 옵션 `dragDropEnabled?: boolean`은 기본 OFF다. 아래 소속 변경은
|
||||
ON에서 허용한다. React는 `dragDropEnabled={true}`, Vanilla는 생성 옵션 또는
|
||||
`handle.setDragDropEnabled(true)`로 활성화한다. `handle.getDragDropEnabled()`로
|
||||
현재 설정을 조회한다. OFF의 `handle.move()`는 `EDITING_DISABLED`를 반환하며 포인터와
|
||||
Alt+M도 시작하지 않는다. 전환 시 진행 중 이동·Pointer capture·Drop 강조를 취소하고
|
||||
이미 완료한 이동을 보존한다. 설정만 바꿀 때 데이터 재요청·재생성·레이아웃 갱신은 없다.
|
||||
직원 정보, 그룹 접기·펼치기, Zoom/Pan/Fit은 기존 독립 설정을 따른다. Fixed는 변경하지 않는다.
|
||||
|
||||
Expanded Story의 데이터 범위 UI는 제거했고 예시 직원 수20/100/300명은 회사별 기준만
|
||||
표시한다. 전체 합산 `createOrgChartExampleDataset` 공개 helper 계약은 유지한다.
|
||||
회사 선택은 즉시 표시를 갱신하고 숨김·복귀에도 완료한 이동을 유지한다. 직원 수는 기존
|
||||
**데이터 적용**으로 새 예시를 생성하며 임시 이동과 새 Fixture를 섞지 않는다. 초기 설정은
|
||||
7개 회사×20명=140명, 선택2개×100명=200명, 선택7개×300명=2,100명이다.
|
||||
|
||||
Expanded Story의 외곽 미리보기는 실제 Center Storybook 공통 카드 CSS의
|
||||
`--sb-center-card-background` / `--sb-center-card-border` / `--sb-center-card-radius`를
|
||||
재사용한다. 전용 `--hm-orgchart-expanded-preview-background`, `-border`, `-radius`
|
||||
입력은 `.hm-orgchart-expanded` 외곽에만 적용한다. 직원 카드·회사 타이틀·Viewport의
|
||||
색상 입력은 그대로이며, 입력을 생략한 Vanilla의 기존 기본 외곽 스타일은 유지한다.
|
||||
|
||||
Auto의 빈 공간 드래그는 기존 Pan이며 직원 카드·그룹 타이틀 드래그는 회사 내부 또는
|
||||
회사 간 소속 변경이다. 직원 이동은 `organizationId`, 조직 그룹 이동은 `parentId`를
|
||||
갱신한다. 같은 회사 내부에서는 파견 직원을 포함한 기존 `affiliationId`를 보존한다.
|
||||
회사 간 직원 이동은 `affiliationId`도 대상 회사로 변경하고, 회사 간 그룹 이동은 이동
|
||||
그룹과 하위 조직 전체의 `companyId`, 소속 직원 전체의 `affiliationId`도 대상 회사로
|
||||
변경한 새 snapshot을 현재 Core 인스턴스에 적용한다. ID·하위 계층·
|
||||
이름·직위·사진·조직장·정렬은 보존하며 회사 색상과 인원 집계는 대상 회사에 맞춰 갱신한다.
|
||||
원본 JSON·회사 프리셋·서버 데이터는 변경하지 않는다.
|
||||
그룹 클릭의 접기·펼치기와 직원 클릭의 정보 팝업은 유지하며 실제 드래그 뒤의 포인터
|
||||
click은 억제한다. 자기 자신·자손을 부모로 지정하는 이동, 회사 Root 이동,
|
||||
조직장 참조를 손상시키는 직원 이동은 거절하며 이유를 안내한다.
|
||||
|
||||
직원 카드 또는 그룹 타이틀에 초점을 둔 뒤 `Alt+M`으로 이동을 시작할 수 있다.
|
||||
방향키로 대상을 선택하고 `Enter`로 확인하거나 `ESC`로 취소한다. 팝업을 꺼도 직원
|
||||
카드는 이동 조작을 위한 초점을 제공한다. Fixed에는 소속 변경을 추가하지 않는다.
|
||||
|
||||
Core와 React의 `onMove(result: OrgChartMoveResult)`는 이동 성공·실패를 알린다.
|
||||
`result.moved`로 성공을 구분하며, React는 성공한 이동 후 열린 HM 직원 Dialog를 닫는다.
|
||||
React callback 변경은 최신 committed callback만 갱신하고 Core를 재생성하거나 reload하지 않는다.
|
||||
|
||||
Expanded Story는 모든 회사의 원본 예시를 하나의 세션 source로 유지하고 회사 선택은
|
||||
`selectedCompanyIds`로 처리한다. 회사 숨김·다시 표시·빈 선택은 성공한 소속 변경을
|
||||
보존한다. **데이터 적용**은 현재 draft 조건으로 새 예시 source를 만들고 이동 내용을
|
||||
초기화한다. **초기화**는 최초 설정과 최초 소속으로 돌아가며 설정값이 이미 최초값이어도
|
||||
이동 내용은 되돌린다. 파일을 다시 작성하거나 React key로 강제 remount하지 않는다.
|
||||
Story의 직원 합계와 그룹 선택은 성공한 `onMove`의 `result.data`를 별도 read model로
|
||||
읽으며, source identity는 유지한다. 표시 직원 수는 최초 예시 인원이 아닌 현재 조직의
|
||||
회사 소속을 기준으로 계산하므로 회사 간 이동 직후와 회사 숨김·다시 표시에도 일치한다.
|
||||
미리보기에는 선택 회사별 현재 직원 수도 표시하며 데이터 설정의 회사당 인원은 예시 생성 기준이다.
|
||||
Reference in new issue
Block a user