it-swarm.com.de

Wie lösche ich ein Diagramm von einer Leinwand, so dass Hover-Ereignisse nicht ausgelöst werden können

Ich verwende Chartjs, um ein Liniendiagramm anzuzeigen, und das funktioniert gut:

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

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

Das Problem tritt jedoch auf, wenn ich versuche, die Daten für das Diagramm zu ändern. Ich aktualisiere das Diagramm, indem ich eine neue Instanz eines Diagramms mit den neuen Datenpunkten erstellt und damit die Leinwand neu initialisiert. 

Das funktioniert gut. Wenn ich jedoch über das neue Diagramm schwebe, werde ich, wenn ich zufällig über bestimmte Positionen gehe, die den Punkten des alten Diagramms entsprechen, immer noch ausgelöst, und der Hover/Label wird immer noch ausgelöst und plötzlich ist das alte Diagramm sichtbar. Es bleibt sichtbar, während sich meine Maus an dieser Stelle befindet, und verschwindet, wenn Sie sich von diesem Punkt entfernen. Ich möchte nicht, dass das alte Diagramm angezeigt wird. Ich möchte es komplett entfernen.

Ich habe versucht, sowohl die Leinwand als auch das vorhandene Diagramm zu löschen, bevor Sie die neue laden. Mögen:

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

und

chart.clear();

Aber bisher hat nichts davon funktioniert. Irgendwelche Ideen, wie ich das verhindern kann?

84
Adam Jones

Ich hatte große Probleme damit

Zuerst habe ich .clear() ausprobiert, dann habe ich .destroy() ausprobiert und versucht, die Chartreferenz auf null zu setzen

Was schließlich das Problem behoben hat: das <canvas>-Element löschen und dann einen neuen <canvas> an den übergeordneten Container anhängen


Mein spezifischer Code (offensichtlich gibt es dafür eine Million Möglichkeiten):

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);
};
107
neaumusic

Ich bin vor einigen Stunden mit dem gleichen Problem konfrontiert.

Die ".clear ()" - Methode löscht zwar die Leinwand, lässt das Objekt jedoch (offensichtlich) lebendig und reaktiv.

Beim sorgfältigen Lesen von der offiziellen Dokumentation habe ich im Abschnitt "Erweiterte Verwendung" die Methode ".destroy ()" bemerkt, die wie folgt beschrieben wird:

"Verwenden Sie diese Option, um alle erstellten Diagramminstanzen zu löschen. Dadurch werden alle Verweise auf das Diagrammobjekt in Chart.js, Sowie alle zugehörigen zugeordneten Ereignis-Listener bereinigt, die mit Chart.js verbunden sind."

Es macht wirklich das, was es behauptet und es hat gut funktioniert, ich schlage vor, es auszuprobieren.

31
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});
}
23
xchiltonx

Dies ist das einzige, was für mich funktioniert hat: 

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

Ich hatte das gleiche Problem hier ... Ich habe versucht, die Methode destroy () und clear () zu verwenden, aber ohne Erfolg.

Ich habe es auf den nächsten Weg gelöst:

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

Es funktioniert perfekt für mich ... Ich hoffe, dass es hilft.

4
Javier Muñoz

Das hat sehr gut für mich funktioniert

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

Verwenden Sie .destroy this, um alle erstellten Diagramminstanzen zu löschen. Dadurch werden alle Verweise, die im Chart-Objekt in Chart.js gespeichert sind, sowie alle zugehörigen Ereignis-Listener, die mit Chart.js verbunden sind, gelöscht. Dies muss aufgerufen werden, bevor die Leinwand erneut für ein neues Diagramm verwendet wird.

4

Wir können die Chartdaten in Chart.js V2.0 wie folgt aktualisieren:

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

Wenn Sie chart.js in einem Angular -Projekt mit TypeScript verwenden, können Sie Folgendes versuchen:

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>

Ich konnte .destroy () auch nicht dazu bringen, zu arbeiten, also mache ich das. Das chart_parent div ist der Ort, an dem die Leinwand angezeigt werden soll. Ich brauche jedes Mal die Leinwand, um die Größe zu ändern, daher ist diese Antwort eine Erweiterung der obigen.

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
Chris

Wenn Sie CanvasJS verwenden, funktioniert dies für mich und das Löschen von Diagrammen und allem anderen. Es kann auch für Sie funktionieren, wenn Sie Ihre Leinwand/Diagramm vollständig vor jeder Verarbeitung an anderer Stelle einrichten:

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

Wenn Sie eine neue Zeichenfläche für chart.js erstellen, wird ein neuer ausgeblendeter iframe generiert. Sie müssen die Leinwand und die alten iframes löschen. 

$('#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 });

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

1
zebus3d

Da zerstören Art und Weise "alles" zerstört, ist eine billige und einfache Lösung, wenn Sie wirklich nur "die Daten zurücksetzen" wollen. Das Zurücksetzen Ihrer Datensätze auf ein leeres Array funktioniert ebenfalls einwandfrei. Wenn Sie also einen Datensatz mit Beschriftungen und einer Achse auf jeder Seite haben:

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

Danach können Sie einfach anrufen:

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

oder abhängig davon, ob Sie einen 2D-Datensatz verwenden:

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

Es ist viel leichter, als das gesamte Diagramm/Daten-Set vollständig zu zerstören und alles neu zu erstellen.

0
T.S

Wir haben vor der Initialisierung eines neuen Diagramms die Vorschaubild-Instanz entfernt/zerstört. Falls bereits vorhanden, erstellen Sie beispielsweise ein neues Diagramm

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

Hoffe das hilft.

0
Qammar Feroz

Für mich hat das funktioniert:

		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
Scrapie

Chart.js hat einen Fehler: Chart.controller(instance) registriert ein neues Diagramm in einer globalen Eigenschaft Chart.instances[] und löscht es aus dieser Eigenschaft in .destroy()

Bei der Diagrammerstellung schreibt Chart.js jedoch auch die ._meta-Eigenschaft in die Datenmengenvariable:

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

und diese Eigenschaft wird bei destroy() nicht gelöscht. 

Wenn Sie Ihr altes Datensatzobjekt verwenden, ohne ._meta property zu entfernen, fügt Chart.js ._meta eine neue Datenmenge hinzu, ohne die vorherigen Daten zu löschen. Bei der Neuinitialisierung jedes Diagramms sammelt Ihr Datenobjekt also alle vorherigen Daten.

Um dies zu vermeiden, zerstören Sie das Datensatzobjekt nach dem Aufruf von Chart.destroy().

0
Andrew Hudik

Das hat für mich funktioniert . Füge einen Aufruf von clearChart hinzu, ganz oben in deinem updateChart (). 

`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;
}`
0
Jay