호버 이벤트가 트리거되지 않도록 캔버스에서 차트를 지우는 방법은 무엇입니까?


109

나는 Chartjs를 사용하여 선 차트를 표시하고 있으며 잘 작동합니다.

// get line chart canvas
var targetCanvas = document.getElementById('chartCanvas').getContext('2d');

// draw line chart
var chart = new Chart(targetCanvas).Line(chartData);

하지만 차트의 데이터를 변경하려고 할 때 문제가 발생합니다. 새 데이터 포인트로 Chart의 새 인스턴스를 만들고 캔버스를 다시 초기화하여 그래프를 업데이트합니다.

이것은 잘 작동합니다. 그러나 새 차트 위로 마우스를 가져 가면 이전 차트에 표시된 포인트에 해당하는 특정 위치를지나 가면 마우스 오버 / 레이블이 여전히 트리거되고 갑자기 이전 차트가 표시됩니다. 내 마우스가이 위치에있는 동안에는 계속 표시되고 해당 지점에서 벗어나면 사라집니다. 이전 차트를 표시하고 싶지 않습니다. 완전히 제거하고 싶습니다.

새 차트를로드하기 전에 캔버스와 기존 차트를 모두 지우려고했습니다. 처럼:

targetCanvas.clearRect(0,0, targetCanvas.canvas.width, targetCanvas.canvas.height);

chart.clear();

그러나 이들 중 어느 것도 지금까지 작동하지 않았습니다. 이런 일이 발생하는 것을 막을 수있는 방법에 대한 아이디어가 있습니까?


18
야,이게 내가 가진 문제 야. "destroy ()"메서드가 작동하지 않고 짜증이납니다.
neaumusic

차트 개체에 액세스하는 방법을 물어봐도 될까요? 같은 문제가 발생하여 차트를 만든 다음 버튼을 클릭하여 삭제해야하는데 완전히 다른 기능에 있으며 캔버스 또는 컨텍스트를 통해 차트 개체에 액세스하는 방법을 찾을 수 없습니다. 사물.
Matt Williams

이 문제에 대해 열린 버그가 있습니다. 여기에서 확인하십시오. github.com/jtblin/angular-chart.js/issues/187
MDT

이 문제가 있었다. 생성 / 재생성 솔루션 stackoverflow.com/a/51882403/1181367
Chris

답변:


142

나는 이것에 큰 문제가 있었다

먼저 시도한 .clear()다음 .destroy()차트 참조를 null로 설정하려고 시도했습니다.

마지막으로 문제를 해결 <canvas>한 이유 : 요소를 삭제 한 다음 <canvas>부모 컨테이너에 새 항목 다시 추가


내 특정 코드 (분명히이 작업을 수행하는 방법은 백만 가지가 있습니다) :

var resetCanvas = function(){
  $('#results-graph').remove(); // this is my <canvas> element
  $('#graph-container').append('<canvas id="results-graph"><canvas>');
  canvas = document.querySelector('#results-graph');
  ctx = canvas.getContext('2d');
  ctx.canvas.width = $('#graph').width(); // resize to parent width
  ctx.canvas.height = $('#graph').height(); // resize to parent height
  var x = canvas.width/2;
  var y = canvas.height/2;
  ctx.font = '10pt Verdana';
  ctx.textAlign = 'center';
  ctx.fillText('This text is centered on the canvas', x, y);
};

2
챔피언처럼 일했습니다. Chart.js 버전 2가이 문제를 해결하는지 아는 사람이 있으면 여기에 게시하십시오. destroy가 깨 졌는지 아니면 잘못 사용하고 있는지 궁금합니다.
TheLettuceMaster 2015

2
좋은! 감사! 방금 $ ( '# results-graph'). remove (); $ ( '# graph-container'). append ( '<canvas id = "results-graph"> <canvas>'); 차트 생성 전에.
Ignacio

.destroy ()가 제대로 작동합니다. 그렇지 않은 경우 .destroy ()를 호출하여 새 차트를
그린 후

