DOM 렌더링
Vue 컴포넌트 없이 앱이 직접 HTML을 관리한다면 @sectile/dom/chart를 사용하세요. 차트 영역의 크기를 재고 Canvas에 그리며, 크기 변경에 맞춰 갱신하고, 키보드와 화면 읽기 프로그램에 필요한 요소도 만듭니다.
지역별 주문
범주별 크기를 같은 기준선에서 비교합니다.
- 가리킨 항목
- 없음
- 선택한 항목
- 없음
// HTML: <div data-chart><canvas></canvas></div>
// Give the container a height and make the canvas fill it with CSS.
import { createChartController } from '@sectile/chart/controller'
import { createDOMChart } from '@sectile/dom/chart'
const orders = [
{ id: 'seoul', region: 'Seoul', orders: 812 },
{ id: 'busan', region: 'Busan', orders: 594 },
{ id: 'daegu', region: 'Daegu', orders: 436 },
{ id: 'incheon', region: 'Incheon', orders: 521 },
]
const datumLabels = new Map(orders.map(order => [order.id, order.region]))
const definition = {
coordinate: { kind: 'cartesian', axes: [
{ id: 'x', orientation: 'x', scale: 'categorical', field: 'region', label: 'Region' },
{ id: 'y', orientation: 'y', scale: 'linear', field: 'orders', label: 'Order volume', unit: 'orders' },
] },
layers: [{
kind: 'bar', id: 'regional-orders', data: orders,
xAxis: 'x', yAxis: 'y', label: 'Orders',
}],
} as const
const root = document.querySelector('[data-chart]')
const canvas = root?.querySelector('canvas')
if (!(root instanceof HTMLElement) || !(canvas instanceof HTMLCanvasElement)) {
throw new Error('차트 영역을 찾을 수 없습니다')
}
const controller = createChartController({
definition,
viewCapabilities: [{ axisID: 'x', minimumSpan: 1 }],
})
const chart = createDOMChart({
root,
canvas,
controller,
renderer: 'auto',
accessibilityLabel: '지역별 주문',
getAccessibleDatumLabel: id => datumLabels.get(String(id)) ?? String(id),
navigation: { wheel: 'native', keyboard: true },
})
window.addEventListener('pagehide', () => {
chart.disconnect()
controller.dispose()
}, { once: true })설치
pnpm add @sectile/chart @sectile/dom기존 HTML 요소 연결하기
데이터와 스케일의 definition과 revenue 데이터를 이어서 사용합니다. 차트 영역에는 높이를 지정하고 Canvas가 그 안을 채우게 합니다.
<div data-chart>
<canvas></canvas>
</div>[data-chart] {
position: relative;
height: 24rem;
}
[data-chart] canvas {
display: block;
width: 100%;
height: 100%;
}import { createChartController } from '@sectile/chart/controller'
import { createDOMChart } from '@sectile/dom/chart'
const root = document.querySelector('[data-chart]')
const canvas = root?.querySelector('canvas')
if (!(root instanceof HTMLElement) || !(canvas instanceof HTMLCanvasElement)) {
throw new Error('차트 영역을 찾을 수 없습니다')
}
const controller = createChartController({
definition,
viewCapabilities: [{ axisID: 'date', minimumSpan: 86_400_000 }],
})
const revenueLabels = new Map(revenue.map(point => [
point.id,
`${point.date.toLocaleDateString()}: ${point.amount.toLocaleString()}`,
]))
const chart = createDOMChart({
root,
canvas,
controller,
renderer: 'auto',
accessibilityLabel: '주간 매출',
getAccessibleDatumLabel: id => revenueLabels.get(id) ?? String(id),
navigation: { wheel: 'native', keyboard: true },
})
window.addEventListener('pagehide', () => {
chart.disconnect()
controller.dispose()
}, { once: true })단일 페이지 앱에서는 pagehide를 기다리지 말고, 이 화면이나 컴포넌트를 제거할 때 같은 두 정리 함수를 호출하세요.
렌더러 선택하기
auto는 WebGL2를 쓸 수 있으면 사용하고, 그렇지 않으면 Canvas2D로 전환합니다. 대부분의 앱에는 이 기본값이 알맞습니다. 호환성 문제를 확인할 때는 canvas2d, 그래픽 가속을 쓸 수 없으면 앱이 실패해야 할 때는 webgl2를 선택하세요.
import { createChartRenderer } from '@sectile/dom/chart'
const renderer = createChartRenderer(canvas, {
mode: 'auto',
style: {
color: [0.18, 0.42, 0.86, 1],
pointRadius: 4,
lineWidth: 2,
},
})직접 만든 렌더러는 createDOMChart의 renderer 옵션으로 전달하고, 더 이상 쓰지 않을 때 renderer.disconnect()도 직접 호출합니다. 대신 'auto', 'canvas2d', 'webgl2' 문자열을 전달하면 차트 연결이 렌더러 생성과 정리를 맡습니다.
페이지 입력을 예측 가능하게 두기
기본값에서는 휠 입력을 페이지 스크롤에 남겨 두고 드래그, 두 손가락 확대·축소, 키보드 탐색을 끕니다. 차트에 필요한 입력만 켜세요. 드래그나 두 손가락 조작을 켤 때는 controlAlternative: 'built-in' 또는 'external'로 같은 동작을 수행할 수 있는 버튼도 제공해야 합니다.
프레임마다 그릴 양 제한하기
renderPolicy: {
type: 'adaptive',
minimumRenderScale: 0.5,
maximumRenderScale: 1,
frameBudgetMs: 12,
maximumRepresentatives: 100_000,
}그리기 항목 수는 대규모 데이터에 설명한 상세도 규칙을 따릅니다. 적응형 렌더링은 프레임 예산을 맞추려고 Canvas 해상도를 낮출 수 있지만 값, ID, 선택, 축의 표시 범위는 바꾸지 않습니다.
사용한 자원 정리하기
chart.disconnect()
controller.dispose()
renderer.disconnect() // 앱에서 직접 만든 renderer일 때만chart.disconnect()는 이벤트 리스너와 크기 관찰자를 제거하고, 대기 중인 프레임을 취소하고, 접근성 요소와 차트 연결이 만든 그래픽 자원을 해제합니다. 여러 번 호출해도 안전합니다.
