( chart.js ) 그래프 오류 해결 / 이전 데이터 오류 / 데이터 초기화

ZZOOO

·

2021. 5. 19. 06:59

안녕하세요, 오늘은 제가 오픈 소스 chart.js를 사용하며 겪은 오류에 대해서 포스팅하려 합니다.


목표 & 문제 상황

 

 

본인이 구현하고자 하는 목표는 다음과 같습니다.

 

  • 통계 자료 구현
  • 날짜를 선택하여 날짜에 해당되는 데이터를 가져와 차트에 보여준다

 


 

문제점은 다음과 같았습니다.

 

  • 최초 날짜 선택 시 데이터를 잘 가져와서 차트에 잘 보여준다.
  • 그 이후, 날짜 선택 시 마우스를 차트에 올렸을 때 이전 차트와 현재 차트가 번갈아가며 출력된다.

 

 

이해가 가지 않으실까, 영상으로 보여드리겠습니다.

 


 

문제의 영상

 

 

 

보셨나요 ? 특정 키를 누른다든지 특정 부분을 클릭하지 않아도, 그려져 있는 차트의 

자세한 값을 보려 마우스 커서를 올리면 이전의 차트로 변경되었다가 다시 돌아오는

버그가 발생하는 모습입니다.

 


본인 코드

 

 

$(function(){

  $('datepicker').change(function(){

    var date = $('datepicker').val();
    var name = $('input[name="project_name"]').val();
    dateObj = new dateDTO(date, name);


    $.ajax({
      url : '/main/chart',
      type : 'get',
      data : dateObj,
      success : function(result){

        var xValue = [0,1,2 ... , 23]; // 24 시간 표현
        
        ...
        ... // chart에 쓰일 값 세팅
 
        chartObj = new Chart("myChart"{
          type : "line",
          data : {
            labels : xValue,
            datasets : [{
              label : "static",
              data : static,
              borderColor : "red",
              fill : false
            },datasets : [{
              label : "static",
              data : static,
              borderColor : "red",
              fill : false, 
              
              ...
              
            }]
          },
          options : {
            legend : {display : true}
          }
        });
      },
      error : function(result){
          alert('err')        
      }
    })
  })
})

 

다음 소스는, 제 소스를 재구성하여 만든 코드입니다.

 


구글링 

 

몇 시간 삽질하다가, 구글에 검색해보았습니다. 마땅히 뭐라고 검색해야 할지 모르겠더라고요.

 

Q : 그래프 두 개 깜빡거림 ? 그래프 중복 ? chart.js 버그/bug ?

 

여러 가지 검색했지만 답변은 대부분 비슷했습니다.

 

A : var chartObj = new Chart(); 이렇게 할당했다면, chartObj.destroy(); 하고 다시 할당해

 

위와 같은 답변이 다수였습니다.

 

하지만, 제가 이 답변을 보고 든 생각은, 관건은 그리기 전에 destroy()를 해서 차트 값을 날리라는 건데요.

그럼 최초에 차트를 그릴 때 그릴 수 없을뿐더러, 선언되지 않은 객체라서, chartObj.destroy() 함수 자체를 

실행할 수 없습니다.

 

그래서 저는 다음과 같이 소스를 수정했습니다.


수정 코드 1차 시도

 

$(function(){

  $('datepicker').change(function(){

    var date = $('datepicker').val();
    var name = $('input[name="project_name"]').val();
    dateObj = new dateDTO(date, name);


    $.ajax({
      url : '/main/chart',
      type : 'get',
      data : dateObj,
      success : function(result){

        var xValue = [0,1,2 ... , 23]; // 24 시간 표현
        
        ...
        ... // chart에 쓰일 값 세팅
        if(chartObj != undefined){
            chartObj.destroy();
        }else{
            chartObj = new Chart("myChart"{
              type : "line",
              data : {
                labels : xValue,
                datasets : [{
                  label : "static",
                  data : static,
                  borderColor : "red",
                  fill : false
                },datasets : [{
                  label : "static",
                  data : static,
                  borderColor : "red",
                  fill : false, 
                  
                  ...
                  
                }]
              },
              options : {
                legend : {display : true}
              }
          });
        }
      },
      error : function(result){
          alert('err')        
      }
    })
  })
})

 

차트 객체 생성 전에 다음과 같은 소스를 추가했습니다.

 

if(chartObj != undefined){
	chartObj.destroy();
}else {
	
    ...
    
}

 

하지만 여전히 버그가 발생합니다.

 

차트를 그리기 전, 그린 후, 여러 군데 로그를 찡겨넣고 테스트해본 결과

위와 같이 작성했을 때에는, chartObj 라는 객체가 계속 undefined로 선언됩니다.

 

그 이유는 .change function 내부에 ajax를 호출한 형태인데, ajax 호출 뒤에

Chart 객체를 생성합니다. 말 그대로 내부에서 사용되는 변수 이름이 chartObj입니다.

 

그렇기 때문에, 2번째 그래프를 보기 위해 날짜를 클릭했을 때, chartObj라는 변수는 당연히

선언된 적 조차 없기에 undefined의 값을 가지고 있는 것입니다.

 

잘 이해가 되시나요 ?

 

그렇다면 다음과 같이 소스를 수정해보겠습니다.

 


수정 코드 2차 시도 ( 해결 )

 

 

$(function(){

  $('datepicker').change(function(){

    var date = $('datepicker').val();
    var name = $('input[name="project_name"]').val();
    dateObj = new dateDTO(date, name);


    $.ajax({
      url : '/main/chart',
      type : 'get',
      data : dateObj,
      success : function(result){

        var xValue = [0,1,2 ... , 23]; // 24 시간 표현
        
        ...
        ... // chart에 쓰일 값 세팅

        if(window.chartObj != undefined){
          window.chartObj.destroy();
        }
	        window.chartObj = new Chart("myChart"{
              type : "line",
              data : {
                labels : xValue,
                datasets : [{
                  label : "static",
                  data : static,
                  borderColor : "red",
                  fill : false
                },datasets : [{
                  label : "static",
                  data : static,
                  borderColor : "red",
                  fill : false, 
                  
                  ...
                  
                }]
              },
              options : {
                legend : {display : true}
              }
          });
        }
      },
      error : function(result){
          alert('err')        
      }
    })
  })
})

 

 

아래와 같은 부분이 수정되었습니다.

 

if(window.chartObj != undefined){
	window.chartObj.destroy();
}
window.chartObj = new Chart({

	...
    
})

 

수정 코드 1차와 같은 구조면서 딱히 다를 것 없습니다.

 

하지만, window.chartObj 라고 선언해주면서 1번 차트 그리기가 끝나고

2번 차트를 다시 호출하는 과정에서 내부 변수로 선언하면 찾을 수 없어 undefined 지만,

 

전역 변수로 선언했기 때문에 변수를 찾을 수 있고 구현한 로직에 맞아떨어지는 모습을 볼 수 있습니다.


 

이렇게, chart.js를 사용하면서 한 번쯤은 겪을 수 있는 에러에 대해서 포스팅을 해보았는데요.

 

오픈 소스 js라 가져다 쓰기 굉장히 편리하지만, 사용하는 사용자가 직접 개발한 것이 아니기에

로직 자체를 자세히 모르다 보니, 이런 현상이 발생할 수도 있다고 생각합니다.

 

도움이 되셨길 바라며 포스팅 마치겠습니다. 감사합니다.

 

반응형