Üzerine gelme olaylarının tetiklenememesi için tuvalden bir grafik nasıl temizlenir?


109

Bir Çizgi Grafiği görüntülemek için Chartjs kullanıyorum ve bu iyi çalışıyor:

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

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

Ancak Grafik için verileri değiştirmeye çalıştığımda sorun ortaya çıkıyor. Yeni veri noktalarıyla yeni bir Grafik örneği oluşturarak ve böylece tuvali yeniden başlatarak grafiği güncelliyorum.

Bu iyi çalışıyor. Ancak, fareyle yeni grafiğin üzerine geldiğimde, eski grafikte görüntülenen noktalara karşılık gelen belirli konumların üzerinden geçersem, fareyle üzerine gelme / etiket hala tetikleniyor ve aniden eski grafik görünür. Farem bu konumdayken görünür durumda kalıyor ve o noktadan ayrıldığında kayboluyor. Eski grafiğin görüntülenmesini istemiyorum. Tamamen kaldırmak istiyorum.

Yenisini yüklemeden önce hem tuvali hem de mevcut grafiği temizlemeye çalıştım. Sevmek:

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

ve

chart.clear();

Ancak şimdiye kadar bunların hiçbiri işe yaramadı. Bunun olmasını nasıl önleyebileceğim hakkında herhangi bir fikrin var mı?


18
Dostum, tam da yaşadığım sorun bu. "Destroy ()" yöntemi işe yaramıyor ve beni sinirlendiriyor.
neaumusic

Grafik nesnesine nasıl eriştiğinizi sorabilir miyim? Ben de aynı sorunu yaşıyorum, bir grafik oluşturuyorum ve sonra bir düğmeyi tıkladığımda onu yok etmem gerekiyor, ancak bu tamamen farklı bir işlevde ve grafik nesnesine tuval veya bağlam üzerinden erişmenin bir yolunu bulamıyorum nesneler.
Matt Williams

Bu sorun için açılmış bir hata var, buraya bakın. github.com/jtblin/angular-chart.js/issues/187
MDT

Bu sorunu yaşadım. Stackoverflow
Chris

Yanıtlar:


143

Bununla büyük sorunlarım vardı

Önce denedim .clear()sonra denedim .destroy()ve grafik referansımı null olarak ayarlamayı denedim

Sonunda benim için sorunu <canvas>çözen şey: öğeyi silmek ve ardından <canvas>üst kapsayıcıya yeni bir tane eklemek


Benim özel kodum (tabii ki bunu yapmanın milyonlarca yolu var):

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
Bir şampiyon gibi çalıştı. Chart.js sürüm 2'nin bunu düzeltip düzeltmediğini bilen biri varsa, buraya gönderin. Acaba yıkım mı bozuldu yoksa yanlış mı kullanıyoruz?
TheLettuceMaster

2
Güzel! Teşekkürler! $ ('# Results-grafik') ekledim. Remove (); $ ('# graph-container']. append ('<canvas id = "results-graph"> <canvas>'); grafik oluşturmadan önce.
Ignacio

.destroy () iyi çalışmalıdır. Değilse, yeni grafik çizmek için .destroy () 'u çağırdıktan sonra, setTimeout ()
Sumeet Kale

bu benim için işe
yarayan

2
destroy () benim için chartjs 2.8.0 ile başarısız oldu ama çözümünüz işe yaradı! Benim durumumda sadece$('#results-graph').remove(); $('#graph-container').append('<canvas id="results-graph"><canvas>');new Chart(document.getElementById("myCanvas")
mimi

40

Birkaç saat önce aynı problemle karşılaştım.

".Clear ()" yöntemi aslında tuvali temizler, ancak (belli ki) nesneyi canlı ve reaktif bırakır.

Resmi belgeleri dikkatlice okuduktan sonra, "Gelişmiş kullanım" bölümünde, aşağıda açıklanan ".destroy ()" yöntemini fark ettim:

"Oluşturulan tüm grafik örneklerini yok etmek için bunu kullanın. Bu, Chart.js tarafından eklenen tüm ilişkili olay dinleyicileriyle birlikte Chart.js içindeki grafik nesnesine depolanan tüm referansları temizler."

Aslında iddia ettiği şeyi yapıyor ve benim için iyi çalıştı, denemenizi öneririm.


Bir örnek gösterebilir misin? Engellemeyi defalarca kullanmayı denedim ve asla işe yaramadı. Her zaman yöntemin bulunmadığına dair bir hata alıyorum.
Ben Hoffman

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

2
Bu doğru cevaptır. Gelecekteki referanslar için bakınız: 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
bu en iyi alternatif
RafaSashi

İyi bir. Teşekkürler
Manjunath Siddappa

11

Benim için işe yarayan tek şey bu:

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

9

Burada da aynı sorunu yaşadım ... destroy () ve clear () yöntemini kullanmaya çalıştım ama başarılı olamadım.

Bunu bir sonraki yolla çözdüm:

HTML:

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

Javascript:

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);

