FrontEnd
[React+TS] apexcharts 차트 고도화 예시(Pie)
mingg123
2023. 6. 30. 15:51
프로젝트에서 apexcharts라는 라이브러리르 사용하고 있다.
우선 사용하기가 쉽고, 공식문서가 굉장히 친절하다. 그냥 type='pie' 'bar' 이런식으로 차트의 종류를 선택해서 쓸 수 있다.
커스텀을 엄청나게 빡세게 하지않아서 그런지 아직은 사용하는데 불편함이 없었다.
보통 통계 부분을 시각화를 많이해서 사용하는데,
조금이라도 더 유저가 친환경적으로 데이터를 확인할 수 있도록 차트를 고도화 한 기획에 대해서 작성하려고 한다.
매출액 파이 차트
수정 전
모든 상품별 매출액을 파이차트로 보여줌
상품의 종류가 매우 많아지거나, 상품금액이 상대적으로 작은 경우에는 사실상 원하는 데이터를 한눈에 파악하기가 힘들다.
수정 후
사용자가 보고싶은 상품을 선택하고, 선택한 상품에 따라 파이차트를 그려준다.
React + MUI5 + react-apexcharts 예시이다.
import { useEffect, useMemo, useState } from 'react';
import ReactApexChart, { Props as ChartProps } from 'react-apexcharts';
import { boardColorSelectionsMap, chartColorArray } from '@kinderlabs-pos/shared-data-type';
import { Box, Checkbox, Stack, Typography } from '@mui/material';
// values = {key: '이용권', value: 10000};
type ValueType = {
key: string;
value: number;
};
export const ApexPieChart = ({ values }: { values: ValueType[] }) => {
const [selectedLabels, setSelectedLabels] = useState<string[]>([]);
const colorArray = ['red', 'blue', 'pupple', 'green'];
// 초기 선택 값
const SHOW_COUNT = 7;
useEffect(() => {
const selectLabels = values.slice(0, Math.min(SHOW_COUNT, values.length)).map((val) => val.key);
setSelectedLabels(selectLabels);
}, [values]);
const handleLabelChange = (label: string) => {
setSelectedLabels((prevLabels) => {
if (prevLabels.includes(label)) {
return prevLabels.filter((prevLabel) => prevLabel !== label);
} else {
return [...prevLabels, label];
}
});
};
const filteredValues = useMemo(() => {
return values.filter((val) => selectedLabels.includes(val.key));
}, [selectedLabels]);
const series = useMemo(() => {
return filteredValues.map((val) => val.value);
}, [filteredValues]);
const options = useMemo(() => {
return {
colors: colorArray.filter((_, idx) => idx < filteredValues.length),
labels: filteredValues.map((val) => val.key),
xaxis: {
labels: {
style: {
colors: filteredValues.map((val) => 'blue'),
},
},
},
yaxis: {
labels: {
style: {
colors: ['blue'],
},
},
},
grid: {
borderColor: 'black',
},
legend: {
labels: {
colors: 'grey.500',
},
},
stroke: {
colors: ['white'],
},
responsive: [
{
breakpoint: 450,
chart: {
width: 280,
height: 280,
},
options: {
legend: {
show: false,
position: 'bottom',
},
},
},
],
};
}, [filteredValues]);
return (
<Stack direction={'row'}>
<ReactApexChart
width={500}
options={{ ...options, legend: { show: false } }}
series={series}
type='pie'
/>
<Stack spacing={0.2}>
{values.map((val) => (
<Stack
direction={'row'}
alignItems={'center'}>
<Box
width={25}
height={25}
sx={{ backgroundColor: colorArray, borderRadius: 1 }}
/>
<Checkbox
checked={selectedLabels.includes(val.key)}
onChange={() => handleLabelChange(val.key)}></Checkbox>
<Typography> {val.key}</Typography>
</Stack>
))}
</Stack>
</Stack>
);
};
우측에 체크박스와 라벨은 라이브러리 내에 파이차트를 저런식으로 커스텀할 수 있는건 존재하지 않아서 내가 따로 컴포넌트로 만들었다.
Line차트랑 계속 추가 예정이다.