간단한 시각화 차트를 만들 수 있는 라이브러리를 찾다가 리액트에서 개발된 라이브러리인 Recharts를 사용해보기로 했다.
https://recharts.org/
공식문서의 가이드와 예제 코드를 보면서 작업하면 된다!
$ npm install recharts
area chart와 bar chart를 동시에 보여주는 composed chart가 필요했다.
차트 종류는 API 메뉴에서 확인할 수 있다.
내리다 보면 차트에 있는 속성이 뭐가 있는지에 대한 자세한 설명이 있다.
부모/자식 컴포넌트에 올 수 있는 것들과 관련 속성들은 어떤 게 있는지 default 값을 확인하면서 필요한 것들을 커스터마이징 할 수 있다.
Property
General Components
<ResponsiveContainer width={700} height="80%">
<AreaChart data={data}
margin={{ top: 20, right: 30, left: 0, bottom: 0 }}>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />
<ReferenceLine x="Page C" stroke="green" label="Min PAGE" />
<ReferenceLine y={4000} label="Max" stroke="red" strokeDasharray="3 3" />
<Area type="monotone" dataKey="uv" stroke="#8884d8" fill="#8884d8" />
</AreaChart>
</ResponsiveContainer>
label : 직교 좌표의 보기 상자에 있는 위치(말이 너무 어렵다..)
- value : Label의 자식으로 지정할 수 있는 레이블의 값
- offset : 지정된 위치에 대한 오프셋
- position : view box를 기준으로 한 레이블의 위치
- angle : 축의 value 값의 각도
<BarChart
width={730}
height={250}
data={data}
margin={{ top: 15, right: 30, left: 20, bottom: 5 }}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name">
<Label value="Pages of my website" offset={0} position="insideBottom" />
</XAxis>
<YAxis label={{ value: 'pv of page', angle: -90, position: 'insideLeft' }} />
<Bar dataKey="pv" fill="#8884d8">
<LabelList dataKey="name" position="top" />
</Bar>
</BarChart>
Cell : 파이, 막대 또는 방사형 막대로 감싸서 각 자식의 속성을 지정할 때 사용
<BarChart width={730} height={250} data={data}>
<Bar dataKey="value">
{
data.map((entry, index) => (
<Cell key={`cell-${index}`} stroke={colors[index]} strokeWidth={index === 2 ? 4 : 1}/>
))
}
</Bar>
</BarChart>
import {
Area,
Bar,
XAxis,
YAxis,
Tooltip,
CartesianGrid,
ComposedChart,
Legend,
ResponsiveContainer,
Cell,
} from "recharts";
const Chart = ({ district, handleClickFiltering }) => {
const { data } = useChartData();
return (
<>
<ResponsiveContainer width="100%" height={500}>
<ComposedChart
data={data}
margin={{ top: 40, right: 40, bottom: 40, left: 40 }}
>
<CartesianGrid stroke="#efefef" />
<XAxis dataKey="time" />
<YAxis
label={{
value: 'area',
angle: -90,
position: 'insideLeft',
offset: -10
}}
yAxisId="left"
domain={[0, 300]}
/>
<YAxis
label={{
value: 'bar',
angle: 90,
position: 'insideRight',
offset: -10
}}
yAxisId="right"
orientation="right"
/>
<Tooltip />
<Legend />
<Bar
dataKey="value_bar"
barSize={20}
fill="#7ac4c0"
yAxisId="right"
>
{data.map((item, idx) => (
<Cell
key={`cell-${idx}`}
fill={`${item.id === district ? `#3ea09b` : `#3e91a07b`}`}
/>
))}
</Bar>
<Area
dataKey="value_area"
type="monotone"
fillOpacity={0.4}
fill="#ff7300"
stroke="#ff7300"
yAxisId="left"
/>
</ComposedChart>
</ResponsiveContainer >
</>
)
};
export default Chart;
area 차트가 bar차트 앞에 위치해 있는데, bar를 클릭했을 때 필터링을 구현해야 하는 요구 사항이 있었다.
근데 bar를 클릭하면 되는데, area와 겹쳐진 bar 부분은 클릭이 안되서 한참을 찾다가 겨우 발견했다.
area차트에 pointerEvent 속성을 없애주어야 한다.
pointerEvents='none’
그래서 area 차트는 hover 이벤트를 제거해서 bar만 클릭되도록 설정해주었다.
공식문서에 있는 예제 코드를 참고하였다.
추가로, 코드를 일일히 작성하지 않고 storybook에서 미리 적용해보고 코드로 작성할 수도 있어 여기서 이것저것 테스트 해보고 작성하는 것을 추천한다!