Vue 차트
@sectile/vue/chart는 차트, 축, 데이터 레이어, 조작 버튼, Canvas 렌더러를 위한 컴포넌트를 제공합니다. 데이터는 배열로 남기 때문에 데이터 하나마다 Vue 컴포넌트나 감시자가 생기지 않습니다.
주간 매출 추이
순서가 있는 값의 변화를 하나의 선으로 표시합니다.
- 가리킨 항목
- 없음
- 선택한 항목
- 없음
<script setup lang="ts">
import {
ChartLine, ChartAxisView, ChartCartesian, ChartNavigation,
ChartPanControl, ChartPlot, ChartRenderer, ChartResetView, ChartRoot,
ChartViewControls, ChartXAxis, ChartYAxis, ChartZoomControl,
} from '@sectile/vue/chart'
const revenue = [
{ id: 'week-27', date: new Date('2026-07-06'), revenue: 128 },
{ id: 'week-28', date: new Date('2026-07-13'), revenue: 142 },
{ id: 'week-29', date: new Date('2026-07-20'), revenue: 137 },
{ id: 'week-30', date: new Date('2026-07-27'), revenue: 163 },
]
const datumLabels = new Map(revenue.map(point => [point.id, point.date.toLocaleDateString()]))
const dom = {
renderer: 'auto',
accessibilityLabel: '주간 매출 추이',
getAccessibleDatumLabel: (id: string | number) => datumLabels.get(String(id)) ?? String(id),
} as const
</script>
<template>
<ChartRoot :dom="dom" class="chart">
<ChartCartesian>
<ChartXAxis id="x" scale="temporal" field="date" label="Week">
<ChartAxisView :minimum-span="1" />
</ChartXAxis>
<ChartYAxis id="y" scale="linear" field="revenue" label="Revenue" unit="USD thousands" />
<ChartLine id="revenue-series" :data="revenue" x-axis="x" y-axis="y" label="Revenue" />
<ChartNavigation keyboard />
<ChartViewControls axis="x">
<ChartPanControl direction="backward">이전</ChartPanControl>
<ChartZoomControl direction="in">확대</ChartZoomControl>
<ChartZoomControl direction="out">축소</ChartZoomControl>
<ChartResetView>초기화</ChartResetView>
</ChartViewControls>
</ChartCartesian>
<ChartPlot><ChartRenderer /></ChartPlot>
</ChartRoot>
</template>
<style scoped>
.chart {
position: relative;
height: 24rem;
}
.chart :deep([data-part='plot']),
.chart :deep(canvas) {
width: 100%;
height: 100%;
}
</style>설치
pnpm add vue @sectile/chart @sectile/dom @sectile/vue이 패키지들은 차트 진입점에만 필요합니다. 다른 @sectile/vue 컴포넌트에는 추가되지 않습니다.
주간 매출 차트 만들기
다음 예제에는 시간 축, 숫자 축, 키보드 탐색, 눈에 보이는 범위 조작 버튼, 데이터별 접근성 이름, 반응형 차트 영역이 들어 있습니다.
<script setup lang="ts">
import {
ChartAxisTicks, ChartAxisView, ChartCartesian, ChartGrid, ChartLegend,
ChartLine, ChartNavigation, ChartPanControl, ChartPlot, ChartRenderer,
ChartResetView, ChartRoot, ChartViewControls, ChartXAxis, ChartYAxis,
ChartZoomControl,
} from '@sectile/vue/chart'
import { computed, shallowRef } from 'vue'
const revenue = shallowRef([
{ id: 271, date: new Date('2026-07-06'), amount: 128_000 },
{ id: 272, date: new Date('2026-07-13'), amount: 142_000 },
{ id: 273, date: new Date('2026-07-20'), amount: 137_000 },
])
const revenueLabels = computed(() => new Map(revenue.value.map(point => [
point.id,
`${point.date.toLocaleDateString()}: ${point.amount.toLocaleString()}`,
])))
const dom = {
renderer: 'auto',
accessibilityLabel: '주간 매출',
getAccessibleDatumLabel: (id: number) => revenueLabels.value.get(id) ?? String(id),
} as const
</script>
<template>
<ChartRoot :dom="dom" class="revenue-chart">
<ChartCartesian>
<ChartXAxis id="date" scale="temporal" field="date" label="주">
<ChartAxisView :minimum-span="86_400_000" update="follow-end" />
</ChartXAxis>
<ChartYAxis id="amount" scale="linear" field="amount" label="매출" />
<ChartLine
id="weekly-revenue"
:data="revenue"
x-axis="date"
y-axis="amount"
label="매출"
/>
<ChartNavigation keyboard />
<ChartViewControls axis="date">
<ChartPanControl direction="backward">이전</ChartPanControl>
<ChartZoomControl direction="in">확대</ChartZoomControl>
<ChartZoomControl direction="out">축소</ChartZoomControl>
<ChartResetView>초기화</ChartResetView>
</ChartViewControls>
</ChartCartesian>
<ChartGrid />
<ChartAxisTicks />
<ChartLegend />
<ChartPlot><ChartRenderer /></ChartPlot>
</ChartRoot>
</template>
<style scoped>
.revenue-chart {
position: relative;
height: 24rem;
}
.revenue-chart :deep([data-part='plot']),
.revenue-chart :deep(canvas) {
width: 100%;
height: 100%;
}
</style>축의 field가 date와 amount를 읽고, id 속성이 각 데이터를 구분합니다. 값이 객체 안쪽에 있거나 계산해야 할 때만 별도 함수를 전달하면 됩니다.
새 데이터를 받으면 revenue.value를 교체하세요. 같은 주간 데이터에는 같은 ID를 유지해야 갱신 뒤에도 선택 상태가 남습니다. ChartRoot가 제거되면 컨트롤러, 이벤트 리스너, 크기 관찰자, 그래픽 자원도 함께 정리됩니다.
파이 또는 도넛 차트 만들기
<ChartRoot :dom="{ accessibilityLabel: '예산 배분' }">
<ChartRadial>
<ChartPie id="budget" :data="budget" label="예산" />
</ChartRadial>
<ChartPlot><ChartRenderer /></ChartPlot>
</ChartRoot>id, value, label 필드가 있는 데이터는 별도 연결 함수 없이 쓸 수 있습니다. 파이와 도넛에는 x축, y축, 이동, 확대·축소 기능을 넣지 않습니다.
상태 제어하고 공유하기
<ChartRoot
v-model="selection"
v-model:view="sharedView"
v-model:cursor="cursor"
@command="persistChartCommand"
>
<!-- declarations -->
</ChartRoot>기본 슬롯은 현재 state, projection, definition 값을 제공합니다. 차트 가까이에 툴팁이나 상태 표시를 만들 때 사용하세요. 페이지의 다른 컴포넌트에서는 useChartSelector, useChartLayerSelector, useChartAxisSelector로 필요한 값만 읽을 수 있습니다.
여러 차트 영역이나 컴포넌트 트리에서 하나의 컨트롤러를 공유해야 할 때만 ChartProvider나 createChartComponents(controller)를 사용하세요.
서버 렌더링 중에는 ChartRoot가 브라우저 자원을 만들지 않습니다. 서버와 첫 클라이언트 렌더링에 같은 차트 구성과 제어 상태를 전달하세요. 크기 측정과 Canvas 그리기는 하이드레이션 뒤 시작합니다.
