개인 프로젝트를 하던 중 그래프로 데이터를 표시하고 싶었던 적이 있다. 캔버스와 데이터를 이용해서 직접 라인 그래프 등을 그릴 수도 있지만, 라이브러리를 이용해서 조금 더 깔끔하고 간편하게 그래프를 그리고 싶어 찾아본 결과 chart.js
를 사용하면 해결할 수 있을 것 같았다.
이 글에서는 간편하게 bar graph를 그리는 정도만 기록할 예정이다.
어느정도 그려보고 나니 간편하다는 생각은 들었지만, 처음 이 라이브러리를 사용하려 했을 땐 역시나 바로 그래프를 그려내기 어려웠다. chart.js
를 사용하기 위해서는 먼저 아래와 같이 사용하려 하는 controller
, element
, scale
과 plugin
을 import 후 register 해주어야 한다.
import { Chart, BarElement, BarController, CategoryScale, LinearScale, Title, Legend } from 'chart.js';
Chart.register(BarElement, BarController, CategoryScale, LinearScale, Title, Legend);
그 후 그리고자 하는 canvas
태그를 찾아 아래와 같이 그려주기만 하면 된다. 아래 코드에서 labels
, datasets
, text
값은 적절히 할당이 되어있는 상태라고 가정했다.
// JavaScript
const canvas = document.getElementById('chart-js');
const ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'bar', // bar graph
data: {
labels: labels, // label 배열
datasets: datasets, // datasets는 label, data, backgroundColor 등을 포함한 객체의 배열
},
options : {
plugins: {
title: {
display: true,
text: text, // text는 차트 제목
},
},
responsive: false, // 원하는 크기의 chart를 만들기 위해 false 할당
},
});
// html canvas 태그
<canvas id="chart-js">
React에서도 위와 동일한 방법으로 차트를 그릴 수는 있다. 다만, document.getElementById(), querySelector()
등의 메소드들은 React lifecycle과 함께 동작하지 못해 Dom Element의 신뢰도가 떨어지며, JavaScript - DOM 간의 의존성이 생기는 것을 피할 수 없다. 또한, DOM API는 Real Dom에 있는 요소를 가져오지만, React의 virtual DOM에 있는 요소가 더 신뢰도가 높기 때문에 useRef
를 사용하는 것이 더 바람직하다.
아래 코드는 React + TypeScript에서 Chart.js
를 사용하는 예시이다.
import { useRef, useState } from 'react';
import { Chart, BarElement, BarController, CategoryScale, LinearScale, Title, Legend } from 'chart.js';
const Chart = () => {
const [labels, setLabels] = useState<string[]>([]);
const [datasets, setDatasets] = useState<datasetsType[]>([]);
const chartRef = useRef<HTMLCanvasElement>(null);
Chart.register(BarElement, BarController, CategoryScale, LinearScale, Title, Legend);
const drawChart = (ctx: CanvasRenderingContext2D, text: string) => {
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: datasets,
},
options: {
plugins: {
title: {
display: true,
text: text,
},
},
responsive: false,
},
});
}
// labels, datasets, text 값을 할당하는 코드 / 로직
// drawChart() 함수를 호출하는 코드 / 로직
return <canvas width={600} height={800} ref={chartRef}></canvas>
}
// html canvas 태그
<canvas id="chart-js">
위와 같이 코드를 작성하면 여러 캔버스를 이용하여 drawChart()
함수를 호출하기만 하면 여러 개의 차트를 간편하게 그릴 수 있다는 장점이 있다.
React에서의 querySelector, 잘 쓰고 있는 걸까?(feat. Ref)
chart.js 공식 문서