GITHUB
Recharts 라이브러리 사용해 차트를 그리기
BLOGProject
Seohyun
Develop
30 Sep 2023
Recharts 라이브러리 사용해 차트를 그리기

이번에 맡은 프로젝트에서 데이터를 효과적으로 보여주기 위해 시각적인 효과로 차트가 포함되어 있었습니다. 여러 차트 라이브러리를 서치해보다가 Recahrts 라이브러리를 사용하기로 했습니다.

Recharts 라이브러리를 선택한 이유

1. 원하는 그래프가 존재함

  • 차트 라이브러리를 선택할 때 가장 고려한 사항이었습니다. 제가 필요한 차트는 시간에 따른 값의 변화를 나타내기 위한 Line Chart, 누적 그래프를 한 눈에 볼 수 있게 나타내기 위한 Stacked Bar Chart를 표현해야 했습니다.

2. 쉬운 커스텀

  • 차트의 범례를 나타내는 legend나 차트에 마우스를 올렸을 때의 tooltip들을 General Components로 제공해 커스텀이 쉬웠습니다.

3. 공식 사이트의 친절함

  • 프로젝트의 요구 사항의 변동이 예상되어 다양한 그래프가 필요했고, 적용을 빨리 해야했던 상황을 바탕으로 했을 때 공식 사이트가 비교적 친절했습니다. API 뿐만 아니라 다양한 차트 예시들을 제공하고 있었습니다. 비록 Storybook은 운영하고 있지 않았으나, 설명이 잘 되어 있는 편이라 생각했습니다.

설치

먼저 Recharts 라이브러리를 사용하기 위해 저는 npm을 이용해 설치해주었습니다.

npm install recharts

Line chart

일단 chart를 그리기 위해 Line, LineChart를 import하고, x축, y축을 나타내기 위한 XAxis, YAxis를 import 합니다. CartesianGrid는 Line chart의 배경 grid를 나타내는 컴포넌트이며, 차트의 데이터를 자세히 설명하는 Tooltip, 차트의 범례를 나타내기 위해 Legend도 함께 import 하겠습니다.

import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
} from "recharts";

테스트를 위해 간단한 mock data를 작성하겠습니다.

const data = [
{
name: "A",
uv: 4000,
pv: 2400,
amt: 2400,
},
{
name: "B",
uv: 3000,
pv: 1398,
amt: 2210,
},
{
name: "C",
uv: 2000,
pv: 9800,
amt: 2290,
},
{
name: "D",
uv: 2780,
pv: 3908,
amt: 2000,
},
{
name: "E",
uv: 1890,
pv: 4800,
amt: 2181,
},
{
name: "F",
uv: 2390,
pv: 3800,
amt: 2500,
},
{
name: "G",
uv: 3490,
pv: 4300,
amt: 2100,
},
];


<LineChart /> 컴포넌트는 차트의 레이아웃 및 data를 주입하는 컴포넌트입니다. width, height로 차트 영역을 지정하고, data로 차트를 그릴 데이터를 주입합니다.

export default function App() {
return (
<LineChart
width={800}
height={500}
data={data}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5,
}}
></LineChart>
);
}


<Line /> : 나타낼 차트입니다. data의 dataKey를 입력해 표현하며, type을 통해 다양한 선의 형태를 표현할 수 있습니다. stroke를 통해 차트의 색을 설정할 수 있고, activeDot은 마우스를 hover했을 때의 원의 크기를 나타냅니다.

<Line
type="monotone"
dataKey="pv"
stroke="#FFAB0B"
activeDot={{ r: 8 }}
strokeWidth={2}
/>
<Line
type="monotone"
dataKey="uv"
stroke="#00A3FF"
strokeWidth={2}
/>

properties

<Tooltip />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />

차트 배경이 되는 점선을 표현하는 <CartesianGrid /> 컴포넌트로 strokeDasharray로 커스텀할 수 있습니다.

기본 Tooltip 외에도 커스텀 Tooltip을 사용할 수 있습니다.

return [dataMin, dataMin + 10000];
/>
<YAxis /> // domain={[0, "auto"]}
return [dataMin, dataMin + 10000];
/>

