Chart.js Rader 구현하기

Imnottired·2023년 5월 12일
0

Lessons Learned

목록 보기
5/6

이번에 오각형을 이용한 그래프를 만들 필요성을 느꼈다.

5가지로 평가 받는 데이터가 있다.
이것을 시각적으로 표현하여 한눈에 들어오게 하고 싶어서 사용하려고한다.

그리고 예전부터 그래프와 관련된 것을 한번쯤 해보고 싶었다.




yarn add react-chartjs-2 chart.js

을 먼저 해주어야한다.
chart.js는 그래프를 만드는 것을 도와주는 라이브러리이고,
React-chartjs-2는 이것을 간편하게 도와주는 라이브러리이다.
(라이브러리의 라이브러리)

react-chartjs-2


import { Bar } from 'react-chartjs-2';

            <Bar 
                data={data}
                width={300}
                height={200}
                options={options}
            />
import {StRadar} from 'react-chartjs-2';

  <StRadar>
        <Radar data={chartData} options={chartOptions} />
      </StRadar>

export default Graph;

(관련 없는 부분은 삭제하였다. 필요하다면 아래 하단 링크를 보면 확인할 수 있습니다.)

위처럼 간단하게 불러서 그에 맞는 데이터값을 넣어주어서 사용할 수 있다.

처음 이것을 설치하고 사용하려고 하였는데, 몇가지 오류가 나서 사용하지 못했다.
지금은 성공된 상태에서 보니 어떠한 것이 문제였는지 알 수 있었다.

내가 참고한 blog에서는 어디까지가 라이브러리이고(Radar), 어디까지가 본인이 만든 컴포넌트(StRadar)인지 정의하지 않았고 이부분이 헷갈려서 되지 못했다.

아마 나는 시작과 동시에 많은 정보가 들어와서 그것을 올바르게 분간하지 못했던 것 같다.

많은 오류들과 정보들로 인해서 혼잡스러웠고, react-chartjs-2를 사용하지 못하였다.
(다음에 쓰게 된다면 이 라이브러리를 설치해서 간단하게 사용할 수도 있을 것 같다)

바로 chart.js 공식 홈페이지를 들어갔다.

Chart.js

위 공식 홈페이지 들어가면 Radar라는 형식의 차트가 있다.
이는 갯수의 맞춰 n각형을 만들고 2가지의 데이터도 비교할 수 있다.
(나중에 비교하는 것을 만들면 효율적일 것 같다.)

위 공식문서에 내용들을 보면 React에 맞추어서 작성되어진 내용은 없었고,
순수 자바스크립트에 맞추어진 내용들로 이루어져있었다.

그래서 바닐라 자바스크립트에 맞추어서 리액트로 수정해야했다.
이러한 과정은 까다로웠고 시간적인인 소모가 필요해보였다.
비슷한 상황을 카카오맵에서 겪었는데, 그때와 같은 방법으로 예시를 참고하기로 하였다.
인터넷에 예시를 검색하고 사용한 예시를 보고 그것을 참고하여서 사용하기로 하였다.

운이 좋게도. next.js에서 사용한 chartjs 예시를 찾을 수 있었고, 그를 바탕으로 작성하였다.
(https://codesandbox.io/s/l6qs1?file=/pages/index.js)

chart.js 예시

위를 보면 id를 받아와서 사용하는데 이를 Ref로 대처할 것이고,
그것을 바탕으로 차트를 할당해줄 것이다.

적용


  const canvasRef = useRef<HTMLCanvasElement>(null);

    <canvas
      ref={canvasRef}
      id="chart"
      aria-label="chart"
      height={350}
      width={580}
    />
    

그 이후에 useEffect를 사용하여서 한번만 생성하도록 할 것이다.

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) {
      return;
    }

    const ctx = canvas.getContext("2d");
    if (!ctx) {
      return;
    }
        chartRef.current = new Chart(ctx, {
     //생략
    });

      return () => {
      if (chartRef.current) {
        chartRef.current.destroy();
      }
    };
      }, [data]);
      

위처럼 canvas가 null로 시작하기때문에 null을 제거해주고
이후에 ctx에 2d를 할당해준다.
new Chart 첫번째 인자로 ctx를 할당해주고 이후 2번쨰 인자에 이 그래프에 대한 조건을 담는다.

