데이터 시각화는 데이터를 이해하고 분석하는데 중요한 역할을 하게 된다.
내가 담당한 탄소 계산기의 경우 이러한 데이터 시각화가 매우 중요한 파트라는 생각이 들었다.
직접 구현을 해볼까 아니면 라이브러리를 사용해볼까 고민을 하다가 시간적인 여유가 부족했기도 했고, 시각화에 대한 부분은 아무래도 라이브러리가 더 잘 되어있을 것이기에 이번 기회에 캠프 기간 잘 사용해보지 않았던 라이브러리를 사용해보기로 했다.
1. 리액트 기반 차트 라이브러리 비교
인기가 많은 몇가지 무료 차트 라이브러리를 보았었다.
Recharts :
- 웹 개발자가 가장 많이 사용하는 차트 라이브러리 중 하나
- 적당한 커스텀이 가능
- 모든 차트 유형을 제공하지는 않음
- 사용이 비교적 쉽고 간단
React-chartjs-2
- 혼합 차트 구성 가능
- Ui가 단순하고 대중적
- 간단한 차트 구현에 적합
- 샘플코드 자체가 tsx 코드
Nivo
- 디자인이 깔끔함
- 공식 문서에서 직접 테스트 가능
- 혼합 차트 제공하지 않음
이 세가지로 고민을 하던 와 중 혼합 차트 사용이 가능한 React-chartjs-2가 끌렸다.
한 차트에서 바 형식과 라인 형식을 사용해야하는 와이어프레임을 봤기 때문에 최적이지 않을까 싶었다. (작업 도중 라인이 빠지긴 했다.. ㅎㅎ)
그래서 결국 HTML 5 컨버스를 사용해 다양한 종류의 차트를 그릴 수 있는, 간단하고 유연한 차트 라이브러리인 Chart.js를 사용해보기로 했다.
설치하기
리액트에서 사용하기 위해선 2가지(+1)를 설치해야한다.
`react-chartjs-2` : Chart.js를 React에서 사용할 수 있도록 도와주는 라이브러리
`chart.js` : 기본 차트 라이브러리
`chartjs-plugin-datalabels` : 차트에 라벨을 붙이기 위한 플러그인
yarn add react-chartjs-2 chart.js chartjs-plugin-datalabels
npm install react-chartjs-2 chart.js chartjs-plugin-datalabels
ThisMonthChart 컴포넌트 구현하기
import 부분
- 라이브러리의 다양한 구성 요소
import React from "react";
import { Bar } from "react-chartjs-2";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
} from "chart.js";
import ChartDataLabels from "chartjs-plugin-datalabels";
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
설정 부분
const ThisMonthChart: React.FC<ThisMonthChartProps> = ({
currentData,
totalAvgData,
lastData,
lastTotalAvgData
}) => {
const data = {
labels: ["지난 달", "이번 달"],
datasets: [
{
label: "평균 배출량",
data: [
lastTotalAvgData?.carbon_emissions || 0,
totalAvgData?.carbon_emissions || 0
],
backgroundColor: "#D9D9D9",
borderColor: "#D9D9D9",
borderWidth: 1
},
{
label: "나의 총 배출량",
data: [
lastData?.carbon_emissions || 0,
currentData?.carbon_emissions || 0
],
backgroundColor: "#5BCA11",
borderColor: "#5BCA11",
borderWidth: 1
}
]
};
`labels` : 차트에 표시될 레이블
`datasets` : 데이터 세트 정의 - 각종 데이터 값이나 데이터와 물리는 Label, css 등을 설정하는 부분
options 부분
const options = {
maintainAspectRatio: false,
responsive: true,
plugins: {
legend: {
position: "top" as const
},
title: {
display: true,
text: "탄소 배출량 비교"
},
datalabels: {
anchor: "end",
align: "end",
formatter: (value) => value.toFixed(2),
color: "#000",
font: {
weight: "bold",
size: 12
}
}
},
layout: {
padding: {
top: 20,
right: 20,
bottom: 20,
left: 20
}
}
};
maintainAspectRatio : 차트의 비율을 유지하는 옵션
responsice: 반응형 차트 지원
return 부분
return (
<div className="flex justify-center items-center w-full h-full">
<Bar
data={data}
options={options}
plugins={[ChartDataLabels]} // 플러그인 등록
/>
</div>
);
컴포넌트 사용하는 부분
useEffect(() => {
// 데이터 불러오기
loadUserAndFetchData(setUser, thisYear, thisMonth, setCurrentData);
loadTotalUsersData(thisYear, thisMonth, setTotalAvgData);
// 이전 달의 데이터 로딩
const previousYear = thisMonth === 1 ? thisYear - 1 : thisYear;
const previousMonth = thisMonth === 1 ? 12 : thisMonth - 1;
loadUserAndFetchData(setUser, previousYear, previousMonth, setLastData);
loadTotalUsersData(previousYear, previousMonth, setLastTotalAvgData);
}, [thisYear, thisMonth]);
...
<ThisMonthChart
currentData={currentData}
totalAvgData={totalAvgData}
lastData={lastData}
lastTotalAvgData={lastTotalAvgData}
/>
props로 여러 데이터들을 받아서 가지고 왔다.
참고로 아래와 같이 데이터가 총 4개가 필요하다
`currentData` : 이번달 내 데이터
`totalAvgData` : 이용자 평균 데이터
`lastData` : 저번달 내 데이터
`lastTotalAvgData` : 저번달 이용자 평균 데이터
(처음 작업할때 데이터를 이번달 내 데이터와 이용자 평균 데이터 이 2개만 가지고와서 작업하다가 왜 안되나 엄청 고생했던..ㅜㅜ)
그리고 밑에는 구현된 화면이다.
내일은 여기에 또 다른 에러들이 있었는데 그 해결 과정을 적어볼까 한다.
그리고... 1000시간 돌파... ㅎㅎ
'프론트엔드 > Next.js' 카테고리의 다른 글
[최종 프로젝트] 비슷한 두개의 컴포넌트를 효율적으로 사용하기 (0) | 2024.11.08 |
---|---|
[최종 프로젝트] React 함수, 매개변수: 가독성을 높이는 작은 습관 (0) | 2024.11.02 |
[최종 프로젝트] 연도, 월 selectbox 컴포넌트 만들기 (0) | 2024.10.31 |
회원가입 시 자동으로 세션 생성 문제 (Next.js & Supabase) (0) | 2024.10.19 |
Next.js에서 middleware.ts 사용 시 주의사항 (tsconfig.json 설정) (0) | 2024.10.17 |