Chart.js를 사용해서 반응형으로 한 차트에 막대 그래프 2개를 렌더링 시켜보겠습니다.
react에서 사용하려면 react-chartjs-2도 설치가 필요합니다.
npm install react-chartjs-2 chart.js
기본적으로 차트가 그려질 컴포넌트.
컴포넌트로 선언할 수 있는 것들은 react-chartjs-2 공식사이트에서 확인할 수 있습니다.
<Bar data={data} options={options} />
<Doughnut data={data} options={options} />
<Chart type={...} options={...} data={...} /> //type을 넘겨주면 Chart 컴포넌트로 모든 타입의 차트사용 가능(multiple 타입 시 주로 사용)
import { ChartData } from 'chart.js';
const data: ChartData<'bar'> = {
labels: ['1번', '2번', '3번'], // 해당 바에 해당하는 라벨
datasets: [
{
label: '정답률',
type: 'bar',
data: [80, 20, 40],
backgroundColor: param.correctRate?.map((data) =>
if (data === min && data === max) return REPORT_COLORS.FIVE_PRIMARY;
return REPORT_COLORS.THREE_PRIMARY), //조건부로 다른 색상으로 랜더링 가능
// barThickness: 20, //두께 픽셀로 지정
barPercentage: 0.5, //두께를 비율로 지정 최대 1
borderRadius: 20, // 모퉁이 둥글리기
borderSkipped: 'bottom', // 하단 양끝은 둥글리기 생략
},
{
label: '평균시간',
type: 'bar', //type이 두가지가 다를 경우 다르게 선언할 수 있음 (생략가능)
data: [100, 210, 350],
backgroundColor: REPORT_COLORS.FIVE_PRIMARY,
yAxisID: 'yRight', //두가지 바가 있을 경우 y축ID 선언 option 설정 시 사용됨.
barPercentage: 0.5,
borderRadius: 20,
borderSkipped: 'bottom',
},
],
});
labels - 각 막대(bar)의 이름입니다.
datasets - 이 차트에 그릴 데이터 집합으로, '정답률', '평균시간' 데이터를 선언했습니다.
ChartData<'bar'>
로 선언하여 타입 안전성을 높여줍니다. 또한 데이터 수정 시 많은 옵션 값들을 파악하기 용이합니다. yAxisID: 'yRight'
를 선언하였습니다. import { ChartOptions } from 'chart.js';
const chartOptions: ChartOptions<'bar'> = {
responsive: true, //반응형 처리
maintainAspectRatio: false, //기본 비율(가로:세로 비율)을 유지 X
plugins: {
legend: {
display: false,
},
},
scales: {
x: {
grid: {
drawTicks: false,
},
ticks: {
padding: 10,
font: {
size: 16,
weight: 'bold',
family: fontFamily[0],
},
color: REPORT_COLORS.BW_767676,
},
},
y: {
grid: {
display: false,
},
min: 0,
max: 100,
ticks: {
callback: function (value) {
return value + '%';
},
stepSize: 20,
font: {
size: 16,
weight: 600,
family: fontFamily[0],
},
color: REPORT_COLORS.BW_A3A3A3,
align: 'start',
},
},
yRight: {
min: 0,
max: 360, //최대 5분, 그외는 6분이상으로 처리
position: 'right', // 오른쪽에 배치
grid: { drawTicks: false },
ticks: {
padding: 10,
callback: function (value) {
return Math.round(Number(value) / 60) < 6
? `${Math.round(Number(value) / 60)}m`
: '6m ↑'; //초단위 데이터를 분으로 변경
},
stepSize: 60, //스텝당 60초씩 계산되도록
font: {
size: 16,
weight: 'bold',
family: fontFamily[0],
},
color: REPORT_COLORS.BW_A3A3A3,
align: 'start',
},
},
},
};
{ responsive: true, maintainAspectRatio: false, }
위의 두 옵션을 줘야 상단 부모에서 높이를 고정하고 width를 100%로 주면 좌우로 아무리 브라우저를 늘였다 줄였다 해도 width를 다채우는 그래프를 그릴 수 있습니다.
maintainAspectRatio를 true로 줄 경우 브라우저를 줄였을때는 비율에 맞게 줄어들지만 다시 브라우저를 늘려도 크기가 같이 커지지않는 문제가 발생하므로 높이를 고정하고 좌우 반응형으로 구현했습니다.
position: 'right'
옵션을 줘서 오른쪽에 배치시켰습니다. align: 'start'
로 y축 눈금(tick) 레이블의 정렬 방향을 왼쪽으로 붙도록 정의했습니다. chart.js에서 필요한 것들을 import 해온 후 register를 해야 차트를 렌더링 할 수 있습니다.
(ChartJS.register(...)를 빼먹으면 차트가 아예 안 나와요.)
import {
ChartData,
Chart as ChartJS,
ChartOptions,
LineElement,
Tooltip,
} from 'chart.js';
ChartJS.register(LineElement, Tooltip);
필요한 것들을 register에 등록하지 않은 경우 차트가 렌더링되지 않으면 콘솔에러가 나오므로 확인 후 필요한 요소들을 추가해주시면 됩니다!
이러한 과정을 거치면 위 이미지에 해당하는 그래프를 만들 수 있습니다 🥰
참고링크
https://www.chartjs.org/docs/latest/charts/bar.html
https://react-chartjs-2.js.org/components/