Benim için mükemmel çalışıyor ... Umarım yardımcı olur.


5

Bu benim için çok iyi çalıştı

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

Oluşturulan tüm grafik örneklerini yok etmek için .destroy bunu kullanın . Bu, Chart.js tarafından eklenen ilişkili olay dinleyicileriyle birlikte Chart.js içindeki grafik nesnesine depolanan tüm referansları temizler. Bu, tuval yeni bir grafik için yeniden kullanılmadan önce çağrılmalıdır.


Bu yol benim için düzgün çalışıyor, vurgulu geri aramaları yok ediyor gibi görünüyor. Tanklar çok fazla !!
Antoine Pointeau

4

Chart.js V2.0'daki grafik verilerini aşağıdaki gibi güncelleyebiliriz:

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

Bunun çok daha iyi bir çözüm olduğuna katılıyorum - Tek istediğimiz "veriyi" yeniden başlatmak olduğunda, Destroy çılgınca aşırı radikaldir.
TS

1

CanvasJS kullanarak, bu benim için grafik ve diğer her şeyi temizlemek için çalışıyor, sizin için de işe yarayabilir ve başka bir yerde her işlemden önce tuvalinizi / grafiğinizi tam olarak ayarlamanızı sağlar:

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

benim için yukarıdaki yöntemlerden hiçbiri işe yaramadı. Bu mükemmel çalıştı. Çok teşekkürler.
başlangıç

1

Ben de .destroy () işlevini alamadım, bu yüzden yaptığım şey bu. Chart_parent div, tuvalin görünmesini istediğim yerdir. Tuvali her seferinde yeniden boyutlandırmak için ihtiyacım var, bu yüzden bu cevap yukarıdakinin bir uzantısı.

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

Bu benim için çalıştı. UpdateChart'ınızın () üst kısmındaki clearChart'a bir çağrı ekleyin

`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

Typecript ile Angular projede chart.js kullanıyorsanız, aşağıdakileri deneyebilirsiniz;

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

Yaptığımız şey, yeni grafiğin başlatılmasından önce, önceden mevcutsa Grafik örneğini önizlemeleri kaldırmak / yok etmek, ardından örneğin yeni bir grafik oluşturmaktır.

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

Bu yardımcı olur umarım.


1

Adam'ın Cevabını Tamamlamak

Vanilla JS ile:

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 için basit düzenleme:

Bu benim için çalıştı. Pencerenin sahipli olmasını sağlayarak grafiği global olarak değiştirin (bildirimini olarak var myChartdeğiştirin window myChart)

Grafik değişkeninin zaten Grafik olarak başlatılıp başlatılmadığını kontrol edin, öyleyse, onu yok edin ve yeni bir tane oluşturun, hatta aynı isimde bir tane daha oluşturabilirsiniz. Kod aşağıdadır:

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

Umarım çalışır!


1
Çok teşekkürler. Bu benim için çalışıyor.
Dante

0

Benim için bu işe yaradı:

		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'de bir hata var: Chart.controller(instance)herhangi bir yeni grafiği global bir mülkte kaydeder Chart.instances[]ve tarihinde bu özellikten siler .destroy().

Ancak grafik oluştururken Chart.js ._metaözelliği de veri kümesi değişkenine yazar :

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
   };

ve üzerinde bu özelliği silmez destroy().

Eski veri kümesi nesnenizi kaldırmadan kullanırsanız ._meta property, Chart.js ._metaönceki verileri silmeden yeni veri kümesini ekler . Bu nedenle, her grafiğin yeniden başlatılmasında veri kümesi nesneniz önceki tüm verileri toplar.

Bunu önlemek için, çağırdıktan sonra veri kümesi nesnesini imha edin Chart.destroy().


0

Yok etme, "her şeyi" bir şekilde yok ettiğinden, gerçekten tek istediğiniz "verileri sıfırlamak" olduğunda ucuz ve basit bir çözüm. Veri kümelerinizi boş bir diziye sıfırlamak da mükemmel şekilde çalışacaktır. Dolayısıyla, etiketleri olan bir veri kümeniz ve her iki tarafta bir ekseniniz varsa:

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

Bundan sonra şunları arayabilirsiniz:

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

veya bir 2d veri kümesi kullanmanıza bağlı olarak:

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

Tüm grafiğinizi / veri kümenizi tamamen yok etmekten ve her şeyi yeniden oluşturmaktan çok daha hafif olacaktır.


0

Birkaç grafik oluşturmak için bir işlev kullanmaktan hoşlananlar ve bunları bir blok da güncellemek isteyenler için sadece .destroy () işlevi benim için çalıştı, daha temiz görünen bir .update () yapmak isterdim ama .. İşte yardımcı olabilecek bir kod parçacığı.

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 ...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.