web-dev-qa-db-fra.com

chart.js charge des données totalement nouvelles

L'API pour chart.js permet d'éditer des points des jeux de données chargés dans celle-ci, par exemple:

.update( )

L'appel de update () sur votre instance Chart rendra à nouveau le graphique avec les valeurs mises à jour, vous permettant ainsi de modifier la valeur de plusieurs points existants, puis de les restituer dans une boucle de rendu animée.

.addData( valuesArray, label )

Appelez addData (valuesArray, label) sur votre instance Chart en transmettant un tableau de valeurs pour chaque ensemble de données, ainsi qu'une étiquette pour ces points.

.removeData( )

L'appel de removeData () sur votre instance Chart supprimera la première valeur de tous les jeux de données du graphique.

Tous ces éléments sont excellents, mais je ne peux pas comprendre comment charger un jeu de données entièrement nouveau, en effaçant l'ancien. La documentation ne semble pas couvrir cela.

76
dthree

J'ai eu d'énormes problèmes avec ça

J'ai d'abord essayé .clear() puis j'ai essayé .destroy() et j'ai essayé de définir la référence de mon graphique sur null

Ce qui a finalement résolu le problème pour moi: supprimer l’élément <canvas> puis ré-ajouter un nouveau <canvas> au conteneur parent


Il y a un million de manières de faire ceci:

var resetCanvas = function () {
  $('#results-graph').remove(); // this is my <canvas> element
  $('#graph-container').append('<canvas id="results-graph"><canvas>');
  canvas = document.querySelector('#results-graph'); // why use jQuery?
  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);
};
89
neaumusic

Vous devez détruire:

myLineChart.destroy();

Puis réinitialisez le graphique:

var ctx = document.getElementById("myChartLine").getContext("2d");
myLineChart = new Chart(ctx).Line(data, options);
57
khrizenriquez

Avec Chart.js V2.0, vous pouvez effectuer les opérations suivantes:

websiteChart.config.data = some_new_data;
websiteChart.update();
35
moonflash

C'est un vieux fil, mais dans la version actuelle (à partir du 1-février 2017), il est facile de remplacer les jeux de données tracés sur chart.js:

supposons que vos nouvelles valeurs d'axe x soient dans le tableau et que les valeurs d'axe y soient dans le tableau y, vous pouvez utiliser le code ci-dessous pour mettre à jour le graphique.

var x = [1,2,3];
var y = [1,1,1];

chart.data.datasets[0].data = y;
chart.data.labels = x;

chart.update();
16
pavan kumar

ChartJS 2.6 prend en charge le remplacement de référence de données (voir Remarque dans la documentation de mise à jour (config)). Ainsi, lorsque vous avez votre graphique, vous pouvez essentiellement faire ceci:

myChart.data.labels = ['1am', '2am', '3am', '4am'];
myChart.data.datasets[0].data = [0, 12, 35, 36];
myChart.update();

L’animation obtenue par l’ajout de points n’est pas animée, mais les points existants du graphique sont animés.

11
Felix Jassler

Ma solution à cela est assez simple. (VERSION 1.X)

