- 현재 존재하는 차트 관련 라이브러리들은 여러개가 있지만 그 중에서 제일 인기가 많고 또 레퍼런스도 많으며 무엇보다 공식문서가 잘 정리되어 있는 chart.js를 사용하기로 했다.
- 특징
- CANVAS 베이스로 빠른 렌더링
- 오픈소스 무료 제공이지만 지속적인 유지보수와 새로운 버전 출시
- 초보자도 쉽게 사용할 수 있을정도로 잘 정리된 문서
- 정말 작은 라이브러리 용량 (713 byte)
- 매우 적은 메모리 사용
사용 방식
- 내가 사용한 chart.js의 방식은 컴포넌트 내부에 chart 컴포넌트들을 따로 만들고 그 컴포넌트에 필요한 정보들(labels, data)들을 props로 전달해 렌더링하는 방식이다.
- 여기서 labels는 가로축, data는 세로축을 의미한다.
- 나의 경우 각 이벤트 마다 서버로부터 데이터를 받는데 그 데이터들을 json으로 받기로 하였다.
기본 구조
import styled from "styled-components";
import { Line } from "react-chartjs-2";
import { Chart as ChartJS } from "chart.js/auto"; //미사용하지만 안적어주면 오류남
const Chart001 = ({ customerGraph }) => {
const chartData001 = {
labels: customerGraph.labels,
datasets: [
{
type: "line",
label: "Dataset 1",
borderColor: "#1b1111",
borderWidth: 2,
data: customerGraph.data,
},
],
};
const chartOptions001 = {
}
return (
<Container>
<Line
type="line"
data={chartData001}
options={chartOptions001}
width="450px"
/>
</Container>
);
};
export default Chart001;
const Container = styled.div`
height: 200px;
width: 100%;
display: flex;
justify-content: center;
`;
- return 먼저 살펴보면 container는 기본적인 css이므로 패스하고
- 우선 Line인지 Bar인지 Doughnut인지 등의 정보를 import한 컴포넌트로 표현한다.
- 이후 내부의 속성으로는 크게
- type
- line인지 bar인지 doughnut인지 표시
- data
- options
- 가 있다.
ChartData
- 우선 ChartData는 크게 labels와 datasets로 나뉘는데
- labels는 가로축의 정보들을 배열로 받고
- datasets의 경우 세로축(그래프)들을 배열로 받는다.
- 단, 여기서 주의할 점은 datasets의 경우 먼저 그래프들을 받는다는 말이다.
- 즉, 보통은 그래프를 한 개 그릴텐데 그러면 datasets의 배열의 길이는 1이 되어야 한다.
- 그래프를 2개 그린다면 2가 된다.
- 그리고 datasets배열의 원소는 객체로 이루어져 있으며 그 객체 내부의 data가 그 그래프의 진짜 세로축의 정보들이며 이것 또한 배열로 받는다.
ChartOption
- 정말 여러가지 옵션들이 있으며 이 부분을 얼마나 잘 다루느냐가 chart.js를 얼마나 잘 다루느냐를 결정한다 해도 과언이 아니다.
responsive
- 차트의 크기를 직접 조절할건지를 묻는 옵션이다.
- true이면 라이브러리 설정, false면 직접 설정이다.
- 차트의 크기를 조절하는 것은 매우 까다로웠기 때문에 개인적으로는 true로 하고 대신 inline으로 width, height의 길이를 조절하는 것도 좋다고 생각한다.
plugin
- 차트의 기본 동적을 커스텀하는 가장 효율적인 방법이다.(라고 공식문서에 써있다..)
- 여기서 내가 처음으로 많이 해매였는데 내가 해야할 기획에는 그래프마다 그래프의 범례를 표시하지 않아야 했다.
- 하지만 chart.js는 범례를 기본적으로 표시한다.
- 이 경우 우리는 따로 그 설정을 꺼줘야 범례를 표시하지 않게 할 수 있다.
- 그 방법은 plugins의 legend의 display속성을 false하는 것이다.
const chartOptions001 = {
plugins: {
legend: {
display: false,
},
},
- 이런 방식은 chart.js의 다른 속성들에도 동일하게 적용된다.
- 따라서 새롭게 표시하지 않아야 하는 chart.js의 기능이 있다면
- 그 기능의 이름을 찾는다.
- 그 기능의 display(혹은 enabled, duration)를 false(또는 0)로 한다.
- 를 염두해 두어야 한다.
tooltip
- 차트에 마우스를 호버했을 때 나오는 창을 뜻한다.
tooltips: {
displayColors: false, // 툴팁 바 컬러 표시 여부
backgroundColor: '#0a6dff', // 툴팁 배경
titleFontColor: '#fff', // 툴팁 폰트 관련
titleAlign: 'center', // 툴팁 폰트 관련
bodySpacing: 2, // 툴팁 폰트 관련
bodyFontColor: '#fff', // 툴팁 폰트 관련
bodyAlign: 'center', // 툴팁 폰트 관련
footerFontStyle: 'bold', // 툴팁 폰트 관련
footerFontColor: '#fff', // 툴팁 폰트 관련
footerAlign: 'center', // 툴팁 폰트 관련
callbacks: {
label: function(tooltipItem, data) {
return data['labels'][tooltipItem['index']] + ": " + data['datasets'][0]['data'][tooltipItem['index']];
},
}
},
- 보통 평균적으로는 위처럼 사용한다.
- 기존 css하듯이 스타일링하면 되지만 그 중 좀 특이한 부분은
font
bodyFont: {
font: {
family: "'Noto Sans KR', sans-serif",
},
},
callback
- 실제로 나오는 tooltip의 데이터를 정한다.
- 보통 title과 label로 나뉘는데
- 전달받는 객체의 method를 통해 정리한다.
callbacks: {
title: context => context[0].label,
label: context => {
let label = context.dataset.label + "" || "";
return context.parsed.y !== null
? label + ": " + context.parsed.y + "배"
: null;
},
},
다음에는?
- chart.js의 scale속성을 이용해서 두 개의 데이터 하나의 그래프에 그리기이다.