thumbnail
[React] ApexCharts의 범례와 체크박스를 활용한 데이터 시각화 개선 방법
React / ApexCharts
2024.08.29.

1. 문제 파악

alt text

위 차트는 APEXCHARTS 라이브러리를 사용한 차트이다. 데이터 시각화를 위해 활용 중이지만, 라이브러리를 사용하다보니 원하는 시각화를 정확히 구현하기 어려울 수 있다.

위 예시에서는 선생님들의 수업에 대한 여러 평가 지표를 표현하는 차트인데, 딱봐도 한눈에 비교가 어렵다. APEXCHART의 단점이라고 생각하는데, 차트상 하나의 라인은 범례(Legend)에 사용하면 반드시 1:1 매칭이 되는 방식이다.

APEXCHART에서는 차트에 사용하는 데이터를 Series 라는 데이터 형식을 사용하는데, 이걸 라이브러리 자체의 기능으로 아무리 커스텀 해봐도 원하는 결과물을 만들기 어려웠다.

여러 지표를 보여주기 때문에 범례에서 제공하는 on/off (Toggle) 기능을 사용하면 유용하지만, 표현하는 라인들에 대한 각각의 범례가 다 표출되니 표현 데이터가 많아질수록 보기 어렵다는 단점이 생긴다.

(위 예시에서는 2개만 있지만 10명의 선생이 나타난다면..? 차트는 한순간에 미술작품으로 변할것이다 ㅋㅋ)


2. 해결방안 탐색

문제 해결을 위해 2가지 방식을 생각해보았다.

1. Series를 원하는 방식으로 변경
2. Custom Legend 만들기

2.1. Series를 원하는 방식으로 변경

Custom Legend 만들기 우선은 그래도 많이 사용되는 차트 라이브러리인데 Series 변경으로 나랑 비슷한 문제를 겪었을 누군가가 있었겠지 하는맘으로 시도해보았으나, 놀랍게도(?) 없었다. 이렇게 저렇게 시도해봤지만 원하는 결과를 얻지 못했다.

2.2. Custom Legend 만들기

그래서 2번 방식을 사용하게 되었다. 간단하게 체크박스로 지표들을 만들고 series 에 해당 지표들을 엮어주어서 toggle을 통해 on/off 를 구현하는 방식으로 하면 될 것이라고 생각했다.


3. 해결방안 적용

우선, 독자들을 위해 APEXCHART에서 사용하는 요소들을 간단히 정리해보겠다.

series 배열: 차트에 표시될 데이터 시리즈(Series)
legend: 차트 상단에 데이터 시리즈의 범례
options: 차트의 스타일과 동작을 설정하는 다양한 옵션

여기서는 legend가 각 데이터 시리즈를(지표별로) 구분하는 데 사용되었고, 차트의 xaxis와 yaxis는 날짜와 값을 기반으로 데이터를 시각화했다.

3.1. 기존 범례 숨기기

// 이전 코드
 legend: {
      position: 'top',
      horizontalAlign: 'left',
      labels: {
        colors: theme.palette.mode === 'light' ? 'black' : '#D5D5EA'
      }
    }

APEXCHARTS의 Options 부분에 기존 범례의 설정이 있다. 삭제하고 show 속성을 false로 해도되지만, 우선 남겨두고 보이지 않게만 처리하였다.

// 변경 코드
 legend: {
      position: 'top',
      horizontalAlign: 'left',
      labels: {
        colors: theme.palette.mode === 'light' ? 'black' : '#D5D5EA'
      }
      show: false
    }


3.2. 체크박스 필터 추가

체크박스에 필요한 상태를 useState()로 추가한다.

추가하는김에 아래에서 사용할 chartSeries도 추가한다.

// 추가 코드
const [visibleIndicators, setVisibleIndicators] = useState({
  출석율: true,
  지각율: true,
  흥미도: true,
  관심도: true,
})
const [chartSeries, setChartSeries] = useState([])

우선 표현 컴포넌트(차트) 상단에 체크박스 를 추가했다.

// 추가 코드
<Box mb={2}>
  {Object.keys(visibleIndicators).map(indicator => (
    <FormControlLabel
      key={indicator}
      control={
        <Checkbox
          checked={visibleIndicators[indicator]}
          onChange={handleCheckboxChange}
          name={indicator}
        />
      }
      label={indicator}
    />
  ))}
</Box>

그리고 handleCheckboxChange 함수를 구현한다.

// 추가 코드
const handleCheckboxChange = event => {
  const { name, checked } = event.target
  setVisibleIndicators(prev => ({
    ...prev,
    [name]: checked,
  }))
}

3.3. chartSeries 추가

useEffect 훅을 이용하여 checkbox가 변경될 때 series를 커스텀해서 chartSeries로 교체해준다.

useEffect(() => {
  const filteredSeries = series.filter(
    item => visibleIndicators[item.name.split(' - ')[0]],
  )
  setChartSeries(filteredSeries)
}, [series, visibleIndicators])

기존의 serires 대신 Custom 한 chartSeries 로 APEXCHART의 series를 교체해준다.

// 이전 코드
<ReactApexChart options={options} series={series} type="area" height={350} />
// 변경 코드
<ReactApexChart
  options={options}
  series={chartSeries} //변경
  type="area"
  height={350}
/>

4. 결론

변경내용을 적용하고나면 아래와 같이 보기좋게 차트가 바뀐다. 체크박스를 모두 체크하면 좀 난잡한건 어쩔수없지만

alt text


아래와같이 보고싶은 지표만 선택한다면 비교하기 용이해졌다.

alt text

Thank You for Visiting My Blog, Have a Good Day 😊
© 2024 JohnnySeo, Powerd By Gatsby. Contact : tjwhd6860@naver.com