FrontEnd

[React+TS] apexcharts 차트 고도화 예시(Pie)

mingg123 2023. 6. 30. 15:51

프로젝트에서 apexcharts라는 라이브러리르 사용하고 있다. 

 

https://apexcharts.com/

 

ApexCharts.js – Open-Source HTML5 JavaScript Charts

See it in action Below is a code snippet to show a glimpse of how easy it is to create interactive charts.

apexcharts.com

우선 사용하기가 쉽고, 공식문서가 굉장히 친절하다.  그냥 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차트랑 계속 추가 예정이다.