getDataSet:function(valuesArr1,valuesArr2){
        var dataset = [];
        var arr1 = {
            label: " (myvalues1)",
            fillColor: "rgba(0, 138, 212,0.5)",
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(0, 138, 212,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: valuesArr1
        };
        var arr2 = {
            label: " (myvalues2)",
            fillColor: "rgba(255, 174, 087,0.5)",
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(255, 174, 087,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: valuesArr2
        };
        /*Example conditions*/
        if(condition 1)
          dataset.Push(arr1);
        }
        if(condition 2){
          dataset.Push(arr1);
          dataset.Push(arr2);
        }

        return dataset;
    }

var data = {
    labels: mylabelone,
    datasets: getDataSet()
};
if(myBarChart != null) // i initialize myBarChart var with null
    myBarChart.destroy(); // if not null call destroy
    myBarChart = new Chart(ctxmini).Bar(data, options);//render it again ...

Pas de scintillement ou de problèmes. getDataSet est une fonction permettant de contrôler le jeu de données à présenter.

11
Henrique C.

J'ai répondu à cette question ici Comment effacer un graphique d'un canevas afin que des événements de survol ne puissent pas être déclenchés?

Mais voici la solution:

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

Selon la documentation, clear() efface le canevas. Considérez-le comme l'outil Gomme dans Paint. Cela n'a rien à voir avec les données actuellement chargées dans l'instance de graphique.

Détruire l'instance et en créer une nouvelle est une perte de temps. Utilisez plutôt les méthodes API removeData() et addData(). Ceux-ci ajouteront/supprimeront un seul segment vers/depuis l'instance de graphique. Ainsi, si vous souhaitez charger de nouvelles données, bouclez simplement un tableau de données de graphique et appelez removeData(index) (les index de tableau doivent correspondre aux index de segment actuels). Ensuite, utilisez addData(index) pour le remplir avec les nouvelles données. Je suggère d'encapsuler les deux méthodes pour boucler les données, car elles s'attendent à un seul index de segment. J'utilise resetChart et updateChart. Avant de continuer, assurez-vous de vérifier Chart.js dernière version et documentation. Ils ont peut-être ajouté de nouvelles méthodes pour remplacer complètement les données.

6
adi518

J'ai rencontré le même problème, j'ai 6 graphiques circulaires sur une page qui peuvent tous être mis à jour en même temps. J'utilise la fonction suivante pour réinitialiser les données du graphique.

// sets chart segment data for previously rendered charts
function _resetChartData(chart, new_segments) {
    // remove all the segments
    while (chart.segments.length) {
        chart.removeData();
    };

    // add the new data fresh
    new_segments.forEach (function (segment, index) {
        chart.addData(segment, index);
    });
};

// when I want to reset my data I call
_resetChartData(some_chart, new_data_segments);
some_chart.update();
4
Piper0804

J'ai essayé la solution neaumusic , mais j'ai découvert plus tard que le seul problème avec destroy est la portée .

var chart;

function renderGraph() {
    // Destroy old graph
    if (chart) {
        chart.destroy();
    }

    // Render chart
    chart = new Chart(
        document.getElementById(idChartMainWrapperCanvas),
        chartOptions
    );
}

Déplacer ma variable de graphique en dehors de l'étendue de la fonction l'a fait fonctionner pour moi.

3
lony

Vous devez nettoyer les anciennes données. Pas besoin de ré-initialiser:

for (i in myChartLine.datasets[0].points)
    myChartLine.removeData();
2
Farsheed

Aucune des réponses ci-dessus n'a aidé ma situation particulière de manière très propre avec un code minimal. J'avais besoin de supprimer tous les jeux de données, puis de boucler pour ajouter plusieurs jeux de données de manière dynamique. Donc, cette partie est destinée à ceux qui se rendent jusqu'au bas de la page sans trouver leur réponse :)

Remarque: assurez-vous d'appeler chart.update () une fois que vous avez chargé toutes vos nouvelles données dans l'objet de jeu de données. J'espère que ça aide quelqu'un

function removeData(chart) {
   chart.data.datasets.length = 0;
}

function addData(chart, data) {
  chart.data.datasets.Push(data);
}
2
Connor Crawford

Si quelqu'un cherche comment faire cela dans React. Pour un graphique linéaire, supposons que vous ayez un composant wrapper autour du graphique:

(Cela suppose que vous utilisez la version 2. Vous n'avez pas besoin d'utiliser react-chartjs. Cela utilise le paquetage normal chart.js de npm.)

propTypes: {
  data: React.PropTypes.shape({
    datasets: React.PropTypes.arrayOf(
      React.PropTypes.shape({

      })
    ),
    labels: React.PropTypes.array.isRequired
  }).isRequired
},
componentDidMount () {
  let chartCanvas = this.refs.chart;

  let myChart = new Chart(chartCanvas, {
    type: 'line',
    data: this.props.data,
    options: {
      ...
    }
  });

  this.setState({chart: myChart});
},
componentDidUpdate () {
    let chart = this.state.chart;
    let data = this.props.data;

    data.datasets.forEach((dataset, i) => chart.data.datasets[i].data = dataset.data);

    chart.data.labels = data.labels;
    chart.update();
},
render () {
  return (
    <canvas ref={'chart'} height={'400'} width={'600'}></canvas>
  );
}

La fonctionnalité componentDidUpdate vous permet de mettre à jour, d'ajouter ou de supprimer des données de this.props.data.

1
Matthew Herbst

Il y a est un moyen de le faire sans vider le canevas ou tout recommencer, mais vous devez gérer la création du graphique pour que les données soient au même format que lors de la mise à jour.

Voici comment je l'ai fait.

    var ctx = document.getElementById("myChart").getContext("2d");
    if (chartExists) {
        for (i=0;i<10;i++){
            myNewChart.scale.xLabels[i]=dbLabels[i]; 
            myNewChart.datasets[0].bars[i].value=dbOnAir[i];
        }
        myNewChart.update();
      }else{
          console.log('chart doesnt exist');
          myNewChart = new Chart(ctx).Bar(dataNew);
          myNewChart.removeData();
          for (i=0;i<10;i++){
              myNewChart.addData([10],dbLabels[i]);
          }
          for (i=0;i<10;i++){      
              myNewChart.datasets[0].bars[i].value=dbOnAir[i];
          }
          myNewChart.update();
          chartExists=true;
        }

En gros, je supprime les données chargées lors de la création, puis je reforme avec la méthode add data. Cela signifie que je peux alors accéder à tous les points. Chaque fois que j'ai essayé d'accéder à la structure de données créée par:

Chart(ctx).Bar(dataNew);

commande, je ne peux pas accéder à ce dont j'ai besoin. Cela signifie que vous pouvez modifier tous les points de données, de la même manière que vous les avez créés, et appeler update () sans aucune animation complète.

0
Simon Unsworth

La seule solution que je puisse trouver jusqu'à présent pour moi-même consiste à réinitialiser le graphique à partir de zéro:

var myLineChart = new Chart(ctx).Line(data, options);

Cependant, cela me semble un peu hokey. Une meilleure solution, plus standard quelqu'un?

0
dthree

J'ai eu beaucoup de problèmes avec cela aussi. J'ai des données et des étiquettes dans des tableaux séparés, puis je réinitialise les données du graphique. J'ai ajouté le line.destroy (); comme suggéré ci-dessus qui a fait le tour

var ctx = document.getElementById("canvas").getContext("2d");
if(window.myLine){
        window.myLine.destroy();
}
window.myLine = new Chart(ctx).Line(lineChartData, {
  etc
  etc
0
Paul

Graphique JS 2.0

Il suffit de définir chart.data.labels = [];

Par exemple:

function addData(chart, label, data) {
    chart.data.labels.Push(label);
    chart.data.datasets.forEach((dataset) => {
       dataset.data.Push(data);
    });
    chart.update();
}

$chart.data.labels = [];

$.each(res.grouped, function(i,o) {
   addData($chart, o.age, o.count);
});
$chart.update();
0