halang-log
💻 Frontend

Chart.js를 이용해 그래프를 만들어보자 - moment.js를 이용해 labels 만들기

date
Sep 8, 2022
slug
chartjs-with-momonetjs
author
status
Public
tags
Chart.js
moment.js
summary
Chart.js를 이용해 그래프를 만들어보자
type
Post
thumbnail
category
💻 Frontend
updatedAt
Nov 22, 2023 12:50 AM
언어
 
notion image
 

개요

현재 SW마에스트로에서 진행하고 있는 프로젝트에는 마이페이지에 통계 부분이 있습니다. 여기서 Day, Week, Month 별로 데이터를 보여주어야 합니다. Chart.js 라이브러리를 사용해 이를 구현하고자 합니다. 이번 포스팅에서는 labels 설정 위주로 진행해보도록 하겠습니다.

설치

chart.js 뿐만 아니라 리액트에서 chart.js를 렌더링하기 위해 필요한 react-chartjs-2도 설치를 해야 합니다.
npm install react-chartjs-2 chart.js yarn add react-chartjs-2 chart.js
react-chartjs-2 문서에 있는 예제 를 참고하여 만들었기 때문에 faker 라이브러리도 설치해 주었습니다.
npm install --save-dev @faker-js/faker yarn add @faker-js/faker
labels를 좀 더 편하게 보여주기 위해 moment.js 를 사용하였습니다.
npm install moment --save yarn add moment

구현

구현 방법은 어렵지 않습니다. 우선 labels 배열을 만드는 방법부터 설명드리겠습니다.
(labels는 빈 배열입니다.)

Day

'오늘'을 기준으로한 29일 이전 ~ '오늘' 까지의 데이터를 보여줍니다.
for (let i = 29; i >= 0; i -= 1) { labels.push(moment(moment(now).subtract(i, 'days')).format('M월 D일')); }

Week

'오늘'을 기준으로한 6일 이전 ~ '오늘' 까지를 마지막 주차로 설정합니다. 즉, 최근 일자부터 7일씩 잘라 1주로 설정합니다.
이렇게 최근 7주간의 데이터를 보여줍니다.
temp 변수를 이용한 이유는 겹치는 일이 없게 하기 위함입니다. (예를 들어, 1월 1일 ~ 1월 7일 다음 주차는 1월 7일이 아닌 1월 8일부터 시작하기 위함)
let temp = 0; for (let i = 48; i > 0; i -= 7) { const last = moment(now) .subtract(i + 6 - temp, 'days') .format('M월 D일'); labels.push( moment(now) .subtract(i - temp, 'days') .format(`${last} ~ M월 D일`), ); temp += 1; }

Month

최근 12개월간의 데이터를 보여줍니다.
for (let i = 11; i >= 0; i -= 1) { const month = moment(now).subtract(i, 'months').format('YYYY년 M월'); if (month.split(' ')[1] === '1월') { labels.push(month.split(' ')[0]); } else { labels.push(month.split(' ')[1]); } }

Chart 그리기

리액트로 chart를 그리는 방법은 다음과 같습니다.
차트 컴포넌트 - 리액트에서는 컴포넌트로 차트를 그릴 수 있습니다.register - 차트를 그리는 데에 필요한 것들을 import 한 후 register 해야 합니다.option - 다양한 option과 plugin을 통해 차트를 커스텀 할 수 있습니다.
저는 추이를 보다 잘 표현하기 위해 line graph를 사용하였습니다.
import React from 'react'; import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, } from 'chart.js'; import { faker } from '@faker-js/faker'; import { Line } from 'react-chartjs-2'; import { calculateLabels } from './calculateLabels'; ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ); const options = { responsive: true, plugins: { title: { display: false, }, legend: { display: false, }, }, interaction: { mode: 'index' as const, intersect: false, }, }; export default function Chart({ type }: { type: string }) { const labels = calculateLabels(type); const data = { labels, datasets: [ { fill: true, data: labels.map(() => faker.datatype.number({ min: 0, max: 1000 })), borderColor: '#F4C952', backgroundColor: '#e9c76b', }, ], }; return <Line options={options} data={data} width="894px" height="320px" />; }
options 에 대해 좀 더 설명드리겠습니다.
  1. responsive
    1. 차트를 반응형으로 만드는지에 대한 여부를 나타냅니다. true로 설정하면 차트의 비율이 container에 맞춰 유연하게 조절됩니다.
  1. plugins
    1. plugins은 차트의 기본 동작을 사용자 지정하거나 변경할 수 있습니다. 저는 title과 legend를 안보이게 설정해 주었습니다.
  1. interaction
    1. 차트에 마우스를 hover했을 때 생기는 interaction을 설정합니다. intersect를 true(default 설정)로 하면 직접 커서를 올려야 보이고 false로 하면 근처에만 올려도 보입니다.
      mode에 관한 것은 이 사이트를 참고하시면 될 것 같습니다.
이 외에도 아래 공식사이트에서 추가적인 내용들을 확인할 수 있습니다.