chart.js 그래프 초기화 - destroy()

dobyming·2023년 1월 14일
0
post-thumbnail

웹팩 번들링 문제를 해결하고 나니, 또 다른 이슈가 발생했었다. 산 넘어 산

구글링 해보니, 꽤 유명한 에러 로그인것 같았다.

초기에 그래프를 로딩하고 그리는데에는 문제가 없었지만, 다른 나라를 클릭하고 데이터를 불러올때, 기존 그래프가 초기화 되질 않아서 다음과 같이 이슈가 발생했다.

그래서 6일동안 삽질한 결과 다음과 같이 해결할 수 있었다.

(이 글을 읽을 당신 프로젝트에서는 안될 수도 있습니다... 그만큼 저도 별의별 방법 다 찾아가면서 해결한 방법이므로 이게 최선책이 아닐 수도 있다는걸 말씀드려요 ^^ ㅜ)


해결

chart.js 공식문서 에서는 기존 차트 instance를 날리고 싶으면 .destroy() 메소드를 써보라고 합니다.

This must be called before the canvas is reused for a new chart.

네 console에 잡혔던 에러랑 똑같은 말을 해주고 있죠,, 이걸로 쇼부를 봅시다.

코드

import Chart from chart.js/auto

function renderChart(data: number[], labels: string[]) {
  const lineChart = $('#lineChart') as HTMLCanvasElement;
  const ctx = lineChart.getContext('2d');
  if (Chart.getChart(lineChart)) {
    Chart.getChart(lineChart)?.destroy();
  }

  Chart.defaults.color = '#f5eaea';
  Chart.defaults.font.family = 'Exo 2';
  if (!ctx) {
    return;
  }
  new Chart(ctx, {
    type: 'line',
    data: {
      labels,
      datasets: [
        {
          label: 'Confirmed for the last two weeks',
          backgroundColor: '#feb72b',
          borderColor: '#feb72b',
          data,
        },
      ],
    },
    options: {
      maintainAspectRatio: false, //차트 그래프 사이즈 고정
    },
  });
}

해당 코드에서 3번째 line의 if문을 주목하시면,

  1. Chart.getChart(lineChart)가 만약 값이 할당되어 있다면 (=그래프가 그려져 있음)
  2. 그 차트값을 불러오고, destroy() (=그래프 초기화)

를 의미합니다.

따라서 다음과 같이 코드를 수정 시, 그래프가 동적으로 변하지 않는 이슈가 해결됩니다.


+) 타입 강하게 잡아내기 : 옵셔널 체이닝(연산자 : '?')

이때 Chart.getChart(lineChart)?.destroy(); 이게 뭔가 싶으실텐데요 ..

해당 연산자는 Optional Chaining 이라고 다음 코드와 동일한 의미를 갖습니다.

if (Chart.getChart(lineChart) === null 
    || Chart.getChart(lineChart) === undefined) { 
  return; 
}
else { 
  Chart.getChart(lineChart).destroy(); 
}

Chart.getChart(lineChart)null 또는 undefined에 해당하지 않는다면(=그래프가 이미 그려져 있는 상태) destroy() 하라는것과 동일한 의미를 지닙니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 6일

진짜 너무너무너무 감사합니다 덕분에 잘해결하였습니다 감사합니다

답글 달기