차트의 x축 <XAxis />, y축 <YAxis />을 나타냅니다. 예시에서는 data에서 name에 해당하는 key를 사용했습니다. domain={[0, 15000]}와 같이 domain을 통해서 나타내고자 하는 범위를 설정할 수 있습니다. default는 [0, ‘auto’]입니다. unit을 통해 축에 단위를 설정할 수 있습니다.

CartesianGrid_before

이와 같이 [dataMin, dataMax]를 통해 동적으로 범위를 설정할 수 있습니다.

domain_before

stacked bar chart

위에서 line chart를 통해 살펴보았으니, stacked bar chart는 빠르게 살펴보겠습니다.

import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
} from "recharts";
const data = [
{
name: "A",
uv: 4000,
pv: 2400,
},
{
name: "B",
uv: 3000,
pv: 1398,
},
{
name: "C",
uv: 2000,
pv: 9800,
},
{
name: "D",
uv: 2780,
pv: 3908,
},
{
name: "E",
uv: 1890,
pv: 4800,
},
{
name: "F",
uv: 2390,
pv: 3800,
},
{
name: "G",
uv: 3490,
pv: 4300,
},
];
export default function App() {
return (
<BarChart width={500} height={300} data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis domain={[0, 20000]} />
<Tooltip />
<Legend />
<Bar dataKey="pv" stackId="a" fill="#8ecae6" />
<Bar dataKey="uv" stackId="a" fill="#43AA8B" />
</BarChart>
);
}

stacked bar chart는 데이터 항목을 누적해 한 눈에 파악할 수 있습니다.


2023-09-25-2

Responsive

  • 반응형이 기본인 Web에서 차트도 예외일 순 없습니다. Recharts 라이브러리에서는 ResponsiveContainer를 통해 반응형 차트를 나타낼 수 있습니다. width와 height 중에 하나는 반드시 퍼센트의 string 형태로 props를 전달해야 합니다. 이 외에도 minWidth, minHeight, debounce 등 properties가 있습니다.

전체 코드

const chartData = fetchData?.chart?.map((data) => {
return {
time: dayjs(data.time).format("YYYY-MM-DD HH:mm"),
ex_1: data.ex1,
ex_2: data.ex2,
ex_3: data.ex3,
ex_4: data.ex4,
};
});
<ResponsiveContainer width="100%" height={458}>
<LineChart
data={chartData}
margin={{
top: 30,
right: 80,
left: 40,
bottom: 40,
}}
>
<CartesianGrid strokeDasharray="2" vertical={false} />
<XAxis
dataKey="time"
label={{
value: "시간",
offset: 20,
angle: 0,
position: "right",
}}
tickMargin={5}
tickFormatter={(tickItem) =>
`${tickItem.split(":", 1).toString().slice(-2)}`
}
unit=""
/>
<YAxis
type="number"
domain={["auto", "auto"]}
unit="°C"
tickCount={11}
label={{
value: "°C",
offset: 15,
angle: 0,
position: "top",
}}
tickFormatter={(tickItem) => tickItem.toLocaleString()}
/>
<Tooltip content={<CustomTooltip />} />
<Legend wrapperStyle={{ bottom: 10, left: 70 }} height={40} />
<Line
type="monotone"
dataKey="ex_1"
stroke="#FFAB0B"
fill="#FFAB0B"
r={0}
strokeWidth={3}
activeDot={{ r: 6 }}
/>
<Line
type="monotone"
dataKey="ex_2"
stroke="#9747FF"
fill="#9747FF"
strokeWidth={3}
r={0}
activeDot={{ r: 6 }}
/>
<Line
type="monotone"
dataKey="ex_3"
stroke="#1FD694"
fill="#1FD694"
strokeWidth={3}
r={0}
activeDot={{ r: 6 }}
/>
<Line
type="monotone"
dataKey="ex_4"
stroke="#00A3FF"
fill="#00A3FF"
strokeWidth={3}
r={0}
activeDot={{ r: 6 }}
/>
</LineChart>
</ResponsiveContainer>;

결과

2023-09-25-3

Recharts 라이브러리를 사용하며 커스텀했던 사항들을 간단히 정리해보았습니다. 더 자세한 내용은 공식 사이트에서 API, Components에서 Parent Components, Child Components를 비롯해 Properties에서 다양한 기능들을 살펴볼 수 있습니다.

© 2024 Park Seohyun