` | - | 드롭다운 팝업(리스트) 영역에 적용할 인라인 스타일 객체 |
| closeWhenPositionChanged | `boolean` | `false` | 버튼 위치 변경 시 자동으로 닫힘 |
| zIndexKey | `'toast'` \| `'tooltip'` \| `'menu'` \| `'dialog'` \| `'modal'` \| `'drawer'` \| `'mask'` | `'menu'` | 팝업 레이어의 z-index 그룹 키 |
| labelTooltipPlacement | `'top'` \| `'top-left'` \| `'top-right'` \| `'bottom'` \| `'bottom-left'` \| `'bottom-right'` \| `'left'` \| `'left-top'` \| `'left-bottom'` \| `'right'` \| `'right-top'` \| `'right-bottom'` | - | 라벨에 표시할 툴팁 위치 |
| size | `'large'` \| `'medium'` \| `'small'` | - | 컴포넌트 크기 |
| disabled | `boolean` | `false` | 비활성화 여부 |
## v-model
| 이름 | 타입 | 기본값 | 설명 |
| -------- | --------------- | ------ | --------------------------- |
| (기본) | `PropertyKey[]` | `[]` | 선택된 값들의 배열(양방향) |
## 이벤트
| 이름 | 파라미터 | 설명 |
| ----- | -------- | ---------------- |
| close | `void` | 드롭다운 닫힘 이벤트 |
## 쿠버네티스 사용 예시
쿠버네티스에서 네임스페이스를 선택할때 사용 예시입니다
[FloatLabel](../form-input/float-label) 도 같이 사용 했습니다
네임스페이스
```vue
네임스페이스
```
### File: menu/filter-multi-dropdown.md
# FilterMultiDropdown
## 기본 사용법
FilterMultiDropdown은 필터링 기능이 추가된 다중 선택 드롭다운 컴포넌트입니다. 사용자는 검색어를 입력하여 목록을 필터링할 수 있으며, 여러 항목을 선택할 수 있습니다. 선택된 항목은 드롭다운 버튼에 표시됩니다.
```vue
```
## Props
| 이름 | 타입 | 기본값 | 설명 |
| ----------- | --------------------------------------------------------------------------- | ------------- | ----------------------------------------- |
| list | `Array<{ label: string, value: PropertyKey, disabled?: boolean }>` | `[]` | 드롭다운 메뉴에 표시할 항목 목록 |
| title | `string` | `undefined` | 드롭다운 라벨 (선택사항) |
| text | `{ selectAllItemLabel: string, whenFilterEmpty: string, noResult: string, noList: string }` | - | 텍스트 라벨 설정 객체 |
| leadingIcon | `IconTypes` | `undefined` | 입력 필드 왼쪽에 표시할 아이콘 (선택사항) |
| type | `'outlined' \| 'contained'` | - | 입력 박스 스타일(외곽선/채움) |
| visibleRows | `number` | `9.35` | 드롭다운 메뉴에 표시할 최대 행 수 |
| size | `'large' \| 'medium' \| 'small'` | `'medium'` | 컴포넌트 크기 |
| disabled | `boolean` | `false` | 비활성화 여부 |
| zIndexKey | `'toast' \| 'tooltip' \| 'menu' \| 'dialog' \| 'modal' \| 'drawer' \| 'mask'` | `'menu'` | 팝업 레이어의 z-index 그룹 키 |
## 타입(Type) 스타일
Outlined(기본)와 Contained(배경 채움) 두 가지 스타일을 지원합니다.
```vue
```
## v-model
| 이름 | 타입 | 기본값 | 설명 |
| ------------- | --------------- | ------- | ------------------------- |
| open | `boolean` | `false` | 드롭다운 메뉴의 열림 상태 |
| selectedList | `PropertyKey[]` | `[]` | 선택된 항목 값들의 배열 |
| searchKeyword | `string` | `''` | 현재 검색 키워드 |
## 이벤트
| 이름 | 파라미터 | 설명 |
| -------------------- | --------------- | ---------------------------- |
| update:selectedList | `PropertyKey[]` | 선택된 항목이 변경될 때 발생 |
| update:searchKeyword | `string` | 검색 키워드가 변경될 때 발생 |
## 검색 및 필터링 기능
FilterMultiDropdown은 사용자가 검색어를 입력하면 목록을 실시간으로 필터링합니다. 필터링된 목록에 대해 전체 선택 옵션도 제공됩니다.
과일 필터
```vue
과일 필터
```
## 빈 리스트 처리
FilterMultiDropdown은 리스트가 비어 있을 때 적절한 메시지를 표시합니다. 검색어가 있는 경우는 "검색 결과가 없습니다"라는 메시지가, 검색어가 없는 경우는 리스트가 비어 있다는 것을 알립니다.
```vue
```
## 크기(Size) 설정 예시
FilterMultiDropdown 컴포넌트는 'small', 'medium', 'large' 세 가지 크기 옵션을 지원합니다. 기본값은 'medium'입니다.
```vue
```
### 접근성
| 키 | 기능 |
| ------------------- | -------------------------------------------------------------- |
| 방향키 ↑ / ↓ | 메뉴 항목 포커스를 한 단계씩 이동 |
| Alt + ↑ / Alt + ↓ | 메뉴 항목 포커스를 5개씩 이동 (macOS에서는 Option 키) |
| Ctrl + ↑ / Ctrl + ↓ | 가장 처음 / 마지막 메뉴 항목으로 이동 (macOS에서는 Command 키) |
| Home | 가장 처음 메뉴 항목으로 이동 |
| End | 가장 마지막 메뉴 항목으로 이동 |
| Enter | 현재 포커스된 메뉴 항목 선택 또는 선택 해제 |
| Escape | 드롭다운 메뉴 닫기 |
### File: menu/filter-single-dropdown.md
# FilterSingleDropdown
## 기본 사용법
FilterSingleDropdown은 필터링 기능이 추가된 단일 선택 드롭다운 컴포넌트입니다. 사용자는 검색어를 입력하여 목록을 필터링할 수 있으며, 하나의 항목만 선택할 수 있습니다. 선택된 항목은 드롭다운 버튼에 표시됩니다.
```vue
```
## Props
| 이름 | 타입 | 기본값 | 설명 |
| --------------- | ------------------------------------------------------------------ | ------------- | ----------------------------------------- |
| list | `Array<{ label: string, value: PropertyKey, disabled?: boolean }>` | `[]` | 드롭다운 메뉴에 표시할 항목 목록 |
| title | `string` | `undefined` | 드롭다운 라벨 (선택사항) |
| text | `{ whenFilterEmpty: string, noResult: string, noList: string }` | - | 텍스트 라벨 설정 객체 |
| leadingIcon | `IconTypes` | `undefined` | 입력 필드 왼쪽에 표시할 아이콘 (선택사항) |
| type | `'outlined' \| 'contained'` | `'outlined'` | 입력 박스 스타일(외곽선/채움) |
| visibleRows | `number` | `9.35` | 드롭다운 메뉴에 표시할 최대 행 수 |
| size | `'large' \| 'medium' \| 'small'` | `'medium'` | 컴포넌트 크기 |
| disabled | `boolean` | `false` | 비활성화 여부 |
| zIndexKey | `'toast' \| 'tooltip' \| 'menu' \| 'dialog' \| 'modal' \| 'drawer' \| 'mask'` | `'menu'` | 팝업 레이어의 z-index 그룹 키 |
| closeWhenSelect | `boolean` | `true` | 항목 선택 시 드롭다운 자동 닫힘 |
## v-model
| 이름 | 타입 | 기본값 | 설명 |
| ----------------- | --------------------- | ------- | ------------------------- |
| open | `boolean` | `false` | 드롭다운 메뉴의 열림 상태 |
| selectedItemValue | `PropertyKey \| null` | `null` | 선택된 항목의 값 |
| searchKeyword | `string` | `''` | 현재 검색 키워드 |
## 이벤트
| 이름 | 파라미터 | 설명 |
| ---------------------- | --------------- | ---------------------------- |
| update:selectedItemValue | `PropertyKey` | 선택된 항목이 변경될 때 발생 |
| update:searchKeyword | `string` | 검색 키워드가 변경될 때 발생 |
## 검색 및 필터링 기능
FilterSingleDropdown은 사용자가 검색어를 입력하면 목록을 실시간으로 필터링합니다. 필터링된 목록에서 사용자는 원하는 항목을 선택할 수 있습니다.
과일 필터
```vue
과일 필터
```
## 빈 리스트 처리
FilterSingleDropdown은 리스트가 비어 있을 때 적절한 메시지를 표시합니다. 검색어가 있는 경우는 "검색 결과가 없습니다"라는 메시지가, 검색어가 없는 경우는 리스트가 비어 있다는 것을 알립니다.
```vue
```
## 크기(Size) 설정 예시
FilterSingleDropdown 컴포넌트는 'small', 'medium', 'large' 세 가지 크기 옵션을 지원합니다. 기본값은 'medium'입니다.
```vue
```
## 타입(Type) 스타일
Outlined(기본)와 Contained(배경 채움) 두 가지 스타일을 지원합니다.
```vue
```
### 접근성
| 키 | 기능 |
| ------------------- | -------------------------------------------------------------- |
| 방향키 ↑ / ↓ | 메뉴 항목 포커스를 한 단계씩 이동 |
| Alt + ↑ / Alt + ↓ | 메뉴 항목 포커스를 5개씩 이동 (macOS에서는 Option 키) |
| Ctrl + ↑ / Ctrl + ↓ | 가장 처음 / 마지막 메뉴 항목으로 이동 (macOS에서는 Command 키) |
| Home | 가장 처음 메뉴 항목으로 이동 |
| End | 가장 마지막 메뉴 항목으로 이동 |
| Enter | 현재 포커스된 메뉴 항목 선택 |
| Escape | 드롭다운 메뉴 닫기 |
## Data
### File: data/tree.md
# Tree
Tree 컴포넌트는 디렉터리, 조직도, 분류 체계 등 계층적인 구조의 데이터를 표현할 때 사용합니다.
사용자는 각 노드를 확장하거나 축소하고, 선택할 수 있어 구조를 직관적으로 탐색할 수 있습니다.
## Tree
```vue
```
## Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| --------- | ------------------------------------- | --------- | ----------- | --------------------- |
| nodes | `TreeNodeData[]` | Yes | - | 트리 노드 데이터 배열 |
| treeType | `'default'` \| `'folder'` \| `'icon'` | No | `'default'` | 트리 표시 타입 |
## v-model
| 이름 | 타입 | 기본값 | 설명 |
| ------ | ---------------- | ------ | ----------------------- |
| (기본) | `string \| null` | `null` | 선택된 노드의 id 바인딩 |
## 이벤트
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | -------------------- | ----------------- |
| node-click | `node: TreeNodeData` | 노드 클릭 시 발생 |
## Icon Tree
```vue
```
## Folder Tree
```vue
```
## Misc
### File: misc/chips.md
# Chips
## 기본
### Default
default-slot
```vue
default-slot
```
## Props
| 이름 | 타입 | 기본값 | 설명 |
| ---------- | ------------------------------------------- | ------- | -------------------- |
| text | `string` | - | 칩에 표시할 텍스트 |
| useToggle | `boolean` | `false` | 클릭 시 토글 사용 여부 |
| selected | `boolean` | `false` | 선택 상태 |
| readonly | `boolean` | - | 읽기 전용 여부 |
| size | `'large'` \| `'medium'` \| `'small'` | - | 컴포넌트 크기 |
| disabled | `boolean` | `false` | 비활성화 여부 |
### Size
```vue
```
## Filter, Disabled
태그나 단어등 콘텐츠를 필터링하는데 사용합니다. 토글 버튼이나 체크박스의 대안으로 사용할 수 있습니다.
### 기본
```vue
```
### 구성
```vue
```
## 성능 브라우저
성능 브라우저에서 조회 조건을 remove, off 로 변경 할 수 있습니다.
```vue
```
### File: misc/badge.md
# Badge
## Basic
```vue
```
## Props
| Prop | Type | Default | Description |
| :------------ | :--------------------------------------------------- | :------------ | :--------------------------------- |
| `size` | `'large'` \| `'medium'` \| `'small'` | `N/A` | 배지 크기 |
| `color` | `'primary'` \| `'gray'` \| `'red'` \| `'green'` \| `'blue'` \| `'purple'` \| `'pink'` \| `'orange'` \| `'teal'` \| `'skyblue'` \| `'inverted'` \| `'gray-light'` \| `'red-light'` \| `'green-light'` \| `'blue-light'` \| `'purple-light'` \| `'pink-light'` \| `'orange-light'` \| `'teal-light'` \| `'skyblue-light'` \| `'inverted-light'` | `'gray-light'` | 배지 색상 |
| `text` | `string` | `N/A` | 배지에 표시할 텍스트 |
| `leadingIcon` | `IconTypes` | `undefined` | 텍스트 앞에 표시할 아이콘 |
| `trailingIcon`| `IconTypes` | `undefined` | 텍스트 뒤에 표시할 아이콘 |
## Size
```vue
```
## Color
```vue
```
### File: misc/badge-digit.md
# BadgeDigit
## Basic
```vue
```
## Props
| Prop | Type | Default | Description |
| :----- | :--- | :------ | :---------- |
| `value` | `number` | `0` | 표시할 숫자 값 |
| `color` | `'primary'` \| `'gray'` \| `'red'` \| `'green'` \| `'blue'` \| `'purple'` \| `'pink'` \| `'orange'` \| `'teal'` \| `'skyblue'` \| `'inverted'` \| `'gray-light'` \| `'red-light'` \| `'green-light'` \| `'blue-light'` \| `'purple-light'` \| `'pink-light'` \| `'orange-light'` \| `'teal-light'` \| `'skyblue-light'` \| `'inverted-light'` \| `'primary-inverted'` \| `'gray-inverted'` \| `'red-inverted'` \| `'green-inverted'` \| `'blue-inverted'` \| `'purple-inverted'` \| `'pink-inverted'` \| `'orange-inverted'` \| `'teal-inverted'` \| `'skyblue-inverted'` \| `'inverted-inverted'` | `'gray-light'` | 배지 색상 |
## 1, 10, 100, 1000...
```vue
```
## Color
```vue
```
### File: misc/badge-dot.md
# BadgeDot
## Basic
```vue
```
## Props
| Prop | Type | Default | Description |
| :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :---------- |
| `color` | `'primary'` \| `'gray'` \| `'red'` \| `'green'` \| `'blue'` \| `'purple'` \| `'pink'` \| `'orange'` \| `'teal'` \| `'skyblue'` \| `'inverted'` \| `'gray-light'` \| `'red-light'` \| `'green-light'` \| `'blue-light'` \| `'purple-light'` \| `'pink-light'` \| `'orange-light'` \| `'teal-light'` \| `'skyblue-light'` \| `'inverted-light'` | `'gray-light'` | 배지 점 색상 |
## Color
```vue
```
### File: misc/progress-button.md
# ProgressButton
## Basic
```vue
```
## Props
| 이름 | 타입 | 기본값 | 설명 |
| -------- | ------------------------------------------- | ---------- | ------------------------------ |
| type | `'circle'` | `'circle'` | 진행 표시 유형 |
| ratio | `number` | `0` | 진행 비율 (0 ~ 1 사이) |
| size | `'large'` \| `'medium'` \| `'small'` | - | 컴포넌트 크기 |
| disabled | `boolean` | `false` | 비활성화 여부 |
## Size
```vue
```
## Animate (can stop by clicking)
```vue
```
### File: misc/progress-circle.md
# Progress Circle
- 조회 기간이 오래 걸리는 조회 화면에서 사용자가 대기 상태를 알 수 있도록 도와주는 컴포넌트
## Basic
```vue
```
## Props
| 이름 | 타입 | 기본값 | 설명 |
| ----- | -------- | ------ | ---------------------- |
| ratio | `number` | `0` | 진행 비율 (0 ~ 1 사이) |
## Animate
```vue
```
### File: misc/progress-indicator.md
# Progress Indicator
- 분석화면에서 로딩 상태를 표시하는 컴포넌트
## Basic
## Props
이 컴포넌트는 Props를 받지 않습니다.
```vue
Loading...
```
### File: misc/spinner.md
# Spinner
- 데이터 로딩, 작업 진행 중 등의 대기 상태를 사용자에게 시각적으로 표시하는 컴포넌트
- 원형으로 회전하는 애니메이션을 통해 진행 중인 상태를 나타냄
## Basic
```vue
```
## Props
| Prop | Type | Default | Description |
| ----------- | ----------------------------------------------- | -------------------------- | ------------------------------ |
| color | `string` | `var(--overlay-primary-900)`| 스피너의 색상 |
| circleColor | `string` | - | 배경 원의 색상(테마에 따라 사용) |
| duration | `string` | `'1.5s'` | 애니메이션 시간 (예: '1.5s') |
| size | `'mini'` \| `'small'` \| `'medium'` \| `'large'` | `'medium'` | 스피너 크기 |
## Sizes
- Spinner는 mini, small, medium, large 네 가지 크기로 제공됩니다
```vue
```
## Custom Color
- Spinner의 색상을 변경할 수 있습니다
```vue
```
## Custom Animation Duration
- Spinner의 애니메이션 속도를 조절할 수 있습니다 (기본값: 1.5s)
```vue
Fast (500ms)
Default (1.5s)
Slow (2000ms)
```
Fast (500ms)
Default (1.5s)
Slow (2000ms)
### File: misc/progress-spinner.md
# Progress Spinner
Progress Spinner는 진행 상태를 원형 애니메이션으로 표시하는 컴포넌트입니다. 로딩 상태를 표시하거나 특정 작업의 진행률을 시각적으로 나타낼 때 사용합니다.
## 기본 사용법
```vue
```
## Props
| 속성 | 타입 | 기본값 | 설명 |
| --------------- | -------- | ---------------------------- | ------------------------------------ |
| `progressRatio` | `number` | `0` | 진행률을 나타내는 값 (0 ~ 1 사이) |
| `color` | `string` | `var(--overlay-primary-900)` | 진행 표시기의 색상 |
| `circleColor` | `string` | `var(--overlay-primary-100)` | 배경 원의 색상 |
| `duration` | `string` | `1.5s` | 애니메이션 지속 시간 |
| `size` | `string` | `medium` | 컴포넌트 크기 (small, medium, large) |
## 진행률 표시하기
`progressRatio` 속성을 사용하여 0부터 1 사이의 값으로 진행률을 표시할 수 있습니다:
```vue
```
위 예제는 원형의 75%가 채워진 상태를 보여줍니다.
## 크기 옵션
Progress Spinner는 세 가지 크기를 지원합니다:
- `small`: 24px
- `medium`: 32px (기본값)
- `large`: 48px
```vue
```
## 색상 변경하기
기본 색상을 변경하려면 `color`와 `circleColor` 속성을 사용합니다:
```vue
```
## 동작 원리
Progress Spinner는 SVG 요소를 사용하여 원형 진행률을 표시합니다. `stroke-dasharray`와 `stroke-dashoffset` 속성을 활용하여 원의 일부분만 표시함으로써 진행률을 시각화합니다.
진행률은 다음과 같이 계산됩니다:
1. 원의 둘레(circumference)를 계산합니다: `2 * π * 반지름`
2. `progressRatio` 값(0~1)에 따라 stroke-dasharray 속성을 설정합니다
3. 이를 통해 원의 특정 부분만 표시되도록 합니다
## 예제: 로딩 상태와 진행률 표시
```vue
로딩 중: {{ Math.round(autoProgress * 100) }}%
다운로드 진행률: {{ Math.round(progress * 100) }}%
```
## 예제: 현재 상태
아래는 이 페이지의 모든 예시 스피너들의 현재 진행률을 한눈에 보여줍니다:
기본: {{ Math.round(baseProgress * 100) }}%
작은: {{ Math.round(smallProgress * 100) }}%
중간: {{ Math.round(mediumProgress * 100) }}%
큰: {{ Math.round(largeProgress * 100) }}%
색상: {{ Math.round(colorProgress * 100) }}%
## 접근성
Progress Spinner 컴포넌트는 `role="progressbar"` 속성을 포함하여 스크린 리더 등의 접근성 도구에서 적절하게 인식됩니다.
### File: misc/skeleton.md
# Skeleton
- 데이터 로딩 중에 UI 레이아웃을 미리 표시하는 플레이스홀더 컴포넌트
- 실제 콘텐츠가 로드되기 전에 화면 구조를 유지하여 사용자 경험 향상
- 펄스 애니메이션으로 로딩 상태를 시각적으로 표시
- 라인별 스켈레톤 효과로 텍스트가 여러 줄일 때 각 줄마다 스켈레톤 표시
## Basic
```vue
```
## Props
| Prop | Type | Default | Description |
| --------- | ---------------- | ---------- | ------------------------------------------ |
| loading | `boolean` | `true` | 스켈레톤 로딩 상태 활성화 여부 |
| radius | `string\|number` | `'0.5rem'` | 스켈레톤 테두리 반경 |
| width | `string\|number` | - | 인라인 모드에서 너비 (자식 있는 경우 무시) |
| minWidth | `string\|number` | - | 최소 너비 |
| maxWidth | `string\|number` | - | 최대 너비 |
| height | `string\|number` | - | 높이 |
| minHeight | `string\|number` | `'1rem'` | 최소 높이 (height가 지정된 경우 무시) |
| maxHeight | `string\|number` | - | 최대 높이 |
## Toggle Loading
- `loading` prop으로 로딩 상태를 제어할 수 있습니다
```vue
```
## Inline Mode (No Children)
- 자식 요소 없이 사용하면 인라인 모드로 작동합니다
- `width`, `height`, `radius` 등의 속성으로 스타일을 직접 제어할 수 있습니다
```vue
```
## With Children
- 자식 요소가 있을 경우, 로딩 상태에서는 자식 요소를 숨기고 스켈레톤 효과를 표시합니다
- 로딩이 완료되면 자동으로 실제 콘텐츠가 표시됩니다
- 자식 요소의 DOM 구조와 레이아웃을 유지합니다
{{ loading ? '로딩 중지' : '로딩 시작' }}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Pellentesque felis tellus, efficitur id convallis a, viverra
eget libero. Nam magna erat, fringilla sed commodo sed,
aliquet nec magna.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Pellentesque felis tellus, efficitur id convallis a, viverra
eget libero. Nam magna erat, fringilla sed commodo sed,
aliquet nec magna.
```vue
{{ loading ? '로딩 중지' : '로딩 시작' }}
실제 콘텐츠
로딩이 완료되면 이 내용이 표시됩니다.
```
## Card Example
- 카드 레이아웃에 적용한 예시입니다
{{ loading ? '로딩 중지' : '로딩 시작' }}
카드 제목
카드 설명 텍스트입니다. 로딩이 완료되면 표시됩니다.
```vue
{{ loading ? '로딩 중지' : '로딩 시작' }}
카드 제목
카드 설명 텍스트입니다. 로딩이 완료되면 표시됩니다.
```
## 동작 방식
Skeleton 컴포넌트는 두 가지 주요 모드로 동작합니다:
### 인라인 텍스트 모드
- 텍스트 콘텐츠를 감쌀 때 적용됩니다 (예: ``, `` 등의 텍스트)
- **라인별 스켈레톤 효과**: 텍스트가 여러 줄일 경우 각 줄마다 개별 스켈레톤이 표시됩니다
- `line-height: 0`, `box-decoration-break: clone` 속성을 통해 라인별 효과 구현
- 원래 텍스트의 줄바꿈, 폰트 크기, 간격이 그대로 유지됩니다
### 엘리먼트 래핑 모드
- 요소나 컴포넌트를 감쌀 때 적용됩니다 (예: ``, `
` 등)
- 원본 DOM 구조를 유지하면서 스켈레톤 효과만 적용합니다
- 로딩 중에는 자식 요소의 가시성만 숨기고(visibility: hidden) 레이아웃은 유지
- `inert` 속성과 `aria-busy` 속성으로 접근성 보장 및 인터랙션 차단
둘 다 다음과 같은 공통 기능을 제공합니다:
- 로딩 상태에서 원본 콘텐츠와 동일한 크기와 모양 유지
- 펄스 애니메이션으로 로딩 중임을 시각적으로 표시
- 사용자 상호작용 차단 (pointer-events: none)
## Custom Radius
- `radius` prop으로 테두리 반경을 조절할 수 있습니다
```vue
```
## Legend
### File: legend/legend.md
# Legend
`Legend`는 차트나 리스트 등에서 색상과 라벨을 함께 보여주는 범례 컴포넌트입니다.
## Props
| Prop | Type | Default | Description |
| :------- | :---------------------------------------- | :------ | :-------------------------------------------------------------- |
| `label` | `string` | `N/A` | 범례에 표시될 텍스트 |
| `color` | `string` | `N/A` | 배지의 배경색. CSS 색상 문자열(`#0EA5E9`, `rgb()`, CSS 변수 등) |
| `type` | `'static'` \| `'interactive'` | `N/A` | 범례 타입 |
| `status` | `'default'` \| `'active'` \| `'inactive'` | `N/A` | 상태 값. 타입에 따라 허용되는 값이 다릅니다. |
### 타입별 Props 제약
- **static**: `type: 'static' | undefined`, `status: 'default'` 고정
- **interactive**: `type: 'interactive'`, `status: 'default' | 'active' | 'inactive'`
## Usage
### Static
```vue
```
### Interactive (상태별)
```vue
```
### Interactive 상태 전환 예시
선택된 항목만 `active`, 나머지는 `inactive`, 선택이 없으면 모두 `default`로 표시되는 예시입니다. 같은 항목을 다시 클릭하면 선택이 해제되어 모두 `default` 상태로 돌아갑니다.
selected: {{ selected || 'none' }}
```vue
selected: {{ selected || 'none' }}
```
## Status Indicator
### File: status-indicator/index.md
# StatusIndicator
`StatusIndicator`는 상태를 시각적으로 표시하는 데 사용되는 컴포넌트입니다.
## Props
| Prop | Type | Default | Description |
| :------ | :----------------------------------------------------------- | :---------- | :------------------------------ |
| `type` | `'default'` \| `'fill'` \| `'dot'` | `'default'` | 인디케이터의 스타일 타입입니다. |
| `color` | `'green'` \| `'red'` \| `'orange'` \| `'blue'` \| `'yellow'` | `N/A` | 인디케이터의 색상입니다. (필수) |
| `size` | `'mini'` \| `'small'` \| `'medium'` \| `'large'` | `'medium'` | 인디케이터의 크기입니다. |
| `disabled` | `boolean` | `false` | Disable state |
## Usage
### Default
Running
```vue
Running
```
### Fill
Running
```vue
Running
```
### Dot
`dot` 타입은 텍스트 왼쪽에 색상 점을 표시합니다.
Running
```vue
Running
```
## Examples
### Default
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
### Fill
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
### Dot
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
Blue
Red
Orange
Yellow
Green
## Tab
### File: tab/tabs.md
# Tabs
탭(Tabs) 컴포넌트는 사용자가 키보드나 마우스를 사용하여 여러 개의 콘텐츠 패널 중 하나를 선택하고 전환할 수 있도록 하는 요소입니다.
각 탭은 특정 패널을 대표하며, 클릭 또는 선택 시 해당 패널의 내용이 표시됩니다.
## 기본 사용법
```vue
{{ activeTab }}
```
## Props
### Tabs 컴포넌트
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| ------------- | ---------------------------- | --------- | -------- | ----------------------------------------------- |
| activeTab | `string \| number \| symbol` | Yes | - | 현재 선택된 탭의 키 |
| tabs | `TabItem[]` | Yes | - | 탭 아이템 배열 |
| tabIdentifier | `string` | No | `'tabs'` | 탭의 고유 키를 생성할 때 사용되는 접두사 식별자 |
tabIdentifier 는 tabs props가 변경되었지만 tab key가 그대로 유지되는 경우 indicator가 제대로 작동하지 않거나 Tab 컴포넌트 자체가 제대로 업데이트 되지 않는 현상을 방지하기 위한 추가 식별자입니다. Tabs 컴포넌트에서는 기본값이 `'tabs'` 입니다.
### TabItem 인터페이스
| 속성 | 타입 | 필수 여부 | 설명 |
| ------------ | ---------------------------- | --------- | --------------------- |
| tabKey | `string \| number \| symbol` | Yes | 탭을 식별하는 고유 키 |
| label | `string` | Yes | 탭에 표시될 텍스트 |
| disabled | `boolean` | No | 탭 비활성화 여부 |
| tooltip | `TooltipProps` | No | 탭에 표시될 툴팁 |
| icon | `IconTypes` | No | 탭에 표시될 아이콘 |
| badgeContent | `number` | No | 배지에 표시될 숫자 |
| contextKey | `any` | No | 탭의 컨텍스트 키 |
## Example
{{ activeTab }}
## Events
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | ------------------------------------ | ------------------------- |
| select:tab | `tabKey: string \| number \| symbol` | 탭이 선택되었을 때 발생 |
| focus:tab | `tabKey: string \| number \| symbol` | 탭이 포커스되었을 때 발생 |
## 접근성
- 키보드 탐색이 지원됩니다
- 비활성화된 탭은 `disabled` 속성이 적용됩니다
## Tab Contraction
Tabs는 고수준 편의 래퍼(Tabs 컴포넌트) 외에도, 더 유연한 조합형 API를 제공합니다. 이 계약을 `TabContraction`이라고 하며, 아래 세 부분으로 구성됩니다.
- **[TabList]**
- **[Tab]**
- **[contextKey]**
### TabList
- **개요**
- `Tab` 항목을 감싸는 리스트 컨테이너입니다.
- 키보드 내비게이션, 인디케이터(Primary) 등을 관리합니다.
#### Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| ----------- | ----------------------------------------------------------------- | --------- | ------------- | -------------------------- |
| selectedKey | `string \| number \| symbol` | Yes | - | 현재 선택된 탭의 키 |
| contextKey | `string \| InjectionKey
` | No | `'tabContext'`| 탭 그룹 컨텍스트 키 |
| type | `'primary' \| 'secondary'` | No | `'primary'` | 탭 리스트 스타일 |
#### Events
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | ----------------------------------- | ----------------------- |
| select:tab | `tabKey: string \| number \| symbol` | 탭이 선택되었을 때 발생 |
| focus:tab | `tabKey: string \| number \| symbol` | 탭이 포커스되었을 때 |
### Tab
#### Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| ------------ | ----------------------------------------------------------------- | --------- | ------ | ---------------- |
| contextKey | `string \| InjectionKey` | No | - | 탭 컨텍스트 키 |
| tabKey | `string \| number \| symbol` | Yes | - | 탭 고유 키 |
| label | `string` | Yes | - | 탭 라벨 |
| disabled | `boolean` | No | `false`| 비활성화 여부 |
| tooltip | `TooltipProps` | No | - | 툴팁 |
| icon | `IconTypes` | No | - | 아이콘 |
| badgeContent | `number` | No | - | 배지 숫자 |
### contextKey
- 동일 화면에 서로 다른 탭 그룹이 공존할 때 상호 간섭을 막기 위해 사용합니다.
- `const contextKey = Symbol('tabContext')` 형태로 정의 후 `TabList`와 각 `Tab`에 동일하게 전달하세요.
### Context API
| 이름 | 타입 | 설명 |
| ----------- | --------------------------------------------------------- | --------------------------- |
| selectedKey | `Ref` | 현재 선택된 탭 키 |
| focusedKey | `Ref` | 현재 포커스된 탭 키 |
| tabElemMap | `Map` | 탭 키와 엘리먼트 매핑 |
| tabOrder | `(string \| number \| symbol)[]` | 탭 렌더링 및 탐색 순서 |
| selectTab | `(key: string \| number \| symbol) => void` | 지정 키를 선택 |
| focusTab | `(key: string \| number \| symbol) => void` | 지정 키로 포커스 이동 |
| register | `(key: string \| number \| symbol, el: HTMLElement) => void` | 탭 요소 등록 |
### Tabs 래퍼와의 관계
- `Tabs` 컴포넌트는 위의 `TabList` + `Tab`을 조합하여 사용하기 쉬운 고수준 래퍼입니다.
- `tabIdentifier`는 `tabs` 배열이 갱신될 때 인디케이터/렌더링 동기화를 돕는 보조 식별자입니다.
### 예시: 조합형 사용(Primary)
```vue
### File: tab/secondary.md
# Secondary Tabs
Secondary Tabs 컴포넌트는 2차 메뉴나 서브 탐색에 사용되는 인터페이스 요소입니다. Primary Tabs와 달리 배경색이 있고 더 컴팩트한 디자인을 가지고 있습니다.
## 기본 사용법
```vue
```
## Props
### SecondaryTabs 컴포넌트
| Prop 이름 | 타입 | 필수 여부 | 설명 |
| ------------- | ---------------------------- | --------- | ------------------- |
| activeTab | `string \| number \| symbol` | Yes | 현재 선택된 탭의 키 |
| tabs | `TabItem[]` | Yes | 탭 아이템 배열 |
| tabIdentifier | `string` | No | 탭 키 생성용 접두사 |
### TabItem 인터페이스
| 속성 | 타입 | 필수 여부 | 설명 |
| ------------ | ---------------------------- | --------- | --------------------- |
| tabKey | `string \| number \| symbol` | Yes | 탭을 식별하는 고유 키 |
| label | `string` | Yes | 탭에 표시될 텍스트 |
| disabled | `boolean` | No | 탭 비활성화 여부 |
| tooltip | `TooltipProps` | No | 탭에 표시될 툴팁 |
| icon | `IconTypes` | No | 탭에 표시될 아이콘 |
| badgeContent | `number` | No | 배지에 표시될 숫자 |
| contextKey | `any` | No | 탭의 컨텍스트 키 |
## Example
{{ activeTab }}
## Events
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | ------------------------------------ | ------------------------- |
| select:tab | `tabKey: string \| number \| symbol` | 탭이 선택되었을 때 발생 |
| focus:tab | `tabKey: string \| number \| symbol` | 탭이 포커스되었을 때 발생 |
## 접근성
- 키보드 탐색이 지원됩니다 (← →)
- 비활성화된 탭은 `disabled` 속성이 적용됩니다
- 포커스 시 시각적 표시가 제공됩니다
## Tab Contraction (Secondary)
Secondary Tabs 역시 조합형 API(`TabContraction`)로 사용할 수 있습니다. Primary와 동일한 계약을 따르며, 스타일만 `secondary`로 적용합니다.
- **[TabList]**: `type='secondary'`를 지정하면 인디케이터 없이 세컨더리 스타일이 적용됩니다
- **[SecondaryTab]**: 각 탭 아이템(아이콘/배지/툴팁/disabled 지원)
- **[contextKey]**: 동일 화면 내 여러 탭 그룹 간 간섭 방지
### TabList (secondary)
#### Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| ----------- | ----------------------------------------------------------------- | --------- | ------------- | -------------------- |
| selectedKey | `string \| number \| symbol` | Yes | - | 현재 선택된 탭의 키 |
| contextKey | `string \| InjectionKey` | No | `'tabContext'`| 탭 그룹 컨텍스트 키 |
| type | `'secondary'` | No | `'secondary'` | 세컨더리 스타일 강제 |
#### Events
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | ----------------------------------- | ----------------------- |
| select:tab | `tabKey: string \| number \| symbol` | 탭이 선택되었을 때 발생 |
| focus:tab | `tabKey: string \| number \| symbol` | 탭이 포커스되었을 때 |
### SecondaryTab
#### Props
| Prop 이름 | 타입 | 필수 여부 | 기본값 | 설명 |
| ------------ | ----------------------------------------------------------------- | --------- | ------ | --------------- |
| contextKey | `string \| InjectionKey` | No | - | 탭 컨텍스트 키 |
| tabKey | `string \| number \| symbol` | Yes | - | 탭 고유 키 |
| label | `string` | Yes | - | 탭 라벨 |
| disabled | `boolean` | No | `false`| 비활성화 여부 |
| tooltip | `TooltipProps` | No | - | 툴팁 |
| icon | `IconTypes` | No | - | 아이콘 |
| badgeContent | `number` | No | - | 배지 숫자 |
### Context API
| 이름 | 타입 | 설명 |
| ----------- | --------------------------------------------------------- | --------------------------- |
| selectedKey | `Ref` | 현재 선택된 탭 키 |
| focusedKey | `Ref` | 현재 포커스된 탭 키 |
| tabElemMap | `Map` | 탭 키와 엘리먼트 매핑 |
| tabOrder | `(string \| number \| symbol)[]` | 탭 렌더링 및 탐색 순서 |
| selectTab | `(key: string \| number \| symbol) => void` | 지정 키를 선택 |
| focusTab | `(key: string \| number \| symbol) => void` | 지정 키로 포커스 이동 |
| register | `(key: string \| number \| symbol, el: HTMLElement) => void` | 탭 요소 등록 |
### 예시: 조합형 사용(Secondary)
```vue
## Scroll
### File: scroll/index.md
# Overlay Scroll
오버레이 스크롤(Overlay Scroll) 컴포넌트는 기본 브라우저 스크롤바를 대체하여 사용자 정의 스크롤바를 제공하는 UI 요소입니다.
이 컴포넌트는 브라우저의 기본 스크롤 기능을 유지하면서 OS 및 브라우저 환경과 무관하게 시각적으로 일관된 사용자 경험을 제공합니다.
## 기본 사용법
```vue
```
## Props
이 컴포넌트는 Props를 받지 않습니다.
## Example
## 동적 콘텐츠 예시
아래 예시는 콘텐츠 양이 변경될 때 스크롤 썸(thumb)의 크기와 위치가 자동으로 조정되는 것을 보여줍니다. 버튼을 클릭하여 아이템 개수를 늘리거나 줄여보세요.
```vue
아이템 늘리기
아이템 줄이기
현재 아이템 개수: {{ itemCount }}
```
현재 아이템 개수: {{ itemCount }}
## 가로 스크롤 예시
가로 스크롤이 필요한 경우에도 OverlayScroll 컴포넌트를 활용할 수 있습니다. 컴포넌트는 자동으로 콘텐츠의 가로 너비를 감지하여 필요한 경우 가로 스크롤바를 표시합니다.
```vue
```
## 동작 원리
오버레이 스크롤 컴포넌트는 다음과 같은 방식으로 동작합니다:
1. 실제 스크롤은 브라우저의 기본 스크롤 메커니즘을 사용합니다.
2. 기본 스크롤바는 CSS를 통해 시각적으로 숨겨집니다.
3. 사용자 정의 스크롤 트랙과 썸(thumb)이 오버레이로 표시됩니다.
4. 스크롤 이벤트가 발생하면 사용자 정의 썸의 위치가 실제 스크롤 위치에 맞게 업데이트됩니다.
5. ResizeObserver를 사용하여 콘텐츠 크기 변경을 감지하고 썸 크기와 위치를 자동으로 조정합니다.
## 구성 요소
컴포넌트는 다음과 같은 주요 요소로 구성됩니다:
- **스크롤 래퍼(Wrapper)**: 전체 컴포넌트를 감싸는 컨테이너
- **스크롤 트랙(Track)**: 사용자 정의 스크롤바가 움직이는 영역
- **스크롤 썸(Thumb)**: 사용자가 볼 수 있는 스크롤바 핸들
- **스크롤 박스(Box)**: 실제 스크롤이 적용되는 영역
- **스크롤 콘텐츠(Content)**: 사용자가 제공하는 실제 콘텐츠가 들어가는 영역
## Events
| 이벤트 이름 | 파라미터 | 설명 |
| ----------- | ------------ | ---------------------------------------------------------- |
| scroll | event: Event | 스크롤이 발생했을 때 트리거됨. 네이티브 이벤트 그대로 전파 |
## 스타일링
오버레이 스크롤 컴포넌트는 다음과 같은 CSS 클래스를 사용합니다:
- `.js-overlay-scroll-wrapper`: 전체 컴포넌트 래퍼
- `.js-overlay-scroll-track`: 스크롤 트랙
- `.js-overlay-scroll-thumb`: 스크롤 썸(핸들)
- `.js-overlay-scroll-box`: 스크롤 박스
- `.js-overlay-scroll-content`: 스크롤 콘텐츠
## 마우스 인터랙션
오버레이 스크롤 컴포넌트는 다음과 같은 마우스 관련 기능을 제공합니다:
1. **스크롤 썸 드래그**: 사용자는 스크롤 썸(thumb)을 클릭한 상태로 드래그하여 스크롤 위치를 조정할 수 있습니다.
2. **스크롤 트랙 클릭**: 사용자가 스크롤 트랙을 클릭하면 클릭한 위치에 따라 페이지 단위로 스크롤됩니다.
## 주의사항
- 컴포넌트가 제대로 작동하려면 부모 요소에 명시적인 높이가 지정되어야 합니다.
- 스크롤 콘텐츠의 높이가 스크롤 박스보다 클 때만 스크롤바가 표시됩니다.
- 스크롤 이벤트는 성능을 위해 `requestAnimationFrame`을 사용하여 최적화되어 있습니다.
## Result
### File: result/index.md
# Result 컴포넌트
Result 컴포넌트는 사용자에게 작업 결과, 상태 또는 피드백을 시각적으로 표시하기 위한 UI 요소입니다. 아이콘, 텍스트 및 색상을 조합하여 다양한 상황에 맞는 결과 화면을 제공합니다.
## 기본 구조
Result 컴포넌트는 다음과 같은 구조로 이루어져 있습니다:
1. 아이콘 영역: 상단에 위치하며 상태를 나타내는 아이콘을 표시
2. 텍스트 영역: 아이콘 아래에 위치하며 캡션, 메인 텍스트, 서브 텍스트를 포함
3. 슬롯: 추가 콘텐츠를 위한 기본 슬롯 제공
## Props
속성
타입
기본값
설명
iconType
IconTypes | 'error-face' | 'dotted-error-face'
undefined
아이콘 타입
color
'gray' | 'blue' | 'green' | 'red' | 'orange' | 'purple' | 'yellow' | 'pink' | ... | 'primary'
'primary'
색상 테마
size
'small' | 'medium' | 'large'
'medium'
크기
caption
string
''
상단 작은 텍스트
title
string
''
주요 텍스트
description
string
''
부가 설명 텍스트
## 크기 변형
```vue
```
## 아이콘 타입
```vue
```
## 색상 테마
```vue
...
```
## 사용 예시
### title만 사용하는 경우
```vue
```
### description만 사용하는 경우
```vue
```
### title + description 사용하는 경우
```vue
```
### icon + title + description 사용하는 경우
```vue
```
### icon + caption + title + description + 슬롯에 버튼 추가한 경우
```vue
```
## K8s Components
### File: jennifer-kubernetes/filter.md
# Filter
> [!CAUTION]
> JenniferKubernetes 프로젝트에서 사용하는 필터 UI입니다.
> 별도의 패키지로 배포되지 않습니다.
## Basic Usage
### Props
| Name | Type | Description |
| ----------------- | ---------------------------------------------------------- | ------------------------------------------------------------------- |
| `title` | `string ` | 필터의 상단 헤더에 위치할 제목입니다. |
| `type (Optional)` | `'text' \| 'portion' ` | 필터의 타입입니다. portion 타입의 경우 바 차트 형식으로 나타냅니다. |
| `filterMap` | `Record ` | 필터의 이름: 개수 쌍을 담고있는 객체입니다. |
| `filterOrder` | `string[] ` | 필터 아이템의 순서를 담고있는 배열입니다. |
| `activeFilterMap` | `Record \| null ` | 체크가 활성화된 필터의 이름: boolean 쌍을 담고있는 객체입니다. |
| `searchText` | `string ` | 필터 내 검색 인풋 UI로 검색한 문자열입니다. |
### Event
| Name | Parameter | Description |
| -------------------------- | --------------------------------- | -------------------------------------------------------- |
| `update:active-filter-map` | `Record \| null` | 체크가 활성화된 필터의 이름: boolean 쌍을 담고있는 객체. |
| `update:search-text` | `string` | 필터 내 검색 인풋 UI로 검색한 문자열. |
```vue
```
### Type: portion
필터 아이템이 바 차트 형식으로 나타납니다.
```vue{21}
```
### Slot: Dropdown
드랍다운을 사용할 수 있는 ` `이 있습니다.
```vue{41-54}
```
## APM Components
### File: j5-components/auto-refresh.md
# AutoRefresh
자동 새로고침 기능을 제공하는 Vue 컴포넌트입니다. 설정된 주기에 따라 자동으로 새로고침을 실행하며, 사용자가 수동으로 제어할 수 있습니다.
## 개요
AutoRefresh 컴포넌트는 실시간 대시보드나 모니터링 화면에서 자동으로 데이터를 새로고침하는 기능을 제공합니다. 사용자가 설정한 주기에 따라 자동으로 새로고침이 실행되며, 일시정지/재생 및 수동 새로고침 기능도 지원합니다.
### 주요 기능
- ⏰ **자동 새로고침**: 설정된 주기에 따라 자동으로 새로고침 실행
- 🎮 **수동 제어**: 일시정지/재생 및 수동 새로고침 버튼 제공
- 📊 **진행률 표시**: 다음 새로고침까지의 진행률을 실시간 시각화
- 🌐 **다국어 지원**: i18n 인젝션을 통한 다국어 지원
- ♿ **접근성**: 키보드 네비게이션 및 스크린 리더 지원
- 🎨 **반응형 애니메이션**: 로딩 상태 및 진행률 애니메이션
### 사용 사례
- 실시간 대시보드의 자동 데이터 갱신
- 모니터링 화면의 주기적 상태 확인
- APM 차트의 실시간 데이터 업데이트
- 서버 상태 모니터링 화면
## Props 인터페이스
```typescript
interface AutoRefreshProps {
/** 자동 새로고침 주기 (초 단위, 최소 1초) */
interval: number;
/** 컴포넌트 비활성화 여부 (기본값: false) */
disabled?: boolean;
/** 컴포넌트 마운트 시 자동으로 새로고침 시작 여부 (기본값: false) */
autoStart?: boolean;
}
```
| 속성 | 타입 | 기본값 | 필수 | 설명 |
| ----------- | --------- | ------- | ---- | ---------------------------------------------- |
| `interval` | `number` | - | ✅ | 자동 새로고침 주기 (초 단위, 최소 1초) |
| `disabled` | `boolean` | `false` | ❌ | 컴포넌트 비활성화 여부 |
| `autoStart` | `boolean` | `false` | ❌ | 컴포넌트 마운트 시 자동으로 새로고침 시작 여부 |
## 이벤트
```typescript
interface AutoRefreshEvents {
/** 자동 새로고침 실행 시 발생하는 이벤트 */
refresh: () => void;
/** 자동 새로고침 활성화/비활성화 토글 시 발생하는 이벤트 */
toggle: (state: AutoRefreshToggleState) => void;
}
interface AutoRefreshToggleState {
isActive: boolean;
interval: number;
}
```
| 이벤트 | 페이로드 | 설명 |
| --------- | ------------------------ | ----------------------------------------------------- |
| `refresh` | - | 자동 새로고침 실행 시 발생하는 이벤트 |
| `toggle` | `AutoRefreshToggleState` | 자동 새로고침 활성화/비활성화 토글 시 발생하는 이벤트 |
## 기본 사용법
```vue
```
## 인터랙티브 데모
Auto Start 테스트
💡 아래 컴포넌트들은 페이지 로드 시 자동으로 새로고침이 시작됩니다.
handleRefresh('Auto Start 5초')"
@toggle="handleToggle"
/>
handleRefresh('Auto Start 8초')"
@toggle="handleToggle"
/>
다양한 주기
handleRefresh('3초')"
@toggle="handleToggle"
/>
handleRefresh('10초')"
@toggle="handleToggle"
/>
handleRefresh('30초')"
@toggle="handleToggle"
/>
💡 자동 새로고침이 활성화되면 컴포넌트 백그라운드에 투명한 바차트가 표시되어
다음 새로고침까지의 진행률을 실시간으로 보여줍니다. 🎨
Event Log
{{ log.time }}
{{ log.message }}
Clear Logs
Status
총 새로고침 횟수: {{ refreshCount }}
마지막 새로고침: {{ lastRefreshTime || '없음' }}
활성 상태: {{ activeCount }}개 활성화
## 데이터 구조
AutoRefresh 컴포넌트에서 사용되는 주요 타입 정의는 다음과 같습니다:
```typescript
// 토글 상태 인터페이스
interface AutoRefreshToggleState {
isActive: boolean; // 현재 활성화 상태
interval: number; // 새로고침 주기 (초)
}
// 다국어 지원 인터페이스
interface I18n {
autoRefresh: string; // "Auto Refresh" 라벨 텍스트
second: string; // "second" 단위 텍스트
}
```
## 고급 사용법
### Auto Start 기능
```vue
```
### 조건부 비활성화
```vue
```
### 다국어 설정
```vue
```
### 외부에서 상태 제어
```vue
```
## 의존성
AutoRefresh 컴포넌트는 다음 외부 의존성을 사용합니다:
- **@vueuse/core**: `useToggle` 컴포저블 사용
- **@jennifersoft/vue-components-v2**: `SvgIcon`, `ICON_TYPE` 컴포넌트 사용
```vue
```
### 필요한 아이콘 타입
- `ICON_TYPE.pause`: 일시정지 아이콘
- `ICON_TYPE.play`: 재생 아이콘
- `ICON_TYPE.loading`: 로딩 아이콘 (자동 회전 애니메이션)
- `ICON_TYPE.refresh`: 새로고침 아이콘
### File: j5-components/global-types.md
# Global Types
`@jennifersoft/apm-core` 라이브러리를 추가하면 아래 타입들이 글로벌로 정의되어, 별도의 Import 없이 사용할 수 있습니다.
## 타입 정의
```typescript
// 국제화 문자열 타입
type I18n = Record;
// 플랫폼 타입
type PlatformType = 'java' | 'net' | 'php' | 'python' | 'opentelemetry';
// 언어 타입
type LanguageType = 'ko' | 'en' | 'ja';
// 테마 타입
type ThemeType = 'classic' | 'dark';
```
## 사용 예제
### I18n 타입 사용
```vue
```
### PlatformType 사용
```vue
```
### LanguageType 사용
```vue
```
### ThemeType 사용
```vue
```
## 타입 확장
필요에 따라 모듈 보강(Module Augmentation)을 통해 추가 글로벌 타입을 정의할 수 있습니다:
```typescript
// types/global.d.ts
declare global {
// 커스텀 글로벌 타입 추가
type CustomMetricType = 'cpu' | 'memory' | 'disk' | 'network';
// 기존 타입 확장
type ExtendedPlatformType = PlatformType | 'nodejs' | 'go';
}
export {};
```
## 주의사항
1. **타입 안전성**: 글로벌 타입을 사용할 때는 타입 안전성을 위해 정확한 값만 사용하세요.
2. **네이밍 충돌**: 다른 라이브러리와의 타입 네이밍 충돌에 주의하세요.
3. **업데이트**: 라이브러리 업데이트 시 타입 정의 변경사항을 확인하세요.
## 관련 문서
- [Vue 3 TypeScript 가이드](https://vuejs.org/guide/typescript/overview.html)
- [TypeScript 글로벌 타입 정의](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-d-ts.html)
### File: j5-components/profile-info.md
# ProfileInfo
트랜잭션에 포함된 프로파일 종류에 대한 표시를 하는 컴포넌트입니다.
## 개요
ProfileInfo 컴포넌트는 트랜잭션 분석 시 각 프로파일 타입(Method, SQL, External Call, Batch Job, Error)의 색상 범례를 제공합니다. 각 프로파일 타입은 고유한 색상으로 구분되어 표시됩니다.
## Props 인터페이스
```typescript
interface Props {
hideBatchJob?: boolean; // Batch Job 항목 숨김 여부 (기본값: false)
hideError?: boolean; // Error 항목 숨김 여부 (기본값: false)
}
```
## 이벤트
- `create-shared-url`: 공유 URL 생성 이벤트 (emit으로 정의되어 있으나 현재 미사용)
## 슬롯
- `tools`: 우측에 추가 도구/버튼을 배치할 수 있는 슬롯
## 기본 사용법
```vue
```
## 인터랙티브 데모
## 고급 사용법
### 특정 프로파일 타입 숨기기
```vue
```
### 커스텀 도구 슬롯 사용
```vue
```
## 프로파일 색상
컴포넌트는 `getProfileColor` 유틸리티 함수를 사용하여 각 프로파일 타입에 고유한 색상을 할당합니다:
- **METHOD**: 메소드 호출
- **SQL**: SQL 쿼리 실행
- **TX_CALL**: 외부 트랜잭션 호출
- **BATCH**: 배치 작업
- **ERROR**: 에러 발생
## 의존성
- `@jennifersoft/vue-components-v2` (Btn 컴포넌트 사용 시)
- Vue 3 Composition API
- Global I18n 타입 정의
### File: j5-components/apm-transaction-table.md
# ApmTransactionTable
## 개요
`ApmTransactionTable`은 APM(Application Performance Monitoring) 환경에서 트랜잭션 데이터를 테이블 형태로 표시하는 컴포넌트입니다. 성능 분석, 오류 추적, 트랜잭션 상세 정보 조회 등의 기능을 제공합니다.
## 주요 기능
- 트랜잭션 데이터의 테이블 뷰 제공
- 정렬, 페이징, 행 선택 기능
- 프로파일 정보 표시
- 도구 슬롯을 통한 확장 가능한 UI
- 트랜잭션 시간 시각화
## Props 인터페이스
```typescript
interface ApmTransactionTableProps<
T extends TransactionData & Record
> extends PagingTableProps {
maxMap: TransactionTime;
}
interface PagingTableProps {
alias: string; // 테이블 식별자
width: number; // 테이블 너비
height: number; // 테이블 높이
displayCount: number; // 페이지당 표시 개수
columns: PagingTableColumn[]; // 컬럼 정의
rows: PagingTableRow[]; // 행 데이터
rowHeight?: number; // 행 높이 (기본값: 56)
sortKey?: string; // 정렬 키
sortOrder?: PagingTableSortOrder; // 정렬 순서
sortLoading?: boolean; // 정렬 로딩 상태
useSkeleton?: boolean; // 스켈레톤 UI 사용 여부
useSelect?: boolean; // 행 선택 기능 사용 여부
foundRowId?: string; // 강조할 행 ID
selectedRowIds?: string[]; // 선택된 행 ID 목록
}
interface TransactionTime {
elapsedTime: number; // 경과 시간 최대값
methodTime: number; // 메서드 시간 최대값
sqlTime: number; // SQL 시간 최대값
txcallTime: number; // 트랜잭션 호출 시간 최대값
batchTime: number; // 배치 시간 최대값
}
```
## 이벤트
```typescript
interface ApmTransactionTableEmits {
(e: 'sort', key: string, order: PagingTableSortOrder): void;
(e: 'select', id: string, row?: PagingTableRow): void;
}
```
- **sort**: 컬럼 정렬 시 발생
- **select**: 행 선택 시 발생
## 슬롯
### tools
테이블 상단의 도구 영역을 커스터마이징할 수 있습니다.
```vue
내보내기
새로고침
```
## 기본 사용법
```vue
```
## 인터랙티브 데모
선택된 행 정보
ID: {{ selectedRowId }}
서비스명: {{ selectedRowData?.data?.serviceName }}
경과시간: {{ selectedRowData?.data?.elapsedTime }}ms
오류코드: {{ selectedRowData?.data?.errCode || '없음' }}
## 데이터 구조
### TransactionData
```typescript
interface TransactionData extends Record {
sid: number; // 시스템 ID
domainName: string; // 도메인명
instId: number; // 인스턴스 ID
instanceName: string; // 인스턴스명
serviceName: string; // 서비스명
serviceHash: number; // 서비스 해시
txid: string; // 트랜잭션 ID
errCode: string; // 오류 코드
elapsedTime: number; // 경과 시간
methodTime: number; // 메서드 시간
sqlTime: number; // SQL 시간
txcallTime: number; // 트랜잭션 호출 시간
batchTime: number; // 배치 시간
startTime: number; // 시작 시간
endTime: number; // 종료 시간
cpuTime: number; // CPU 시간
sqlCount: number; // SQL 개수
httpStatusCode: string; // HTTP 상태 코드
linked: boolean; // 연결 여부
stacked: boolean; // 스택 여부
async: boolean; // 비동기 여부
transactionTypes: TransactionType[]; // 트랜잭션 타입 목록
}
type TransactionType = 'ERROR' | 'LINKED' | 'STACKED' | 'ASYNC';
```
## 고급 사용법
### 커스텀 도구 모음
```vue
CSV 내보내기
설정 초기화
페이지: {{ page }}
```
### 정렬 및 필터링
```vue
```
## 의존성
- `@jennifersoft/apm-components`
- `@jennifersoft/apm-apis`
- `@jennifersoft/vue-components-v2` (도구 버튼 사용 시)
### File: j5-components/ColumnChart.md
# ColumnChart
## 개요
`ColumnChart`는 시계열 데이터를 세로 막대 형태로 시각화하는 범용 차트 컴포넌트입니다.
### 주요 기능
- **가변 길이 데이터 지원**: 임의의 개수의 데이터 포인트를 자동으로 정렬
- **선택적 축 표시**: Y축과 X축을 독립적으로 표시/숨김 가능
- **X축 레이블 회전**: 많은 데이터 포인트가 있을 때 레이블 회전 지원
- **선택 상태 관리**: 개별 컬럼 선택 및 시각적 피드백
- **반응형 레이아웃**: Flex 기반으로 컨테이너 크기에 자동 맞춤
- **이벤트 지원**: 클릭, 마우스 호버 등의 인터랙션 이벤트
### 사용 사례
- 시간별/일별 메트릭 추이 표시
- 서비스별 트랜잭션 개수 비교
- 응답 시간 분포 시각화
- 에러 발생 빈도 모니터링
## Props 인터페이스
### ChartItem 타입
```typescript
interface ChartItem {
name: string; // 레이블 텍스트
value: number; // 차트에 표시될 값
time?: number; // 선택적 타임스탬프
}
```
### Props
```typescript
interface Props {
// 필수
data: ChartItem[];
// 선택적 - 축
showYAxis?: boolean; // Y축 표시 여부 (기본값: false)
showXAxis?: boolean; // X축 표시 여부 (기본값: false)
rotateXLabels?: boolean; // X축 레이블 45도 회전 (기본값: false)
hideYLabelWhenZero?: boolean; // maxCount가 0일 때 Y축 레이블 숨김 (기본값: false)
// 선택적 - 크기 (px 단위, width의 -1은 100% 가변)
width?: number; // 차트 너비 (기본값: -1, 즉 100%)
height?: number; // 차트 높이 (기본값: 200)
// 선택적 - 스타일 (px 단위)
gap?: number; // 컬럼 간격 (기본값: 4)
padding?: number; // 차트 내부 패딩 (기본값: 8)
borderRadius?: number; // 컬럼 모서리 둥글기 (기본값: 4)
// 선택적 - 축 스타일 (px 단위)
yAxisWidth?: number; // Y축 너비 (기본값: 40)
yAxisPaddingRight?: number; // Y축 오른쪽 패딩 (기본값: 8)
yAxisFontSize?: number; // Y축 폰트 크기 (기본값: 11)
yAxisLabelCount?: number; // Y축 레이블 개수 (기본값: 3)
xAxisHeight?: number; // X축 높이 (기본값: 20)
xAxisHeightRotated?: number; // X축 높이 (회전 시) (기본값: 40)
xAxisPaddingTop?: number; // X축 상단 패딩 (기본값: 4)
xAxisFontSize?: number; // X축 폰트 크기 (기본값: 11)
// 선택적 - 선택 상태
// -2: 아무것도 선택 안 함, -1: 전체 선택, >= 0: 특정 컬럼 선택
selectedIndex?: number; // 선택된 인덱스 (기본값: -1)
}
```
## 이벤트
```typescript
// 컬럼 클릭 시 발생 (value가 0인 컬럼은 클릭 불가)
emit('select', item: ChartItem, index: number)
// 컬럼에 마우스 호버 시 발생
emit('mouseenter', item: ChartItem, e: MouseEvent)
// 컬럼에서 마우스가 벗어날 때 발생
emit('mouseleave')
```
## 기본 사용법
간단한 컬럼 차트를 생성하는 기본 예제입니다:
```vue
```
## 인터랙티브 데모
Last Event: {{ eventLog }}
## 데이터 구조
`ColumnChart`는 `ChartItem[]` 타입의 데이터를 받습니다:
```typescript
interface ChartItem {
name: string; // X축에 표시될 레이블
value: number; // 차트에 표시될 숫자 값
time?: number; // 선택적 타임스탬프 (milliseconds)
}
```
### 샘플 데이터
```typescript
const sampleData: ChartItem[] = [
{ name: '00:00', value: 120, time: 1609459200000 },
{ name: '01:00', value: 250, time: 1609462800000 },
{ name: '02:00', value: 180, time: 1609466400000 },
{ name: '03:00', value: 420, time: 1609470000000 },
{ name: '04:00', value: 310, time: 1609473600000 },
{ name: '05:00', value: 190, time: 1609477200000 },
];
```
## 고급 사용법
### 1. 미니 차트 (축 없음)
시각적 표시기로 사용하기 위한 최소한의 차트:
```vue
```
### 2. 선택 상태 관리
사용자 선택을 추적하고 시각적으로 표시:
```vue
```
### 3. Y축 레이블 개수 조정
더 세밀한 Y축 스케일 표시:
```vue
```
### 4. 반응형 차트
컨테이너 너비에 자동으로 맞춤:
```vue
```
### 5. X축 레이블 회전 (많은 데이터)
48개 이상의 데이터 포인트가 있을 때:
```vue
```
### 6. 커스텀 스타일링
차트 외관 조정:
```vue
```
## 선택 상태 값 (selectedIndex)
- `-2`: 아무것도 선택 안 함 (모든 컬럼이 연한 색상)
- `-1`: 전체 선택 (모든 컬럼이 기본 색상) - **기본값**
- `>= 0`: 특정 인덱스의 컬럼만 선택 (선택된 컬럼은 진한 색상, 나머지는 연한 색상)
## 주의사항
1. **데이터 개수**: 너무 많은 데이터(100개 이상)는 성능에 영향을 줄 수 있습니다
2. **레이블 길이**: X축 레이블이 너무 길면 `rotateXLabels`를 사용하세요
3. **0값 클릭**: `value`가 0인 컬럼은 클릭이 불가능합니다
4. **최소 높이**: 의미 있는 시각화를 위해 최소 60px 이상의 높이를 권장합니다
5. **Y축 레이블**: `hideYLabelWhenZero`는 모든 값이 0일 때 Y축 레이블을 공백으로 표시합니다
## 의존성
- **Vue 3**: Composition API (`ref`, `computed`)
- **@jennifersoft/apm-components**: ChartItem 타입
- **CSS Variables**: 테마 색상 (`--gray-*`, `--blue-*`, `--overlay-*`)
### File: j5-components/daily-and-hourly-chart.md
# DailyAndHourlyChart
## 개요
`DailyAndHourlyChart`는 서비스 메트릭 데이터를 일간 및 시간별로 시각화하는 차트 컴포넌트입니다. 메트릭 선택, 탭 전환, 데이터 선택 등의 인터랙티브 기능을 제공하여 시계열 데이터 분석을 지원합니다.
## 주요 기능
- 일간/시간별 메트릭 데이터 시각화
- 메트릭 타입 선택 (서비스 개수, 응답시간 등)
- 차트 타입 전환 (Bar, Column)
- 날짜 및 시간 선택 기능
- v-model을 통한 양방향 데이터 바인딩
- 커스텀 툴팁 포맷터 지원
## Props 인터페이스
```typescript
interface DailyAndHourlyChartProps {
width: number; // 차트 너비
height: number; // 차트 높이
tabItems: TabItem[]; // 차트 타입 탭 항목
metricItems: MetricItem[]; // 메트릭 선택 항목
items: ChartItem[]; // 차트 데이터
hourlyItemMap: Record; // 시간별 데이터 맵
nameWidth?: number; // 이름 영역 너비 (기본값: 32)
tooltipFormatter?: (item: ChartItem, type: ChartType) => string; // 툴팁 포맷터
}
interface TabItem {
label: string; // 탭 표시 텍스트
value: ChartType; // 차트 타입 값
}
interface MetricItem {
label: string; // 메트릭 표시 텍스트
value: string; // 메트릭 값 (형식: "daily:MxDef" 또는 "hourly:MxDef")
}
interface ChartItem {
time: number; // 시간 (timestamp)
name: string; // 표시명
value: number; // 값
}
type ChartType = 'bar' | 'column';
```
## v-model Props
```typescript
// 양방향 바인딩 지원 props
selectedMetric: string; // 선택된 메트릭 (기본값: "daily:service_count")
selectedDate: number; // 선택된 날짜 (기본값: -1)
selectedHour: number; // 선택된 시간 (기본값: -1)
selectedTab: ChartType; // 선택된 차트 타입 (기본값: "bar")
```
## 이벤트
```typescript
interface DailyAndHourlyChartEmits {
(e: 'tab', item: ChartType): void;
(e: 'select', time: number, hour: number, duplicate: boolean): void;
(e: 'metric', metric: MxDef, interval: number): void;
(e: 'update:selectedMetric', selectedMetric: string): void;
(e: 'update:selectedDate', selectedDate: number): void;
(e: 'update:selectedHour', selectedHour: number): void;
(e: 'update:selectedTab', selectedTab: ChartType): void;
}
```
- **tab**: 차트 타입 탭 변경 시 발생
- **select**: 차트 데이터 선택 시 발생
- **metric**: 메트릭 변경 시 발생
- **update:\*** : v-model 업데이트 이벤트
## 기본 사용법
```vue
```
## 샘플 코드 예제
```vue
```
## 인터랙티브 데모
현재 상태
선택된 메트릭:
{{ selectedMetric }}
선택된 날짜:
{{ selectedDate >= 0 ? new Date(selectedDate).toLocaleDateString() : '없음' }}
선택된 시간:
{{ selectedHour >= 0 ? `${selectedHour}시` : '없음' }}
차트 타입:
{{ selectedTab }}
{{ event.time }}
{{ event.type }}
{{ event.message }}
## 데이터 구조
### ChartItem
```typescript
interface ChartItem {
time: number; // 시간 (Unix timestamp)
name: string; // 표시명 (예: "01/01", "14:00")
value: number; // 메트릭 값
}
```
### MetricItem & TabItem
```typescript
interface MetricItem {
label: string; // 사용자에게 표시될 텍스트
value: string; // 메트릭 식별자 (형식: "daily:MxDef" 또는 "hourly:MxDef")
}
interface TabItem {
label: string; // 탭 텍스트
value: ChartType; // 차트 타입 ('bar' | 'column')
}
```
## 고급 사용법
### 커스텀 툴팁 포맷터
```vue
```
### 동적 데이터 로딩
```vue
```
### 반응형 차트 크기
```vue
```
## 의존성
- `@jennifersoft/apm-components`
- `@jennifersoft/apm-apis`
- `@jennifersoft/vue-components-v2`
- `@vueuse/core` (유틸리티 함수 사용 시)
### File: j5-components/relation-tree.md
# RelationTree
MSA 분석을 위한 연관된 트랜잭션들을 트리 구조로 시각화하는 컴포넌트입니다.
## 개요
RelationTree는 트랜잭션 간의 관계를 계층적 트리 구조로 표현하며, 각 노드는 트랜잭션 또는 애플리케이션을 나타냅니다. 사용자는 드래그, 줌, 노드 선택 등의 인터랙션을 통해 복잡한 MSA 구조를 효과적으로 분석할 수 있습니다.
## Props 인터페이스
```typescript
interface Props {
width: number; // 컴포넌트 전체 너비
height: number; // 컴포넌트 전체 높이
screenWidth: number; // 뷰포트 너비
screenHeight: number; // 뷰포트 높이
children: RelationTreeData[]; // 트리 데이터
globalScale?: number; // 전역 스케일 (기본값: 1)
selectedId?: string; // 선택된 노드 ID
focusedId?: string; // 포커스된 노드 ID
useResizer?: boolean; // 리사이저 사용 여부 (기본값: false)
useKeyboard?: boolean; // 키보드 사용 여부 (기본값: false)
useSimpleTooltip?: boolean; // 간단한 툴팁 사용 여부 (기본값: false)
showScaleControls?: boolean; // 스케일 컨트롤 표시 여부 (기본값: true)
layout?: RelationTreeLayout; // 레이아웃 방향 ('horizontal' | 'vertical', 기본값: 'horizontal')
}
interface RelationTreeData extends ApiRelationData {
rootId?: string;
type: 'TRANSACTION' | 'APPLICATION';
id: string;
name: string;
children?: RelationTreeData[];
startTime: number;
relation: ApiTransactionRelationData | ApiApplicationRelationData;
}
```
## 이벤트
- `select`: 노드 선택 시 발생 - `(nodeId: string) => void`
- `focus`: 노드 포커스 시 발생 - `(nodeId: string) => void`
## 기본 사용법
```vue
```
## 인터랙티브 데모
## 주요 기능
### 1. 스케일 컨트롤
- **마우스 휠**: 확대/축소
- **스케일 컨트롤러**: 우상단 버튼으로 정밀 조정
- **globalScale prop**: 초기 스케일 설정
### 2. 드래그 앤 팬
- **마우스 드래그**: 뷰포트 이동
- **자동 센터링**: 루트 노드 기준 자동 정렬
### 3. 노드 인터랙션
- **호버**: 노드 정보 툴팁 표시
- **클릭**: 노드 선택 (select 이벤트 발생)
- **포커스**: 키보드 네비게이션 지원
### 4. 툴팁 모드
- **기본 툴팁**: 상세한 메트릭 정보 표시
- **간단한 툴팁**: 핵심 정보만 표시
## 고급 사용법
### 키보드 네비게이션 활성화
```vue
```
### 특정 노드 미리 선택
```vue
```
### 커스텀 크기 설정
```vue
```
## 데이터 구조
관계 트리 데이터는 다음과 같은 구조를 가져야 합니다:
```typescript
interface RelationTreeData {
type: 'TRANSACTION' | 'APPLICATION';
id: string;
name: string;
startTime: number;
children?: RelationTreeData[];
relation: {
domainId: number;
domainName: string;
instId: number;
instanceName: string;
elapsedTime: number;
sqlTime: number;
externalCallTime: number;
methodTime: number;
errorTypeOrZero: number;
stacked: boolean;
async: boolean;
};
}
```
## 성능 최적화
1. **대용량 데이터**: 가상화를 통한 렌더링 최적화
2. **스로틀링**: 드래그/줌 이벤트 스로틀링 적용
3. **메모리 관리**: 컴포넌트 언마운트 시 리소스 정리
## 의존성
- Vue 3 Composition API
- D3.js (hierarchy, tree, shape)
- `@vueuse/core` (throttle, timeout 유틸리티)
- `@jennifersoft/apm-apis` (타입 정의)
### File: j5-components/relation-chart.md
# RelationChart
## 개요
`RelationChart`는 마이크로서비스 아키텍처에서 서비스 간의 관계와 성능 메트릭을 시각화하는 차트 컴포넌트입니다. `RelationTree`와 달리 차트 형태로 데이터를 표시하며, 응답 시간 또는 시작 시간별로 정렬 기능을 제공합니다.
### 주요 기능
- 서비스 관계를 막대 차트 형태로 시각화
- 응답 시간(response time) 또는 시작 시간(start time) 기준 정렬
- 노드 선택 및 포커스 기능
- 에러 상태 표시
- 툴팁을 통한 상세 정보 표시
- RelationTree와의 선택 동기화 지원
### RelationTree와의 차이점
- **RelationTree**: 트리 구조로 계층적 관계를 시각화
- **RelationChart**: 차트 형태로 성능 메트릭 중심 시각화
## Props 인터페이스
```typescript
interface RelationChartProps {
// 필수 Props
children: RelationTreeData[]; // 관계 데이터 트리
width: number; // 차트 너비
height: number; // 차트 높이
// 선택적 Props
focusedId?: string; // 포커스된 노드 ID
selectedId?: string; // 선택된 노드 ID
useSort?: boolean; // 정렬 기능 사용 여부 (기본값: true)
hideSort?: boolean; // 정렬 헤더 숨김 여부 (기본값: false)
sortType?: string; // 정렬 타입 ('response' | 'start')
selectedNode?: RelationTreeData; // 선택된 노드 데이터
}
```
## 이벤트
### @select
노드가 선택되었을 때 발생합니다.
```typescript
(node: RelationTreeData) => void
```
### @focus
노드에 포커스가 설정되었을 때 발생합니다.
```typescript
(node: RelationTreeData | undefined) => void
```
### @node-click
노드가 클릭되었을 때 발생합니다. 일반적으로 xviewAnalysisV2 화면으로 이동할 때 사용됩니다.
```typescript
(node: RelationTreeData) => void
```
## 기본 사용법
```vue
```
## 인터랙티브 데모
## 데이터 구조
### RelationTreeData 인터페이스
```typescript
interface RelationTreeData extends ApiRelationData {
rootId?: string;
}
interface ApiRelationData {
type:
| 'APPLICATION'
| 'TRANSACTION'
| 'INDIVIDUAL_DB'
| 'INDIVIDUAL_EXTERNAL_CALL';
id: string;
name: string;
startTime: number;
relation: ApiTransactionRelationData | ApiApplicationRelationData;
children: ApiRelationData[];
}
interface ApiApplicationRelationData {
hitSum: number;
elapsedTimeAverage: number;
sqlTimeAverage: number;
externalCallTimeAverage: number;
elapsedTimeStandardDeviation: number;
errorCount: number;
transactionIdByDomain?: Record;
transactionSearchRange?: {
startTime: number;
endTime: number;
};
}
```
## 고급 사용법
### 정렬 기능 커스터마이징
```vue
```
### RelationTree와 선택 동기화
```vue
```
## 스타일링
컴포넌트는 CSS 변수를 통해 커스터마이징할 수 있습니다:
```css
:root {
--relation-chart-background: white;
--relation-chart-border-color: #e5e7eb;
--relation-chart-hover-color: #f3f4f6;
--relation-chart-selected-color: #dbeafe;
--relation-chart-error-color: #fca5a5;
}
```
## 접근성
- 키보드 내비게이션 지원 (화살표 키로 노드 선택)
- ARIA 레이블 제공
- 포커스 상태 시각적 표시
## 성능 고려사항
- 대량의 노드를 렌더링할 때는 가상 스크롤링이 자동으로 적용됩니다
- 500개 이상의 노드를 표시할 경우 성능 저하가 발생할 수 있습니다
- 필요한 경우 데이터를 페이지네이션하거나 필터링하는 것을 권장합니다
## 의존성
- Vue 3.0+
- @jennifersoft/vue-components-v2
- @jennifersoft/apm-apis
- d3-scale (차트 스케일링)
- @vueuse/core (리사이즈 감지)
### File: j5-components/paging-table.md
# PagingTable
성능 데이터 표현을 위한 테이블 컴포넌트입니다.
## Enums
```ts
export enum PagingTableCellType {
TEXT,
TEXT_WITH_TOOLTIP,
VALUE,
DATE,
TIME,
ERROR,
BAR,
CUSTOM,
}
export enum PagingTableSortOrder {
NONE,
ASC,
DESC,
}
```
## Types
```ts
import { PagingTableCellType, PagingTableSortOrder } from './enums';
export interface PagingTableProps> {
alias: string;
width: number;
height: number;
displayCount: number;
columns: PagingTableColumn[];
rows: PagingTableRow[];
rowHeight?: number;
rowId?: string;
maxMap?: Record;
sortKey?: string;
sortOrder?: PagingTableSortOrder;
sortLoading?: boolean;
}
export interface PagingRowProps> {
row: PagingTableRow;
columns: PagingTableColumn[];
cellWidths: number[];
scrollBarWidth: number;
maxMap?: Record;
}
export interface PagingTableColumn {
key: string;
name: string;
rate: number;
sortable: boolean;
visible: boolean;
type: PagingTableCellType;
color?: string;
}
export interface PagingTableRow {
data: T;
id?: string;
}
// PaingTable.vue
interface SimpleTableData extends Record {
name: string;
age: number;
city: string;
status: string;
}
const emit = defineEmits(['sort', 'select']);
const props = defineProps>();
```
## Sample Code
```vue
```
## Demo
### File: j5-components/tree-selector.md
# TreeSelector
성능을 고려하여 가상 스크롤이 적용된 다목적 트리 컴포넌트입니다.
## 개요
TreeSelector는 계층적 데이터를 트리 구조로 표시하며, 단일 선택과 다중 선택 모드를 지원합니다. 가상 스크롤링을 통해 대용량 데이터도 효율적으로 처리할 수 있습니다.
## Props 인터페이스
```typescript
interface Props {
tree: TreeNode[]; // 트리 데이터
multiSelect?: boolean; // 다중 선택 모드 (기본값: false)
leafIconForMultiSelect?: IconTypes; // 다중 선택 시 체크박스 표시할 아이콘 타입
width?: number; // 컴포넌트 너비 (기본값: 0 - 자동)
height?: number; // 컴포넌트 높이 (기본값: 300)
checkedKeys?: string[]; // 체크된 노드 키 목록 (기본값: [])
}
interface TreeNode {
key: string; // 고유 키
label: string; // 표시 텍스트
children: TreeNode[]; // 자식 노드들
fold?: boolean; // 접힘 상태 (기본값: false)
check?: boolean; // 체크 상태 (기본값: false)
disable?: boolean; // 비활성화 상태 (기본값: false)
icon?: IconTypes; // 노드 아이콘
data?: T; // 사용자 데이터
}
```
## 이벤트
- `fold`: 노드 접힘/펼침 시 발생 - `(nodes: TreeNode[]) => void`
- `change`: 노드 선택 변경 시 발생 - `(nodes: TreeNode[]) => void`
## 기본 사용법
```vue
```
## 인터랙티브 데모
TreeSelector
Selected Nodes
{{ node.label }} ({{ node.key }})
## 사용 시나리오
### 1. 단일 선택 모드 (Single Selection)
단일 노드만 선택할 수 있는 기본 모드입니다.
```vue
```
### 2. 다중 선택 모드 (Multi Selection)
여러 노드를 동시에 선택할 수 있습니다.
```vue
```
### 3. 제한된 다중 선택 (Leaf-only Multi Selection)
특정 아이콘을 가진 노드(주로 리프 노드)만 체크박스를 표시합니다.
```vue
```
### 4. 미리 체크된 상태로 시작
```vue
```
## 고급 기능
### 가상 스크롤링
대용량 트리 데이터의 성능을 위해 가상 스크롤링이 자동으로 적용됩니다.
```vue
```
### 커스텀 아이콘 사용
각 노드에 다양한 아이콘을 설정할 수 있습니다.
```vue
```
### 노드 상태 관리
```vue
```
## 데이터 구조 예제
### 도메인/인스턴스 트리
```typescript
interface DomainData {
domainId: number;
instanceId: number;
}
const domainTree: TreeNode[] = [
{
key: 'domain-1000',
label: 'Production',
icon: ICON_TYPE.domainGroup,
data: { domainId: 1000, instanceId: 0 },
children: [
{
key: 'instance-1001',
label: 'web-server-01',
icon: ICON_TYPE.domain,
data: { domainId: 1000, instanceId: 1001 },
children: [],
},
],
},
];
```
## 성능 최적화
1. **가상 스크롤링**: 대용량 데이터 처리
2. **지연 로딩**: 필요한 노드만 렌더링
3. **메모리 효율성**: 불필요한 DOM 노드 최소화
## 접근성 (Accessibility)
- 키보드 네비게이션 지원
- 스크린 리더 호환성
- ARIA 속성 자동 적용
## 의존성
- Vue 3 Composition API
- `@jennifersoft/vue-components-v2` (아이콘)
- Virtual Scrolling 라이브러리 (내장)
### File: j5-components/navigation-bar.md
# NavigationBar
좌측 수직 네비게이션 사이드바 컴포넌트
## 개요
NavigationBar는 APM 애플리케이션의 메인 네비게이션 인터페이스를 제공하는 좌측 수직 사이드바 컴포넌트입니다. 메뉴 클릭 시 슬라이드 패널이 열리며, 대시보드, 분석, 통계 등의 주요 기능에 접근할 수 있습니다.
### 주요 기능
- 📱 **수직 사이드바**: 72px 고정 너비의 좌측 네비게이션 바
- 🎯 **슬라이드 패널**: 메뉴 클릭 시 256px (기본값) 너비의 패널이 슬라이드로 열림
- 🔄 **토글 동작**: 같은 메뉴 재클릭 시 패널 닫기, 다른 메뉴 클릭 시 패널 전환
- 🌐 **Teleport 지원**: Portal을 통한 유연한 DOM 배치
- 🏷️ **배지 표시**: 알림 개수 등을 표시하는 배지 지원
- 🎨 **커스터마이징**: 로고, 메뉴 아이템, 패널 콘텐츠 완전 커스터마이징
- 🔌 **독립 패널**: 일반 패널과 별도로 작동하는 커스텀 패널 지원
- ♿ **접근성**: 외부 클릭 감지, 키보드 네비게이션
## Props
### NavigationBar Props
| 속성 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| `headMenuItems` | `MenuItem[]` | `[]` | 상단 메뉴 아이템 목록 |
| `tailMenuItems` | `MenuItem[]` | `[]` | 하단 메뉴 아이템 목록 |
| `logoSrc` | `string` | - | 로고 이미지 소스 (없으면 #logo 슬롯 사용) |
| `logoHref` | `string` | `'/'` | 로고 클릭 시 이동할 URL |
| `selectedPanel` | `string \| null` | `null` | 현재 선택된 패널 키 (v-model) |
| `panelWidth` | `number` | `256` | 패널 너비(px) - 일반 패널과 커스텀 패널 모두에 적용 |
| `teleportTo` | `string \| null` | `'body'` | Teleport 대상 선택자 |
| `enableCustomPanel` | `boolean` | `false` | 커스텀 패널 활성화 여부 |
| `customPanelKey` | `string` | `'custom'` | 커스텀 패널 식별 키 |
| `class` | `string` | - | 추가 CSS 클래스 |
### MenuItem Interface
```typescript
interface MenuItem {
/** 메뉴 식별자 */
key: string;
/** 아이콘 (ICON_TYPE) */
icon: IconTypes;
/** 표시 이름 */
displayName: string;
/** 메뉴 타입 */
type: 'panel' | 'event'; // panel: 패널 열림, event: 이벤트만 발생
/** 선택 상태 */
selected?: boolean;
/** 눌림 상태 (패널이 열려있을 때 시각적 피드백) */
pressed?: boolean;
/** 비활성화 상태 */
disabled?: boolean;
/** 배지 (알림 개수 등) */
badge?: number | string;
/** 툴팁 텍스트 */
tooltip?: string;
}
```
### SubMenuItem Interface
```typescript
interface SubMenuItem {
/** 메뉴 식별자 */
key: string;
/** 아이콘 (thumbnail이 있으면 선택사항) */
icon?: IconTypes;
/** 표시 이름 */
displayName: string;
/** 선택 상태 */
selected?: boolean;
/** 눌림 상태 (클릭 시 임시 시각적 피드백) */
pressed?: boolean;
/** 비활성화 상태 */
disabled?: boolean;
/** 검색 하이라이트 인덱스 */
indices?: number[];
/** 썸네일 이미지 경로 (아이콘 대신 사용) */
thumbnail?: string;
/** 툴팁 텍스트 */
tooltip?: string;
}
```
## Events
| 이벤트 | 파라미터 | 설명 |
|--------|----------|------|
| `menu-click` | `item: MenuItem` | 메뉴 클릭 시 발생 |
| `panel-open` | `panelKey: string, item?: MenuItem` | 패널 열림 시 발생 |
| `panel-close` | `panelKey: string, item?: MenuItem` | 패널 닫힘 시 발생 |
| `logo-click` | - | 로고 클릭 시 발생 |
| `update:selectedPanel` | `value: string \| null` | v-model 업데이트 |
## Slots
### #logo
로고 영역 슬롯. `logoSrc` prop이 없을 때 사용됩니다.
```vue
MY APP
```
### #panel-{key}
각 패널의 전체 콘텐츠를 정의하는 슬롯. `{key}`는 `MenuItem.key` 값입니다.
```vue
```
### #custom-panel
독립적인 커스텀 패널 슬롯. `enableCustomPanel`이 true일 때 표시됩니다.
```vue
```
## TypeScript 타입
```typescript
import type {
MenuItem,
SubMenuItem,
NavigationBarProps,
NavigationBarEmits
} from '@jennifersoft/apm-components';
```
## 관련 컴포넌트
NavigationBar와 함께 사용되는 주요 컴포넌트들입니다.
### NavHeader
패널 상단에 표시되는 헤더 컴포넌트입니다.
#### Props
| 속성 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| `title` | `string` | - | 헤더 타이틀 텍스트 |
| `tailIcon` | `IconTypes` | - | 우측 커스텀 아이콘 (closeable이 false일 때) |
| `closeable` | `boolean` | `false` | 닫기 아이콘 표시 및 close 이벤트 발생 여부 |
| `clickable` | `boolean` | `false` | 헤더 클릭 가능 여부 |
#### Events
| 이벤트 | 파라미터 | 설명 |
|--------|----------|------|
| `click` | `event: MouseEvent` | 헤더 클릭 시 발생 (clickable이 true일 때) |
| `close` | - | 닫기 아이콘 클릭 시 발생 (closeable이 true일 때) |
#### 사용 예시
```vue
```
### SubNavItem
패널 내부의 서브메뉴 아이템 컴포넌트입니다.
#### Props
| 속성 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| `icon` | `IconTypes` | - | 아이콘 (thumbnail이 없을 때 필수) |
| `name` | `string` | - | 표시 이름 |
| `selected` | `boolean` | `false` | 선택 상태 (보라색 하이라이트) |
| `pressed` | `boolean` | `false` | 눌림 상태 (회색 오버레이) |
| `disabled` | `boolean` | `false` | 비활성화 상태 |
| `indices` | `number[]` | - | 검색어 하이라이트 문자 인덱스 배열 |
| `thumbnail` | `string` | - | 썸네일 이미지 URL (67×48px, 아이콘 대신 표시) |
| `tooltip` | `string` | - | 툴팁 텍스트 |
#### Events
| 이벤트 | 파라미터 | 설명 |
|--------|----------|------|
| `click` | `event: MouseEvent` | 아이템 클릭 시 발생 |
#### 사용 예시
```vue
```
### SubHeader
패널 내부의 섹션 구분 헤더입니다.
#### Props
| 속성 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| `title` | `string` | - | 섹션 타이틀 |
#### 사용 예시
```vue
```
## 기본 사용법
```vue
```
## 인터랙티브 데모
NavigationBar 데모
좌측 메뉴를 클릭하여 패널을 열고 닫아보세요.
선택된 패널: {{ selectedPanel || '없음' }}
## 주요 기능 상세
### 메뉴 타입 동작
MenuItem의 `type` 속성으로 메뉴 클릭 시 동작을 제어합니다.
- **`type: 'panel'`**: 메뉴 클릭 시 연결된 패널이 열리거나 닫힙니다
- **`type: 'event'`**: 패널을 열지 않고 `menu-click` 이벤트만 발생시킵니다
```vue
```
### 스크롤 위치 유지
NavigationBar는 패널별 스크롤 위치를 자동으로 저장하고 복원합니다.
**동작 방식:**
- 각 패널의 스크롤 위치가 Map에 저장됩니다
- 다른 패널로 전환 시 현재 스크롤 위치가 저장됩니다
- 이전에 열었던 패널로 돌아가면 스크롤 위치가 복원됩니다
- 성능을 위해 throttle(200ms) 적용된 스크롤 핸들러 사용
- 일반 패널과 커스텀 패널의 스크롤 위치가 독립적으로 관리됩니다
```vue
```
### 패널 너비 설정
`panelWidth` prop은 **일반 패널과 커스텀 패널 모두**에 적용됩니다.
```vue
```
**참고:** 각 패널마다 다른 너비가 필요한 경우, CSS로 개별 패널 콘텐츠의 너비를 조정하세요.
### 커스텀 패널 동작
커스텀 패널은 일반 패널과 독립적으로 작동하는 특수 패널입니다.
**특징:**
- `enableCustomPanel` prop으로 표시/숨김 제어
- 메뉴 선택과 무관하게 독립적으로 표시 가능
- 일반 패널이 열리면 자동으로 닫힙니다
- 외부 클릭 시 자동으로 닫힙니다
- 별도의 스크롤 위치 저장
```vue
도움말 보기
```
### Z-Index 레이어 구조
NavigationBar와 패널들의 z-index 구조를 이해하면 레이아웃 문제를 방지할 수 있습니다.
```
Navigation Bar: z-index 20 (최상단)
├─ General Panel: z-index 10 (중간)
└─ Custom Panel: z-index 9 (하단)
```
**주의사항:**
- 일반 패널이 열린 상태에서 커스텀 패널을 열면, 일반 패널이 위에 표시됩니다
- 다른 UI 요소와 z-index 충돌을 피하려면 이 구조를 고려하세요
- Teleport를 사용하므로 부모 컨테이너의 z-index는 영향을 주지 않습니다
## 고급 사용법
### 1. 배지 표시
알림 개수 등을 배지로 표시할 수 있습니다.
```vue
```
### 2. 이벤트 타입 메뉴
패널을 열지 않고 이벤트만 발생시키는 메뉴입니다.
```vue
```
### 3. 서브메뉴 with 썸네일
서브메뉴 아이템에 썸네일 이미지를 표시할 수 있습니다.
```vue
```
### 4. 커스텀 패널
일반 패널과 독립적으로 작동하는 커스텀 패널을 사용할 수 있습니다.
```vue
도움말 열기
```
### 5. 동적 패널 너비
패널 너비를 동적으로 조정할 수 있습니다.
```vue
```
## 의존성
### 내부 컴포넌트
- **NavHeader**: 패널 헤더 컴포넌트
- **SubNavItem**: 서브메뉴 아이템 컴포넌트
- **SubHeader**: 서브메뉴 섹션 헤더
- **Divider**: 구분선 컴포넌트
- **WrappedNavItem**: 메뉴 아이템 래퍼
### 외부 의존성
- `@vueuse/components`: vOnClickOutside 디렉티브
- `@jennifersoft/vue-components-v2`: ICON_TYPE
## 스타일링
### 기본 구조
- **네비게이션 바**: 72px 고정 너비, 좌측 고정
- **패널**: 기본 256px 너비, 슬라이드 애니메이션
- **z-index**: 네비게이션 바(20), 일반 패널(10), 커스텀 패널(9)
### CSS 클래스
```scss
.navigation-bar {
width: 72px;
height: 100vh;
position: fixed;
left: 0;
top: 0;
}
.navigation-panel {
position: fixed;
left: 72px;
top: 0;
height: 100vh;
background: white;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
}
```
## 주의사항
1. **Teleport 사용**: 기본적으로 `body`에 Teleport되므로 전역 스타일 충돌에 주의하세요.
2. **패널 외부 클릭**: 패널은 외부 클릭 시 자동으로 닫힙니다.
3. **z-index 관리**: 커스텀 패널과 일반 패널은 별도의 z-index를 가집니다.
4. **v-model 사용**: `selectedPanel`은 v-model로 양방향 바인딩됩니다.
5. **슬롯 네이밍**: 패널 슬롯은 `#panel-{key}` 형식으로 명명해야 합니다.
## 브라우저 지원
- Chrome (최신 2개 버전)
- Firefox (최신 2개 버전)
- Safari (최신 2개 버전)
- Edge (최신 2개 버전)
### File: j5-components/topology-chart.md
# TopologyChart
MSA (Microservices Architecture) 분석을 위한 Force 기반 노드-링크 다이어그램 컴포넌트입니다.
## 개요
TopologyChart는 마이크로서비스 간의 관계와 호출 패턴을 자유로운 형태의 네트워크 그래프로 시각화합니다. Force 시뮬레이션을 통해 자연스러운 노드 배치가 가능하며, 사용자가 직접 노드를 드래그하여 레이아웃을 조정할 수 있습니다.
## 주요 특징
- **인터랙티브**: 노드 드래그, 확대/축소, 팬 기능 지원
- **Force 시뮬레이션**: 물리 기반 시뮬레이션으로 자연스러운 노드 배치
- **자동 스케일**: 데이터에 맞는 자동 스케일 조정
- **노드 필터링**: 고립된 노드 숨기기 기능
- **시각적 피드백**: 호버/클릭 시 연결된 노드/엣지 하이라이팅
- **실시간 편집**: 드래그로 노드 위치 조정 가능
## Props Interface
```typescript
interface TopologyChartProps {
/** 토폴로지 데이터 */
data?: TopologyData;
/** 차트 너비 */
width?: number;
/** 차트 높이 */
height?: number;
/** Force 시뮬레이션 사용 여부 */
enableForceSimulation?: boolean;
/** 웹 워커 객체 (undefined: 자동생성, Worker: 직접제공) */
worker?: Worker;
/** 노드 스케일 컨트롤 표시 여부 */
showScaleControls?: boolean;
/** 자동 스케일 조정 활성화 여부 */
enableAutoScale?: boolean;
/** 노드 라벨 숨김 여부 */
hideNodeLabels?: boolean;
/** 실시간 모드 활성화 여부 */
realtimeMode?: boolean;
/** 현재 선택된 엣지 - 상세 정보 표시용 */
selectedEdge?: TopologyEdge;
/** 엣지 상세 데이터 - API 호출 후 가져온 데이터 */
edgeDetailData?: EdgeDetailData;
/** 현재 선택된 노드 - 상세 정보 표시용 */
selectedNode?: TopologyNode;
/** 노드 상세 데이터 - API 호출 후 가져온 데이터 */
nodeDetailData?: NodeDetailData;
/** 활성화할 클러스터 ID 배열 */
activeClusterIds?: string[];
/** 애니메이션 효과를 적용할 클러스터 ID */
animatedClusterId?: string;
/** 노드 툴팁 버튼 표시 여부 */
showNodeTooltipButton?: boolean;
/** 엣지 툴팁 버튼 표시 여부 */
showEdgeTooltipButton?: boolean;
/** 툴팁 오프셋 */
tooltipOffset?: number;
/**
* localStorage 저장 키 - autoSave와 함께 사용시 globalScale, viewport, nodePositions를 localStorage에 저장
* 조건: storageKey && autoSave가 모두 true일 때만 활성화
* 활성화 시 enableForceSimulation과 enableAutoScale은 자동으로 무시됨
*/
storageKey?: string;
/** 자동 저장 활성화 여부 - storageKey와 함께 사용시 localStorage에 상태 자동 저장 */
autoSave?: boolean;
}
```
## Events
```typescript
interface TopologyChartEmits {
/** 노드 호버 시 발생 */
'node-hover': [node: TopologyNode];
/** 노드 클릭 시 발생 */
'node-click': [node: TopologyNode];
/** 노드 선택 시 발생 (상세 데이터 로딩 포함) */
'node-select': [node: TopologyNode];
/** 노드 선택 해제 시 발생 */
'node-unselect': [];
/** 노드 분석 요청 시 발생 */
'node-analysis': [node: TopologyNode];
/** 엣지 호버 시 발생 */
'edge-hover': [edge: TopologyEdge];
/** 엣지 클릭 시 발생 */
'edge-click': [edge: TopologyEdge];
/** 엣지 선택 시 발생 (상세 데이터 로딩 포함) */
'edge-select': [edge: TopologyEdge];
/** 엣지 선택 해제 시 발생 */
'edge-unselect': [];
/** 엣지 분석 요청 시 발생 */
'edge-analysis': [edge: TopologyEdge];
/** 호버 해제 시 발생 */
'hover-out': [];
/** 차트 렌더링 완료 시 발생 */
'chart-ready': [];
/** 레이아웃 오류 발생 시 발생 */
'layout-error': [error: Error];
/** 클러스터 감지 완료 이벤트 */
'clusters-detected': [clusters: TopologyCluster[]];
/** 개별 클러스터 렌더링 완료 이벤트 */
'cluster-rendered': [clusterId: string, renderInfo: ClusterRenderInfo];
/** 전체 클러스터 렌더링 완료 이벤트 */
'all-clusters-rendered': [renderInfo: ClusterRenderInfo[]];
/** 포스 시뮬레이션 상태 변경 이벤트 (true: 완료, false: 시작) */
'simulation-state': [isComplete: boolean];
/** 포스 시뮬레이션 종료 이벤트 (더 이상 사용되지 않음, simulation-state 사용 권장) */
'force-simulation-end': [tickCount: number, finalAlpha: number];
/** 자동 저장 상태 변경 이벤트 */
'auto-save': [saved: boolean];
/** 노드 위치 상태 변경 이벤트 */
'node-positions-state': [hasPositions: boolean];
}
```
## 기본 사용법
```vue
```
## 인터랙티브 데모
토폴로지 통계
총 노드:
{{ nodeStats.total }}개
연결된 노드:
{{ nodeStats.connected }}개
고립된 노드:
{{ nodeStats.isolated }}개
총 엣지:
{{ edgeStats.total }}개
정상 엣지:
{{ edgeStats.normal }}개
실패 엣지:
{{ edgeStats.failed }}개
{{ event.time }}
{{ event.type }}
{{ event.detail }}
💡 사용법: 노드 드래그/클릭, 마우스 휠 확대/축소, 배경 드래그 이동, Force 시뮬레이션을 통한 물리 기반 자동 배치 등의 기능을 사용할 수 있습니다.
## 동적 크기 조절
```vue
```
## 이벤트 로깅 시스템
사용자 인터랙션을 추적하고 디버깅에 활용할 수 있는 이벤트 로깅 시스템:
```vue
이벤트 로그
{{ event.time }}
{{
event.type
}}
{{ event.detail }}
로그 지우기
```
## 통계 정보 표시
토폴로지 데이터의 통계 정보를 실시간으로 계산하고 표시:
````vue
토폴로지 통계
총 노드 수:
{{ nodeStats.total }}개
연결된 노드:
{{ nodeStats.connected }}개
고립된 노드:
{{ nodeStats.isolated }}개
총 엣지 수:
{{ edgeStats.total }}개
정상 엣지:
{{ edgeStats.normal }}개
실패 엣지:
{{ edgeStats.failed }}개
총 실패 건수:
{{ edgeStats.totalFailures }}건
최고 실패 엣지:
{{
edgeStats.topFailureEdge
}}
## 데이터 구조 ### TopologyData ```typescript interface TopologyData { nodes:
TopologyNode[]; edges: TopologyEdge[]; }
````
### TopologyNode
노드는 세 가지 타입으로 구분됩니다:
```typescript
// 인스턴스 노드
interface TopologyInstanceNode {
type: 'INSTANCE';
props: {
domainId: number;
instId: number;
oid: number;
shortName: string;
longName: string;
};
}
// 도메인 노드
interface TopologyDomainNode {
type: 'DOMAIN';
props: {
domainId: number;
shortName: string;
longName: string;
};
}
// 원격 호출 노드
interface TopologyRemoteCallNode {
type: 'REMOTE_CALL';
props: {
remoteCallType: RemoteCallTypeDef;
languageTypeOrZero: number;
customMethodDescHashOrZero: number;
customMethodDescOrEmpty: string;
ipAddressOrEmpty: string;
portOrZero: number;
};
}
type TopologyNode =
| TopologyInstanceNode
| TopologyDomainNode
| TopologyRemoteCallNode;
```
### TopologyEdge
```typescript
interface TopologyEdge {
relation: {
source: TopologyNode;
target: TopologyNode;
};
statistic: {
count: number; // 호출 횟수
timeSum: number; // 총 응답 시간 (ms)
failureCount: number; // 실패 횟수
};
}
```
## 샘플 데이터
자세한 샘플 데이터는 별도 파일에서 관리됩니다:
```typescript
// j5-components/data/sample-topology-data.ts 에서 import
import {
getCompleteTopologyData,
sampleTopologyData,
} from './data/sample-topology-data';
// 완전한 샘플 데이터 사용
const topologyData = getCompleteTopologyData();
// 또는 기본 노드만 사용하고 엣지는 직접 생성
const basicData = sampleTopologyData;
```
샘플 데이터에는 다음 요소들이 포함되어 있습니다:
- **8개 노드**: 웹서버, API게이트웨이, 마이크로서비스들, 데이터베이스, 캐시, 고립된 서비스
- **8개 엣지**: 다양한 호출량과 에러 발생 시나리오
- **실제적인 메트릭**: count, timeSum, failureCount 값들
- **Force 시뮬레이션 테스트**: 고립된 노드를 포함한 다양한 네트워크 구조
## 클러스터 기능
### 클러스터 자동 감지
TopologyChart는 노드 간의 연결 관계를 분석하여 자동으로 클러스터를 감지합니다:
```vue
```
### 클러스터 유형
```typescript
interface TopologyCluster {
id: string; // 클러스터 고유 ID
nodeIds: string[]; // 클러스터에 포함된 노드 ID 배열
type: 'normal' | 'isolated'; // 일반 클러스터 또는 고립된 노드
nodeCount: number; // 클러스터 내 노드 개수
}
interface ClusterRenderInfo {
cluster: TopologyCluster;
isRendered: boolean;
nodeCount: number;
}
```
### 선택적 클러스터 표시
특정 클러스터만 선택적으로 표시할 수 있습니다:
```vue
```
## API 통합 기능
### 노드 상세 데이터 로딩
노드 선택 시 자동으로 상세 메트릭 데이터를 로딩합니다:
```vue
```
### 엣지 상세 데이터 로딩
엣지 선택 시 트랜잭션 상세 데이터를 로딩합니다:
```vue
```
### 성능 테스트 시나리오
다양한 크기의 토폴로지 데이터로 성능 테스트를 수행할 수 있습니다:
```vue
Small Scale (8개 노드)
Medium Scale (25개 노드)
Large Scale (50개 노드)
Extreme Scale (100개 노드)
```
## 고급 기능
### Force 시뮬레이션
`enableForceSimulation`을 활성화하면 D3.js의 force 시뮬레이션을 사용하여 노드들이 물리 법칙에 따라 자동으로 배치됩니다:
- **Link Force**: 연결된 노드들을 적절한 거리에 배치
- **Charge Force**: 노드들 간의 반발력으로 겹치지 않게 배치
- **Center Force**: 노드들을 중앙으로 끌어당김
- **Collision Force**: 노드들이 겹치지 않도록 충돌 검사
#### Force 시뮬레이션 상태 감지
Force 시뮬레이션 상태 변경을 감지하려면 `simulation-state` 이벤트를 사용하는 것이 권장됩니다:
```vue
```
:::warning 중요한 변경사항 (v0.25.9+)
`enableForceSimulation`이 `false`일 때도 `simulation-state` 이벤트가 올바르게 발생합니다. 이전 버전에서는 이 경우 이벤트가 누락되는 버그가 있었습니다. `force-simulation-end` 이벤트는 하위 호환성을 위해 유지되지만, 새로운 코드에서는 `simulation-state`를 사용하는 것이 권장됩니다.
:::
#### 레거시 이벤트 (하위 호환성)
기존 `force-simulation-end` 이벤트도 계속 지원됩니다:
```vue
```
### 시각적 상태
- **정상 노드**: 초록색 배경, 연결된 상태
- **에러 노드**: 빨간색 배경, 실패한 엣지가 있는 경우
- **고립 노드**: 회색 배경, 연결이 없는 경우
- **선택/호버**: 관련된 노드와 엣지가 하이라이팅됨
### 스케일 컨트롤
- **확대/축소**: 마우스 휠 또는 버튼으로 차트 확대/축소
- **자동 스케일**: 데이터에 맞는 최적의 스케일 자동 계산
- **뷰포트 이동**: 배경 드래그로 차트 이동 가능
## 활용 사례
### 기본 모니터링
1. **마이크로서비스 아키텍처 시각화**: 서비스 간 의존성과 호출 관계 파악
2. **성능 병목 지점 탐지**: 높은 응답 시간과 실패율을 가진 연결 식별
3. **장애 전파 경로 추적**: 실패 카운트 기반 장애 영향 범위 분석
### 고급 분석
4. **클러스터 기반 서비스 그룹화**: 자동 감지된 클러스터를 통한 마이크로서비스 도메인 분리
5. **선택적 시스템 뷰**: 특정 클러스터만 표시하여 복잡한 시스템의 관심 영역 집중 분석
6. **대규모 인프라 최적화**: 100개 이상 노드를 가진 복잡한 시스템의 성능 분석
### 실시간 운영
7. **동적 모니터링**: 노드 위치 보존을 통한 실시간 상태 변화 추적
8. **자동화된 인시던트 대응**: API 통합을 통한 자동 상세 데이터 로딩 및 분석
9. **다단계 드릴다운 분석**: 엣지 선택 시 자동 트랜잭션 내역 로딩
### 비즈니스 인사이트
10. **용량 계획**: 성능 테스트 시나리오를 통한 확장성 검증
11. **비용 최적화**: 고립된 노드 식별 및 미사용 리소스 발견
12. **아키텍처 ꫀ버닝**: 마이크로서비스 의존성 맵 기반 전체 시스템 이해도 향상
## 개발 서버에서 테스트
업데이트된 TopologyChart를 테스트하려면:
```bash
# VitePress 개발 서버 실행
cd ../../clara-server/frontend/apps/design-docs
pnpm dev
# 브라우저에서 확인
open http://localhost:5173/j5-components/topology-chart
```
## 버전 업데이트 내역
### v0.25.9 버그 수정 및 개선 (2025-10-13)
- **시뮬레이션 이벤트 수정**: `enableForceSimulation`이 `false`일 때 `simulation-state` 이벤트가 누락되던 버그 수정
- **새로운 이벤트 추가**: `simulation-state`, `node-unselect`, `edge-unselect`, `node-analysis`, `edge-analysis`, `auto-save`, `node-positions-state` 이벤트 추가
- **클러스터 드래그 개선**: 고립된 노드 클러스터 드래그 기능 완전 복원
- **충돌 처리 최적화**: 클러스터 충돌 감지 및 처리 로직 개선
- **실시간 모드 버그 수정**: `realtimeMode`에서 `enableForceSimulation=false` 시 클러스터 드래그 버그 수정
### v0.25.2~v0.25.8 클러스터 드래그 및 시뮬레이션 개선
- **클러스터 정보 컴포넌트**: ClusterInfo 컴포넌트 추가 및 드래그 기능 구현
- **동적 힘 분배**: 클러스터 노드 개수 기반 동적 힘 분배 시스템
- **4단계 충돌 로직**: 다양한 시나리오별 클러스터 충돌 감지 및 해결
- **공간 그리드 최적화**: Spatial Grid를 이용한 충돌 감지 성능 최적화
- **자동 저장 개선**: 노드 위치 localStorage 저장 및 복원 기능
### v0.19.2 주요 업데이트
- **클러스터 자동 감지**: 노드 간 연결 관계 분석을 통한 스마트 클러스터링
- **API 통합 기능**: 노드/엣지 선택 시 자동 상세 데이터 로딩
- **성능 테스트 시나리오**: Small~Extreme 스케일의 다양한 테스트 데이터 지원
- **선택적 클러스터 표시**: 특정 클러스터만 표시하여 대규모 시스템의 분석 대응
- **실시간 모드**: 노드 위치 보존을 통한 지속적인 모니터링 지원
- **향상된 이벤트 시스템**: `node-select`, `edge-select`, `clusters-detected` 등 새로운 이벤트 추가
업데이트된 TopologyChart는 이제 엔터프라이즈급 대규모 시스템 모니터링과 지능형 상태 분석을 지원하며, 실시간 API 통합을 통해 더욱 심층적인 인사이트를 제공합니다.
### File: j5-components/sankey-diagram.md
# SankeyDiagram
MSA (Microservices Architecture) 분석을 위한 계층형 플로우 다이어그램 컴포넌트입니다.
## 개요
SankeyDiagram은 마이크로서비스 간의 호출량과 데이터 플로우를 시각적으로 표현하는 차트입니다. 노드는 서비스를, 링크는 서비스 간 호출 관계를 나타내며, 링크의 두께로 호출량을 직관적으로 파악할 수 있습니다.
## 주요 특징
- **플로우 시각화**: 서비스 간 호출량을 링크 두께로 표현
- **메트릭 선택**: count 또는 timeSum 메트릭 선택 가능
- **노드 정렬**: 다양한 노드 정렬 방식 지원 (left, center, right, justify)
- **에러 하이라이팅**: 에러 발생 링크 별도 색상 표시
- **인터랙티브 컨트롤**: 노드 크기, 폰트 크기 실시간 조정
- **그라데이션 링크**: 소스와 타겟 노드 색상을 혼합한 링크 색상
- **상세 데이터 연동**: 노드/엣지 선택 시 상세 정보 표시 지원
- **노드 필터링**: 마지막 depth의 상위 노드 수 제한 기능
- **라벨 제어**: 노드 라벨 표시/숨김 옵션
## Props Interface
```typescript
interface SankeyDiagramProps {
/** 토폴로지 데이터 */
data: TopologyData;
/** 차트 너비 (기본값: 800) */
width?: number;
/** 차트 높이 (기본값: 600) */
height?: number;
/** 노드 정렬 방식 (기본값: 'justify') */
nodeAlign?: 'left' | 'center' | 'right' | 'justify';
/** 노드 스케일 컨트롤 표시 여부 (기본값: true) */
showScaleControls?: boolean;
/** 에러 하이라이팅 활성화 (기본값: false) */
errorOnlyHighlight?: boolean;
/** 선택된 메트릭 (기본값: 'timeSum') */
selectedMetric?: 'timeSum' | 'count';
/** 노드 라벨 숨김 여부 (기본값: false) */
hideNodeLabels?: boolean;
/** 마지막 depth의 상위 클러스터 수 제한 (기본값: -1, -1이면 전체 표시) */
maxClusterCount?: number;
/** 현재 선택된 엣지 - 상세 정보 표시용 */
selectedEdge?: TopologyEdge;
/** 엣지 상세 데이터 - API 호출 후 가져온 데이터 */
edgeDetailData?: EdgeDetailData;
/** 현재 선택된 노드 - 상세 정보 표시용 */
selectedNode?: TopologyNode;
/** 노드 상세 데이터 - API 호출 후 가져온 데이터 */
nodeDetailData?: Record;
}
```
## Events
```typescript
interface SankeyDiagramEmits {
/** 노드 호버 시 발생 */
'node-hover': [node: TopologyNode];
/** 노드 클릭 시 발생 */
'node-click': [node: TopologyNode];
/** 노드 선택 시 발생 (상세 데이터 로딩 포함) */
'node-select': [node: TopologyNode];
/** 링크 호버 시 발생 */
'link-hover': [link: TopologyEdge];
/** 링크 클릭 시 발생 */
'link-click': [link: TopologyEdge];
/** 엣지 선택 시 발생 (상세 데이터 로딩 포함) */
'edge-select': [edge: TopologyEdge];
/** 호버 해제 시 발생 */
'hover-out': [];
/** 차트 렌더링 완료 시 발생 */
'chart-ready': [];
/** 레이아웃 오류 발생 시 발생 */
'layout-error': [error: Error];
}
```
## 기본 사용법
```vue
```
## 라이브 데모
SankeyDiagram 라이브 데모
💡 사용법: 컴포넌트가 로드되면 노드나 링크 클릭/호버, 메트릭 변경에 따른 링크 두께 조정, 스케일 컨트롤로 노드 크기와 폰트 조정 등의 기능을 사용할 수 있습니다.
## API 통합 및 실시간 데이터
SankeyDiagram도 TopologyChart와 동일한 방식으로 JENNIFER APM API를 통해 실시간 데이터를 가져올 수 있습니다:
```vue
데이터 로딩 중... {{ Math.round(progress * 100) }}%
```
## 동적 메트릭 전환
메트릭을 동적으로 전환하여 다양한 관점에서 데이터 플로우를 분석할 수 있습니다:
```vue
{{ selectedMetric === 'timeSum' ? '응답 시간' : '호출 횟수' }}
통계
총
{{
selectedMetric === 'timeSum'
? '응답 시간'
: '호출 횟수'
}}:
{{ totalMetricValue.toLocaleString()
}}{{ selectedMetric === 'timeSum' ? 'ms' : '건' }}
평균
{{
selectedMetric === 'timeSum'
? '응답 시간'
: '호출 횟수'
}}:
{{ averageMetricValue.toLocaleString()
}}{{ selectedMetric === 'timeSum' ? 'ms' : '건' }}
최대
{{
selectedMetric === 'timeSum'
? '응답 시간'
: '호출 횟수'
}}:
{{ maxMetricValue.toLocaleString()
}}{{ selectedMetric === 'timeSum' ? 'ms' : '건' }}
```
## 이벤트 로깅 및 분석
SankeyDiagram의 인터랙션을 추적하고 사용자 행동을 분석할 수 있습니다:
```vue
사용자 상호작용 분석
총 클릭 수:
{{ totalClicks }}
노드 클릭:
{{ nodeClicks }}
링크 클릭:
{{ linkClicks }}
가장 많이 클릭된 노드:
{{ mostClickedNode }}
노드별 클릭 빈도
{{ getNodeName(nodeId) }}
```
## 데이터 구조
SankeyDiagram은 TopologyChart와 동일한 데이터 구조를 사용합니다.
### TopologyData
```typescript
interface TopologyData {
nodes: TopologyNode[];
edges: TopologyEdge[];
}
```
### TopologyEdge (중요)
Sankey 다이어그램에서 링크의 두께는 `statistic` 필드의 값에 따라 결정됩니다:
```typescript
interface TopologyEdge {
relation: {
source: TopologyNode;
target: TopologyNode;
};
statistic: {
count: number; // 호출 횟수 (selectedMetric="count"일 때 사용)
timeSum: number; // 총 응답 시간 (selectedMetric="timeSum"일 때 사용)
failureCount: number; // 실패 횟수 (에러 하이라이팅에 사용)
};
}
```
## 노드 정렬 방식
### justify (기본값)
노드들이 전체 너비에 고르게 분산되어 배치됩니다. 가장 균형 잡힌 레이아웃을 제공합니다.
### left
모든 노드가 왼쪽 정렬되어 배치됩니다. 시작점이 명확한 플로우에 적합합니다.
### center
모든 노드가 중앙 정렬되어 배치됩니다. 대칭적인 구조를 강조하고 싶을 때 사용합니다.
### right
모든 노드가 오른쪽 정렬되어 배치됩니다. 최종 결과를 강조하고 싶을 때 사용합니다.
## 메트릭 선택
### timeSum (기본값)
각 엣지의 `timeSum` 값을 사용하여 링크 두께를 결정합니다. 총 응답 시간이 클수록 링크가 두껍게 표시됩니다.
### count
각 엣지의 `count` 값을 사용하여 링크 두께를 결정합니다. 호출 횟수가 많을수록 링크가 두껍게 표시됩니다.
## 에러 하이라이팅
`errorOnlyHighlight` 옵션을 활성화하면:
- **에러 링크**: `failureCount > 0`
### File: j5-components/transaction-table.md
# TransactionTable
트랜잭션 데이터에 특화된 고성능 테이블 컴포넌트입니다.
## 개요
TransactionTable은 BaseTable을 확장하여 트랜잭션 분석에 필요한 특수 기능들을 제공합니다. ProfileInfo 컴포넌트를 내장하고, 트랜잭션 전용 행 렌더링과 정렬 기능을 포함합니다.
## Props 인터페이스
```typescript
interface Props>
extends PagingTableProps {
maxMap: TransactionTime; // 각 시간 메트릭의 최대값
}
interface TransactionData {
elapsedTime: number; // 응답시간
sqlTime: number; // SQL 실행시간
externalCallTime: number; // 외부 호출 시간
methodTime: number; // 메소드 실행시간
errorType: number; // 에러 타입
// ... 기타 트랜잭션 속성들
}
interface TransactionTime {
elapsedTime: number;
sqlTime: number;
externalCallTime: number;
methodTime: number;
}
```
## 기본 사용법
```vue
내보내기
{{ page }} / {{ Math.ceil(totalCount / 20) }}
```
## 내장 기능
### 1. ProfileInfo 자동 표시
트랜잭션 프로파일 정보가 테이블 상단에 자동으로 표시됩니다.
### 2. 전용 행 렌더링
트랜잭션 데이터에 최적화된 셀 렌더링을 제공합니다.
### 3. 시간 메트릭 시각화
응답시간, SQL 시간, 외부 호출 시간을 바 차트로 시각화합니다.
### 4. 내장 정렬
트랜잭션 데이터에 최적화된 정렬 알고리즘을 제공합니다.
## 고급 사용법
### 에러 트랜잭션 필터링
```vue
```
### 성능 임계값 기반 색상
```vue
```
## 의존성
- BaseTable
- ProfileInfo
- ColumnTools
- Vue 3 Composition API
### File: j5-components/base-row.md
# BaseRow
테이블 행 렌더링을 위한 기본 컴포넌트입니다.
## 개요
BaseRow는 BaseTable에서 사용되는 행 렌더링 컴포넌트입니다. 다양한 셀 타입을 지원하며, 선택 상태와 스켈레톤 로딩을 처리합니다.
## Props
```typescript
interface Props> {
row: PagingTableRow; // 행 데이터
columns: PagingTableColumn[]; // 컬럼 정의
cellWidths: number[]; // 셀 너비 배열
scrollBarWidth: number; // 스크롤바 너비
maxMap?: Record; // 최대값 맵 (BAR 셀용)
}
```
## 지원 셀 타입
- **TEXT**: 일반 텍스트
- **VALUE**: 숫자 값 (천단위 구분자)
- **DATE**: 날짜 형식
- **TIME**: 시간 형식
- **BAR**: 바 차트 시각화
- **ERROR**: 에러 상태 표시
- **SKELETON**: 로딩 상태
## 기본 사용법
```vue
```
## 의존성
- PagingTableColumn, PagingTableRow 타입
- 각종 셀 렌더러 컴포넌트
### File: j5-components/base-table.md
# BaseTable
재사용 가능한 기본 테이블 컴포넌트입니다. 정렬, 페이징, 컬럼 크기 조정, 행 선택 등의 기본 테이블 기능을 제공합니다.
## 개요
BaseTable은 PagingTable의 핵심 기능을 담당하는 컴포넌트로, 대용량 데이터 테이블을 효율적으로 렌더링하고 사용자 인터랙션을 처리합니다. 컬럼 설정 저장, 동적 크기 조정, 스켈레톤 로딩 등의 고급 기능을 포함합니다.
## 주요 특징
- **📊 대용량 데이터 처리**: 가상화를 통한 효율적인 렌더링
- **🔧 컬럼 커스터마이징**: 크기 조정, 표시/숨김, 순서 변경
- **🔍 정렬 및 검색**: 다중 컬럼 정렬과 행 검색 지원
- **💾 설정 저장**: 로컬 스토리지를 통한 사용자 설정 유지
- **⚡ 스켈레톤 로딩**: 데이터 로딩 중 스켈레톤 UI 표시
- **✅ 행 선택**: 단일/다중 행 선택 지원
## Props Interface
```typescript
interface PagingTableProps> {
/** 테이블 고유 식별자 (설정 저장용) */
alias: string;
/** 테이블 너비 */
width: number;
/** 테이블 높이 */
height: number;
/** 페이지당 표시할 행 수 */
displayCount: number;
/** 컬럼 정의 배열 */
columns: PagingTableColumn[];
/** 테이블 데이터 배열 */
rows: PagingTableRow[];
/** 행 높이 (기본값: 40px) */
rowHeight?: number;
/** 컬럼별 최대값 맵 (프로그레스 바 등에 사용) */
maxMap?: Record;
/** 현재 정렬 키 */
sortKey?: string;
/** 현재 정렬 순서 */
sortOrder?: PagingTableSortOrder;
/** 정렬 로딩 상태 */
sortLoading?: boolean;
/** 스켈레톤 로딩 사용 여부 (기본값: true) */
useSkeleton?: boolean;
/** 행 선택 기능 사용 여부 (기본값: true) */
useSelect?: boolean;
/** 찾을 행 ID (해당 행으로 자동 스크롤) */
foundRowId?: string;
/** 선택된 행 ID 배열 */
selectedRowIds?: string[];
}
```
## 컬럼 정의
```typescript
interface PagingTableColumn {
/** 컬럼 키 (데이터 객체의 속성 이름) */
key: string;
/** 컬럼 표시 이름 */
name: string;
/** 셀 타입 */
type: PagingTableCellType;
/** 컬럼 비율 (0-1, 전체 너비 대비) */
rate?: number;
/** 정렬 가능 여부 */
sortable?: boolean;
/** 표시 여부 */
visible?: boolean;
/** 셀 색상 */
color?: string;
}
```
## 행 데이터 구조
```typescript
interface PagingTableRow {
/** 실제 데이터 객체 */
data: T;
/** 행 고유 식별자 */
id: string;
}
```
## Events
```typescript
interface PagingTableEmits {
/** 컬럼 정렬 시 발생 */
'sort': [key: string, order: PagingTableSortOrder];
/** 행 선택 시 발생 */
'select': [id: string, row?: PagingTableRow];
}
```
## 기본 사용법
```vue
총 {{ tableRows.length }}개 항목
설정 초기화
데이터 내보내기
{{ getStatusText(value) }}
{{ value }}
```
## 컬럼 타입
BaseTable은 다양한 셀 타입을 지원합니다:
```typescript
enum PagingTableCellType {
TEXT = 'TEXT', // 일반 텍스트
NUMBER = 'NUMBER', // 숫자 (천 단위 구분자 포함)
DATETIME = 'DATETIME', // 날짜/시간
PROGRESS = 'PROGRESS', // 프로그레스 바
CUSTOM = 'CUSTOM', // 커스텀 렌더링
LINK = 'LINK', // 링크
BADGE = 'BADGE', // 배지
CHART = 'CHART' // 미니 차트
}
```
## 설정 저장 및 복원
BaseTable은 사용자 설정을 자동으로 로컬 스토리지에 저장합니다:
```typescript
// 저장되는 설정들
interface TableSettings {
columnRates: number[]; // 컬럼 너비 비율
visibleColumns: string[]; // 표시되는 컬럼 키
sortKey: string; // 마지막 정렬 키
sortOrder: PagingTableSortOrder; // 마지막 정렬 순서
}
// 스토리지 키 형식
const storageKeys = {
columnRates: `COLUMN_RATES#${alias}`,
visibleColumns: `VISIBLE_COLUMNS#${alias}`,
sortSettings: `SORT_SETTINGS#${alias}`
};
```
## 슬롯 활용
### information 슬롯
```vue
총 {{ totalCount }}개
{{ selectedCount }}개 선택됨
필터 적용됨
```
### tools 슬롯
```vue
설정 초기화
```
### row 슬롯
```vue
{{ formatCellValue(value, column.type) }}
```
## 의존성
- `@jennifersoft/vue-components-v2`: ProgressIndicator 컴포넌트
- Vue 3: Composition API와 Generic Props 지원
- 로컬 스토리지: 사용자 설정 저장
## 브라우저 지원
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
## 알려진 제한사항
1. **메모리 사용량**: 대용량 데이터 (10,000+ 행)에서 메모리 사용량 증가
2. **가상화**: 현재 수직 가상화만 지원 (수평 가상화 미지원)
3. **컬럼 순서**: 동적 컬럼 순서 변경 미지원 (향후 버전에서 지원 예정)
### File: j5-components/popover-balloon.md
# PopoverBalloon
위치 기반 팝오버 말풍선 컴포넌트입니다.
## 개요
PopoverBalloon은 특정 요소 주변에 말풍선 형태의 팝오버를 표시하는 컴포넌트입니다. HTML 콘텐츠를 지원하며, 다양한 위치와 스타일링 옵션을 제공합니다.
## Props
```typescript
interface Props {
content: string; // HTML 문자열 지원
position?: PopoverPosition; // 위치 (기본: 'right')
offset?: number; // 오프셋 (기본: 10px)
cursorNone?: boolean; // 화살표 숨김 (기본: false)
contentPadding?: number; // 콘텐츠 패딩 (기본: 24px)
}
type PopoverPosition =
| 'top'
| 'top-left'
| 'top-right'
| 'bottom'
| 'bottom-left'
| 'bottom-right'
| 'left'
| 'right';
```
## 기본 사용법
```vue
```
## 위치 옵션
- `top`, `top-left`, `top-right`: 상단 배치
- `bottom`, `bottom-left`, `bottom-right`: 하단 배치
- `left`, `right`: 좌/우측 배치
---
# TooltipBalloon
간단한 툴팁 말풍선 컴포넌트입니다.
## 개요
TooltipBalloon은 PopoverBalloon의 경량화 버전으로, 간단한 텍스트 툴팁을 표시할 때 사용합니다.
## Props
```typescript
interface Props {
text: string; // 툴팁 텍스트
position?: TooltipPosition; // 위치 (기본: 'top')
visible?: boolean; // 표시 여부 (기본: false)
}
```
## 기본 사용법
```vue
버튼
```
---
# NodeTooltip
노드 요소용 전용 툴팁 컴포넌트입니다.
## 개요
NodeTooltip은 토폴로지나 관계 트리의 노드에 표시되는 전용 툴팁입니다. 노드의 메트릭 정보를 구조화된 형태로 표시합니다.
## Props
```typescript
interface Props {
width: number; // 노드 너비
x: number; // X 좌표
y: number; // Y 좌표
translateX: number; // X 변환값
translateY: number; // Y 변환값
data: NodeData; // 노드 데이터
cursorNone?: boolean; // 커서 숨김
scale?: number; // 스케일 (기본: 1)
useSimpleTooltip?: boolean; // 간단한 툴팁 모드
}
```
## 기본 사용법
```vue
```
---
# TextInNode
노드 내부에 표시되는 텍스트 컴포넌트입니다.
## 개요
TextInNode는 토폴로지나 관계 트리의 노드 내부에 텍스트를 표시하는 컴포넌트입니다. 텍스트 길이에 따른 자동 줄바꿈과 말줄임표를 지원합니다.
## Props
```typescript
interface Props {
text: string; // 표시할 텍스트
maxWidth?: number; // 최대 너비 (기본: 무제한)
fontSize?: number; // 폰트 크기 (기본: 14px)
textAlign?: 'left' | 'center' | 'right'; // 텍스트 정렬 (기본: 'center')
ellipsis?: boolean; // 말줄임표 사용 (기본: true)
}
```
## 기본 사용법
```vue
```
## 공통 사용 패턴
### 호버 툴팁 패턴
```vue
```
### 조건부 툴팁
```vue
```
## 의존성
- Vue 3 Composition API
- CSS Variables for theming
### File: j5-components/scale-controller.md
# ScaleController
차트나 캔버스 요소의 확대/축소를 제어하는 UI 컨트롤러 컴포넌트입니다. 마우스 휠, 터치 제스처, 버튼 클릭을 통한 스케일 조정을 지원합니다.
## 개요
ScaleController는 토폴로지 차트, 이미지 뷰어, 캔버스 기반 애플리케이션 등에서 사용할 수 있는 범용 스케일 컨트롤러입니다. 직관적인 UI와 다양한 입력 방식을 통해 사용자가 콘텐츠의 확대/축소를 쉽게 조절할 수 있습니다.
## 주요 특징
- **🎯 다양한 입력 지원**: 마우스 휠, 터치 핀치, 버튼 클릭
- **📱 터치 최적화**: 모바일 디바이스의 핀치 제스처 지원
- **🎨 위치 커스터마이징**: 4가지 코너 위치 선택 가능
- **⚙️ 완전 커스터마이징**: 크기, 마진, 아이콘 등 자유로운 스타일링
- **♿ 접근성**: 키보드 네비게이션과 스크린 리더 지원
- **🔧 이벤트 기반**: 유연한 스케일 로직 구현 가능
## Props Interface
```typescript
interface ScaleControllerProps {
/** 컨트롤러 위치 (기본값: 'bottom-right') */
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
/** 컨트롤러 표시 여부 (기본값: true) */
visible?: boolean;
/** 마우스 휠 이벤트 활성화 여부 (기본값: true) */
enableWheel?: boolean;
/** 터치 이벤트 활성화 여부 (기본값: true) */
enableTouch?: boolean;
/** 버튼 크기 (기본값: 32px) */
buttonSize?: number;
/** 컨트롤러 마진 (기본값: 8px) */
margin?: number;
}
```
## Events
```typescript
interface ScaleControllerEmits {
/** 마우스 휠 이벤트 (확대/축소) */
'wheel': [event: WheelEvent];
/** '+' 버튼 클릭 (확대) */
'clickUp': [];
/** '-' 버튼 클릭 (축소) */
'clickDown': [];
/** '원복' 버튼 클릭 (초기 스케일로 복원) */
'clickReset': [];
}
```
## 기본 사용법
```vue
```
## SVG 차트와 함께 사용
```vue
{{ node.label }}
```
## 토폴로지 차트와 통합
```vue
```
## 터치 제스처 처리
```vue
```
## 커스텀 스타일링
```vue
```
## 구성 요소
ScaleController는 다음 구성 요소들로 이루어져 있습니다:
### 버튼 종류
- **확대 버튼** (`+`): 스케일 증가
- **원복 버튼** (⛶): 초기 스케일로 복원
- **축소 버튼** (`-`): 스케일 감소
### 이벤트 처리
- **마우스 휠**: 부드러운 확대/축소
- **터치 핀치**: 모바일 디바이스 지원
- **버튼 클릭**: 정확한 스케일 조정
### 설정 옵션
- **위치**: 4개 코너 중 선택
- **크기**: 버튼 크기와 마진 조정
- **활성화**: 개별 이벤트 타입 제어
## 의존성
- `@jennifersoft/vue-components-v2`: SvgIcon, ICON_TYPE
- Vue 3: Composition API 기반
- 터치 이벤트 지원을 위한 모던 브라우저
## 브라우저 지원
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
- 모바일 브라우저 (iOS Safari, Android Chrome)
## 알려진 제한사항
1. **터치 인터페이스**: 복잡한 멀티터치 제스처는 제한적 지원
2. **성능**: 고해상도 캔버스에서 연속적인 스케일 변경 시 성능 저하 가능
3. **브라우저 호환성**: 일부 오래된 브라우저에서 터치 이벤트 지원 제한
## 활용 사례
1. **토폴로지 차트**: 네트워크 다이어그램 확대/축소
2. **이미지 뷰어**: 고해상도 이미지 상세 보기
3. **캔버스 에디터**: 그래픽 편집 도구의 줌 기능
4. **데이터 시각화**: 복잡한 차트의 상세 분석
5. **지도 애플리케이션**: 지도 영역 확대/축소
6. **게임 인터페이스**: 미니맵이나 전략 뷰어