또한 useEffect의 인자로 data를 넣었기때문에 그래프가 여러개 생기는 것을 막기 위해 return 값으로 cleanup(화살표) 함수를 넘겨주었다.

먼저 완성된 이미지를 보여주고 세부적인 것에 대해 정리하겠다.

    chartRef.current = new Chart(ctx, {
type: "radar",
      data: {
        labels: ["집내부", "건물/단지", "교통", "치안", "생활 및 입지"],
        datasets: [
          {
            label: "만족도",
            data,
            backgroundColor: "rgba(255, 96, 0, 0.2)",
            borderColor: "rgba(255, 108, 61, 1)",
          },
        ],
      },

chart의 2번째 인자로 상세한 데이터를 넘겨주는데,
type을 통해 그래프를 정하고, data에는 그래프의 카테고리와 그래프의 제목을 정해줄 수 있다.
그리고 datasets에서는 그래프의 색깔만 추가할 수 있다.(폰트 변경은 되지 않는다)

옵션 카테고리

options: {
		1번 옵션
        responsive: false,
        elements: {
          line: {
            borderWidth: 3,
          },
        },

먼저 responsive는 반응형 여부이다.
2번째는 borderwidth는 그래프 선의 굵기이다.
responsive를 true, borderwidth를 12 정도로 크게 넣으면

위와 같이 커지고, 선이 굵어진다.

        2번 옵션
        scales: {
          r: {
            suggestedMin: 0,
            suggestedMax: 5,
            pointLabels: {
              font: {
                size: 12,
                weight: "bold",
                family: "Pretendard-Regular",
              },
            },
          },
        },

scales에 r은 범위를 의미한다.
pointLabels의 font는 라벨 카테고리를 의미한다.
min max를 0~100으로 font를 50으로 키우면


한번에 무엇인지 알 수 있다.

        3번 옵션
        plugins: {
          legend: {
            labels: {
              font: {
                size: 16,
                weight: "bold",
                family: "Pretendard-Regular",
              },
            },
          },
        },
      },
      

마지막으로 legend의 labels의 font는
그래프의 제목이다.

50으로 키워주었다.




마무리

three.js를 잠깐 해본 적이 있는데 그때부터 한번 canvas관련 작업을 해보고 싶었는데 직접 잘 구현이 되어서 다행이었다.

그리고 여기에는 적지 않았지만, 그래프가 2개이상 생기는 버그가 생겼었다.
그래서 이 상황을 해결하기위해 여러 상황을 만들어보고 시도하였지만 잘되지않았고,
아침에 자고 일어나서 해보니 그냥 되었다..

원인을 알아내기 위해 다시 똑같은 상황을 만들었음에도 잘되었다..
어제는 안되었던 것이 갑자기 되어서 혼란스럽고 찝찝했지만,
해야할 일들이 있기에 여기에서 마무리하겠다.

참고자료

https://velog.io/@choichoijin/Chart.js%EB%A1%9C-%EC%B0%A8%ED%8A%B8-%ED%81%AC%EB%A6%AC%EA%B8%B0-React-Typescript

https://www.chartjs.org/docs/latest/charts/radar.html

https://codesandbox.io/s/l6qs1?file=/pages/index.js

https://velog.io/@ksh4820/react-chartjs-2-%EA%B7%B8%EB%9E%98%ED%94%84

profile
새로운 것을 배우는 것보다 정리하는 것이 중요하다.

4개의 댓글

comment-user-thumbnail
2023년 5월 14일

잘봤습니다. Chart.js랑 캔버스 이런 거에 대해서 아예 문외한이라 잘 모르는데 이번 기회에 잘보고 가용 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 5월 14일

오 저도 이번에 개인 프로젝트에서 써보고 싶은 부분이 있네요 ...!

답글 달기
comment-user-thumbnail
2023년 5월 14일

그래프 라이브러리도 있군요.. 프로젝트를 한번에 2개나 진행하시는게 대단하십니다 👍

답글 달기
comment-user-thumbnail
2023년 5월 14일

저도 그래프 나중에 써보고 싶어용 참고하겠습니다 ㅎㅎ

답글 달기