web-dev-qa-db-fra.com

Détruire le graphique à barres chart.js pour redessiner un autre graphique dans le même <canvas>

J'utilise la bibliothèque Chart.js pour dessiner un graphique à barres, il fonctionne bien, mais je souhaite maintenant détruire le graphique à barres et créer un graphe linéaire dans le même canvas. J'ai essayé ces deux façons de nettoyer la toile:

var grapharea = document.getElementById("barChart").getContext("2d");

grapharea.destroy();

var myNewChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });

deuxième voie:

var grapharea = document.getElementById("barChart").getContext("2d");

grapharea.clear();

var myNewChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });

Est-ce que je l'appelle bien? OnButtonClick J'appelle cette fonction qui utilise le même canevas.

29
Uzair Xlade

La méthode correcte à utiliser pour pouvoir dessiner un autre graphique sur le même canevas est .destroy(). Vous devez l'appeler sur l'objet graphique créé précédemment. Vous pouvez également utiliser la même variable pour les deux graphiques.

var grapharea = document.getElementById("barChart").getContext("2d");

var myChart = new Chart(grapharea, { type: 'bar', data: barData, options: barOptions });

myChart.destroy();

myChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });

Directement des docs (sous Méthodes de prototype) :

.détruire()

Utilisez cette option pour détruire toutes les instances de graphique créées. Cela nettoiera toutes les références stockées dans l'objet graphique dans Chart.js, ainsi que tous les écouteurs d'événements associés attachés par Chart.js. Cela doit être appelé avant que la toile ne soit réutilisée pour un nouveau graphique.

// Example from the docs
var myLineChart = new Chart(ctx, config);
// Destroys a specific chart instance
myLineChart.destroy();

Il est explicitement indiqué que cette méthode doit être appelée pour que le canevas puisse être réutilisé pour un nouveau graphique.

.clear() est également mentionné plus loin dans la même section en tant que fonction qui "effacera la trame du graphique. Utilisée de manière intensive en interne entre les images d'animation, mais elle pourrait être utile." Le graphique sera bien vivant après avoir appelé cette méthode. Ce n'est donc pas la méthode à appeler si vous souhaitez réutiliser le canevas pour un nouveau graphique.

Pour être honnête, cependant, dans des cas comme le vôtre, j’ai souvent utilisé un conteneur div pour envelopper ma canvas et, chaque fois que je devais créer un nouveau graphique, j’ai placé un nouvel élément canvas dans cette div. J'ai ensuite utilisé cette canvas nouvellement créée pour le nouveau graphique. Si vous rencontrez un comportement étrange, éventuellement lié à des graphiques occupant le fond avant le graphique actuel, pensez également à cette approche.

59
xnakos

Enlevez la toile après chaque appel de carte, cela a fonctionné pour moi

$("canvas#chartreport").remove();
$("div.chartreport").append('<canvas id="chartreport" class="animated fadeIn" height="150"></canvas>');
var ctx = document.getElementById("chartreport").getContext("2d");
chartreport= new Chart(ctx, { .... });
18
It0007

Pour ChartJS v2.x, vous pouvez utiliser update () pour mettre à jour les données du graphique sans détruire ni créer explicitement le canevas.

var chart_ctx = document.getElementById("chart").getContext("2d");

var chart = new Chart(chart_ctx, {
    type: "pie",
    data: {}
    options: {}
}

$.ajax({
    ...
}).done(function (response) {
    chart.data = response;
    chart.update();
});
1
bmatovu

Afin de résoudre ce problème, j’ai utilisé les méthodes add() et remove() de jQuery pour effacer le canevas. Je supprime le composant et avant de le dessiner à nouveau, je rajoute le canevas avec le même identifiant à l'aide de la méthode append() de jQuery.

redraw(){

 $("#myChart").remove();// removing previous canvas element
 //change the data values or add new values for new graph
 $("#chart_box").after("<canvas id='myChart'></canvas>");
 // again adding a new canvas element with same id
 generateGraph();// calling the main graph generating function 

}
0
Ankit Abhinav

J'utilise Chart.js 2.7.2 à partir de maintenant. Dans mon application, je créais plusieurs graphiques et j'avais besoin d'un moyen d'y accéder pour "remplacer" correctement leurs données et corriger le "vieux graphique" en survol. Aucune des réponses que j'ai essayées n'a fonctionné correctement.

Voici un moyen de gérer cela avec un ou plusieurs graphiques:

Stocker les graphiques en global

var charts=[]; // global

Fonction pour créer des graphiques 

function createChart(id, type, labels, data)
{
    // for multiple datasets
    var datasets=[];
    data.forEach(function(set) {
        datasets.Push({
            label: set.label,
            data: set.data
        });
    });  

    var config = {
        type: type,
        data: {
            labels: labels,
            datasets: datasets
        }
    };

    if(typeof charts[id] == "undefined") // see if passed id exists
    {   
        // doesn't, so create it
        charts[id]= new (function(){
            this.ctx=$(id); // canvas el
            this.chart=new Chart(this.ctx, config);
        })();     
        console.log('created chart '+charts[id].chart.canvas.id);     
    }
    else
    {
        charts[id].chart.destroy(); // "destroy" the "old chart"
        charts[id].chart=new Chart(charts[id].ctx, config); // create the chart with same id and el
        console.log('replaced chart '+charts[id].chart.canvas.id);        
    }
    // just to see all instances
    Chart.helpers.each(Chart.instances, function(instance){
        console.log('found instance '+instance.chart.canvas.id)
    })

}

Pour chacun de vos éléments de toile comme: 

<canvas id="thiscanvasid"></canvas>

Utilisez la fonction pour créer/remplacer le graphique 

createChart('#thiscanvasid', 'bar', json.labels, json.datasets);
0
Chris