그 유일한 해결책은 나에게 많은 감사를했다지만, 폭과 높이의 당신은 이미 당신이 초기화 함수에서 같은 값으로 재설정해야 고정 설정하는 경우
샌디 Elkassar을

2
chartjs 2.8.0에서 destroy ()가 실패했지만 솔루션이 작동했습니다! 제 경우 $('#results-graph').remove(); $('#graph-container').append('<canvas id="results-graph"><canvas>');에는new Chart(document.getElementById("myCanvas")
mimi

40

몇 시간 전에 같은 문제에 직면했습니다.

".clear ()"메소드는 실제로 캔버스를 지우지 만 (분명히) 객체를 살아 있고 반응 적으로 남겨 둡니다.

"고급 사용법"섹션에서 공식 문서를 주의 깊게 읽으면 다음과 같이 설명 된 ".destroy ()"메소드를 발견했습니다.

"이를 사용하여 생성 된 모든 차트 인스턴스를 제거합니다. 이렇게하면 Chart.js에서 첨부 된 모든 관련 이벤트 리스너와 함께 Chart.js 내의 차트 개체에 저장된 모든 참조가 정리됩니다."

그것은 실제로 그것이 주장하는 것을 수행하고 그것은 나를 위해 잘 작동했습니다, 나는 그것을 시도해 보는 것이 좋습니다.


예를 보여 주시겠습니까? 여러 번 차단을 사용하려고 시도했지만 작동하지 않습니다. 메서드가 존재하지 않는다는 오류가 항상 발생합니다.
Ben Hoffman

3
(<ChartInstance> this.chart) .destroy ();
David Dal Busco

2
이것이 바로 anszwer입니다. 향후 참조는 다음을 참조하십시오. stackoverflow.com/questions/40056555/…
ThePhi

29
var myPieChart=null;

function drawChart(objChart,data){
    if(myPieChart!=null){
        myPieChart.destroy();
    }
    // Get the context of the canvas element we want to select
    var ctx = objChart.getContext("2d");
    myPieChart = new Chart(ctx).Pie(data, {animateScale: true});
}

1
이 가장 좋은 대안이다
RafaSashi

잘 했어. 감사합니다
Manjunath Siddappa

11

이것은 나를 위해 일한 유일한 것입니다.

document.getElementById("chartContainer").innerHTML = '&nbsp;';
document.getElementById("chartContainer").innerHTML = '<canvas id="myCanvas"></canvas>';
var ctx = document.getElementById("myCanvas").getContext("2d");

9

여기서도 같은 문제가 발생했습니다. destroy () 및 clear () 메서드를 사용하려고했지만 성공하지 못했습니다.

다음 방법으로 해결했습니다.

HTML :

<div id="pieChartContent">
    <canvas id="pieChart" width="300" height="300"></canvas>
</div>

자바 스크립트 :

var pieChartContent = document.getElementById('pieChartContent');
pieChartContent.innerHTML = '&nbsp;';
$('#pieChartContent').append('<canvas id="pieChart" width="300" height="300"><canvas>');

ctx = $("#pieChart").get(0).getContext("2d");        
var myPieChart = new Chart(ctx).Pie(data, options);

저에게 완벽하게 작동합니다 ... 도움이 되었으면합니다.


5

이것은 나를 위해 아주 잘 작동했습니다.

    var ctx = $("#mycanvas");
     var LineGraph = new Chart(ctx, {
        type: 'line',
        data: chartdata});
        LineGraph.destroy();

.destroy를 사용 하여 생성 된 모든 차트 인스턴스를 삭제합니다. 이렇게하면 Chart.js에 연결된 모든 관련 이벤트 리스너와 함께 Chart.js 내의 차트 개체에 저장된 모든 참조가 정리됩니다. 캔버스가 새 차트에 다시 사용되기 전에 호출해야합니다.


이 방법은 나를 위해 제대로 작동하며 호버 콜백을 파괴하는 것처럼 보입니다. 탱크가 많이 !!
앙투안 Pointeau

4

Chart.js V2.0에서 다음과 같이 차트 데이터를 업데이트 할 수 있습니다.

var myChart = new Chart(ctx, data);
myChart.config.data = new_data;
myChart.update();

나는 이것이 훨씬 더 나은 솔루션이라는 데 동의합니다. Destroy는 너무 급진적입니다. 우리가 정말로 원하는 것은 "데이터"를 다시 시작하는 것입니다.
TS

1

CanvasJS를 사용하면 차트 및 다른 모든 항목을 지우는 데 도움이되며 다른 곳에서 처리하기 전에 캔버스 / 차트를 완전히 설정할 수 있습니다.

var myDiv= document.getElementById("my_chart_container{0}";
myDiv.innerHTML = "";

위의 방법 중 어느 것도 작동하지 않았습니다. 이것은 완벽하게 작동했습니다. 감사합니다.
초급

1

.destroy ()도 작동하지 않으므로 이것이 내가하는 일입니다. chart_parent div는 캔버스를 표시하려는 곳입니다. 매번 크기를 조정할 캔버스가 필요 하므로이 답변은 위의 답변의 확장입니다.

HTML :

<div class="main_section" > <div id="chart_parent"></div> <div id="legend"></div> </div>

JQuery :

  $('#chart').remove(); // this is my <canvas> element
  $('#chart_parent').append('<label for = "chart">Total<br /><canvas class="chart" id="chart" width='+$('#chart_parent').width()+'><canvas></label>');

1

하나의 새 chart.js 캔버스를 생성하면 숨겨진 하나의 새 iframe이 생성되므로 캔버스와 이전 iframe을 삭제해야합니다.

$('#canvasChart').remove(); 
$('iframe.chartjs-hidden-iframe').remove(); 
$('#graph-container').append('<canvas id="canvasChart"><canvas>'); 
var ctx = document.getElementById("canvasChart"); 
var myChart = new Chart(ctx, { blablabla });

참조 : https://github.com/zebus3d/javascript/blob/master/chartJS_filtering_with_checkboxs.html


1

이것은 나를 위해 일했습니다. updateChart () 상단에 clearChart에 대한 호출을 추가합니다.

`function clearChart() {
    event.preventDefault();
    var parent = document.getElementById('parent-canvas');
    var child = document.getElementById('myChart');          
    parent.removeChild(child);            
    parent.innerHTML ='<canvas id="myChart" width="350" height="99" ></canvas>';             
    return;
}`

1

Typescript가있는 Angular 프로젝트에서 chart.js를 사용하는 경우 다음을 시도 할 수 있습니다.

Import the library:
    import { Chart } from 'chart.js';

In your Component Class declare the variable and define a method:

  chart: Chart;

  drawGraph(): void {
    if (this.chart) {
      this.chart.destroy();
    }

    this.chart = new Chart('myChart', {
       .........
    });
  }


In HTML Template:
<canvas id="myChart"></canvas>

1

우리가 한 것은 새 차트를 초기화하기 전에 미리보기 Chart 인스턴스 (이미 존재하는 경우)를 제거 / 파기 한 다음 새 차트를 만드는 것입니다.

if(myGraf != undefined)
    myGraf.destroy();
    myGraf= new Chart(document.getElementById("CanvasID"),
    { 
      ...
    }

도움이 되었기를 바랍니다.


1

아담의 답변 보완

Vanilla JS 사용 :

document.getElementById("results-graph").remove(); //canvas
div = document.querySelector("#graph-container"); //canvas parent element
div.insertAdjacentHTML("afterbegin", "<canvas id='results-graph'></canvas>"); //adding the canvas again


1

2020 년 간단한 편집 :

이것은 나를 위해 일했습니다. 창을 소유하여 차트를 글로벌로 변경하십시오 (선언을에서 var myChart로 변경하십시오 window myChart).

차트 변수가 이미 Chart로 초기화되어 있는지 확인하십시오. 그렇다면 동일한 이름으로 다른 변수를 만들 수 있더라도 제거하고 새로 만드십시오. 다음은 코드입니다.

if(window.myChart instanceof Chart)
{
    window.myChart.destroy();
}
var ctx = document.getElementById('myChart').getContext("2d");

작동하기를 바랍니다!


1
매우 감사합니다. 이것은 나를 위해 작동합니다.
Dante

0

나를 위해 이것은 일했습니다.

		var in_canvas = document.getElementById('chart_holder');
	//remove canvas if present
			while (in_canvas.hasChildNodes()) {
				  in_canvas.removeChild(in_canvas.lastChild);
				} 
	//insert canvas
			var newDiv = document.createElement('canvas');
			in_canvas.appendChild(newDiv);
			newDiv.id = "myChart";


0

Chart.js에는 버그가 있습니다. Chart.controller(instance) 전역 속성에 새 차트를 등록Chart.instances[] 의이 속성에서 삭제합니다 .destroy().

그러나 차트 생성시 Chart.js는 또한 다음과 같이 씁니다. ._meta 데이터 셋 변수에 속성을 .

var meta = dataset._meta[me.id];
if (!meta) {
   meta = dataset._meta[me.id] = {
       type: null,
       data: [],
       dataset: null,
       controller: null,
       hidden: null,     // See isDatasetVisible() comment
       xAxisID: null,
       yAxisID: null
   };

에서이 속성은 삭제되지 않습니다 destroy().

제거하지 않고 이전 데이터 세트 객체를 사용하는 경우 ._meta property Chart.js가 새 데이터 세트를._meta 이전 데이터를 삭제하지 않고 합니다. 따라서 각 차트를 다시 초기화 할 때 데이터 세트 개체는 모든 이전 데이터를 누적합니다.

이를 방지하려면 Chart.destroy().


0

destroy는 "모든 것"을 파괴하기 때문에 값 싸고 간단한 해결책은 "데이터를 재설정"하는 것입니다. 데이터 세트를 빈 배열로 재설정하는 것도 완벽하게 작동합니다. 따라서 레이블이있는 데이터 세트와 각 측면에 축이있는 경우 :

window.myLine2.data.labels = [];
window.myLine2.data.datasets[0].data = [];
window.myLine2.data.datasets[1].data = [];

그 후에 간단히 다음을 호출 할 수 있습니다.

window.myLine2.data.labels.push(x);
window.myLine2.data.datasets[0].data.push(y);

또는 2D 데이터 세트를 사용하는지 여부에 따라

window.myLine2.data.datasets[0].data.push({ x: x, y: y});

전체 차트 / 데이터 세트를 완전히 파괴하고 모든 것을 재 구축하는 것보다 훨씬 가볍습니다.


0

나를 좋아하는 사람들은 함수를 사용하여 여러 그래픽을 생성하고 블록도 업데이트하고 싶은 경우 .destroy () 함수 만 저에게 효과적이었습니다. . 다음은 도움이 될 수있는 코드 스 니펫입니다.

var SNS_Chart = {};

// IF LABELS IS EMPTY (after update my datas)
if( labels.length != 0 ){

      if( Object.entries(SNS_Chart).length != 0 ){

            array_items_datas.forEach(function(for_item, k_arr){
                SNS_Chart[''+for_item+''].destroy();
            });

       }

       // LOOP OVER ARRAY_ITEMS
       array_items_datas.forEach(function(for_item, k_arr){

             // chart
             OPTIONS.title.text = array_str[k_arr];
             var elem = document.getElementById(for_item);
             SNS_Chart[''+for_item+''] = new Chart(elem, {
                 type: 'doughnut',
                 data: {
                     labels: labels[''+for_item+''],
                     datasets: [{
                        // label: '',
                        backgroundColor: [
                            '#5b9aa0',
                            '#c6bcb6',
                            '#eeac99',
                            '#a79e84',
                            '#dbceb0',
                            '#8ca3a3',
                            '#82b74b',
                            '#454140',
                            '#c1502e',
                            '#bd5734'
                        ],
                        borderColor: '#757575',
                        borderWidth : 2,
                        // hoverBackgroundColor : '#616161',
                        data: datas[''+for_item+''],
                     }]
                 },
                 options: OPTIONS

             });
             // chart
       });
       // END LOOP ARRAY_ITEMS

  }
 // END IF LABELS IS EMPTY ...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.