chart.js charge des données totalement nouvelles

87

L'API pourchart.js permet d'éditer les points des ensembles de données qui y sont chargés, par exemple:

.update( )

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

.addData( valuesArray, label )

Appel de 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 de graphique supprimera la première valeur de tous les ensembles de données du graphique.

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

trois
la source

Réponses:

98

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 ma référence de graphique sur null

Ce qui a finalement résolu le problème pour moi: supprimer l' <canvas>élément, puis en réappliquer un nouveau <canvas>au conteneur parent


Il y a un million de façons de faire cela:

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);
};
neaumusic
la source
20
Cette réponse fonctionne, mais j'ai trouvé que destroy fonctionne également dans la dernière version. Recommandé sur ce post - github.com/nnnick/Chart.js/issues/559
HockeyJ
cela aiderait à vider le div du conteneur de graphes pour supprimer les anciennes iframes $ ('# results-graph'). remove (); $ ('# graph-container'). empty (); $ ('# graph-container'). append ('<canvas id = "results-graph"> <canvas>');
heyyan khan
66

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);
Khrizenriquez
la source
2
utilisez-le simplement comme ceci if (window.myLine) {window.myLine.destroy (); } OU si (myLineChart) {myLineChart.destroy (); }
jayant singh
Peut confirmer que la destruction, puis la réinitialisation ne provoque aucun scintillement et semble que les points de données ont été mis à jour dynamiquement
Titan
40

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

websiteChart.config.data = some_new_data;
websiteChart.update();
éclair de lune
la source
18
Exactement ce que l'op a demandé.
Perry
2
Quand je le fais chart.config.data = newData, j'ai cette erreur: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') Quelqu'un a le même problème?
Benjamin Lucidarme
21

Il s'agit d'un ancien fil de discussion, mais dans la version actuelle (au 1er février 2017), il est facile de remplacer les ensembles de données tracés sur chart.js:

supposons que vos nouvelles valeurs de l'axe des x soient dans le tableau x et les valeurs de l'axe des y 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();
Pavan Kumar
la source
Merci beaucoup, mec! Gaspillé toute la journée. Enfin tombé sur votre réponse. Merci.
Dronacharya
Cela a été utile et a fonctionné pour moi. Même simplement utiliser [] pour définir un ensemble de données vide, puis faire un nouveau "push" fera également l'affaire.
TS
17

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

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

Il ne fait pas l'animation que vous obtenez en ajoutant des points, mais les points existants sur le graphique seront animés.

Felix Jassler
la source
12

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 ni de problèmes. getDataSetest une fonction pour contrôler quel jeu de données je dois présenter

Henrique C.
la source
Pouvez-vous également ajouter l'extrait de code de getDataSet ()?
Gotham's Reckoning
1
Ajout de l'exemple getDataSet ()
Henrique C.
6

Selon la documentation, clear() efface la toile. Considérez-le comme l'outil Gomme de 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 un gaspillage. Utilisez plutôt les méthodes API removeData()et addData(). Ceux-ci ajouteront / supprimeront un seul segment de / vers l'instance de graphique. Donc, si vous voulez charger des données complètement nouvelles, 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 index de segment unique. J'utilise resetChartet updateChart. Avant de continuer, assurez-vous de vérifier la Chart.jsdernière version et la documentation. Ils peuvent avoir ajouté de nouvelles méthodes pour remplacer complètement les données .

adi518
la source
3
J'aime votre réponse et elle est cohérente avec les informations que j'ai lues en ligne. Si vous êtes en mesure de montrer et d'exemple, ce serait vraiment utile. Les deux exemples similaires que j'ai vus en ligne sont: jsbin.com/yitep/5/edit?html,js,output et jsbin.com/yitep/4/edit?html,js,output
Rethabile
Le seul problème est que la mise à jour d'un graphique devient extrêmement lourde et très lente si vous devez remplacer les données du graphique par un ensemble de données complètement différent. Pour commencer, je n'ai pas trouvé de moyen de mettre à jour les étiquettes de l' axe des x existantes . La seule vraie solution dans de telles circonstances est de détruire et de rétablir l'intégralité du graphique.
deceze
Malheureusement, je n'ai traité que d'un graphique en anneau, qui est moins complexe. Avez-vous vérifié la dernière API?
adi518
4

J'ai rencontré le même problème, j'ai 6 graphiques à secteurs 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();

Piper0804
la source
Bien que cela fonctionne, j'ai trouvé que c'était beaucoup plus lent (en raison de l'animation lors de l'ajout de chaque point) par rapport à la recréation du graphique.
Danila Vershinin le
3

J'ai essayé une 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 la portée de la fonction, cela a fonctionné pour moi.

solitaire
la source
3

Aucune des réponses ci-dessus n'a aidé ma situation particulière d'une manière très propre avec un code minimal. J'avais besoin de supprimer tous les ensembles de données, puis de boucler pour ajouter plusieurs ensembles de données de manière dynamique. Donc, cet extrait est pour ceux qui arrivent 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 l'ensemble de données. J'espère que cela aide quelqu'un

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

function addData(chart, data) {
  chart.data.datasets.push(data);
}
Connor Crawford
la source
2

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

for (i in myChartLine.datasets[0].points)
    myChartLine.removeData();
Farsheed
la source
1

Si quelqu'un cherche comment faire cela dans React. Pour un graphique en ligne, en supposant que vous ayez un composant wrapper autour du graphique:

(Cela suppose que vous utilisez v2. Vous n'avez pas besoin d'utiliser react-chartjs. Cela utilise le chart.jspackage normal 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 componentDidUpdatefonctionnalité vous permet de mettre à jour, d'ajouter ou de supprimer des données du this.props.data.

Matthew Herbst
la source
1

Il n'est pas nécessaire de détruire le graphique. Essayez avec ça

function removeData(chart) {

        let total = chart.data.labels.length;

        while (total >= 0) {
            chart.data.labels.pop();
            chart.data.datasets[0].data.pop();
            total--;
        }

        chart.update();
    }
José Andres Beltran Ruiz
la source
1

Veuillez apprendre comment Chart.js (version 2 ici) fonctionne et faites-le pour l'attribut que vous voulez:


1.Veuillez supposer que vous avez un graphique à barres comme celui ci-dessous dans votre HTML:

<canvas id="your-chart-id" height="your-height" width="your-width"></canvas>

2.Veuillez supposer que vous avez un code javascript qui remplit votre graphique pour la première fois (par exemple lorsque la page est chargée):

var ctx = document.getElementById('your-chart-id').getContext('2d');
var chartInstance = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: your-lables-array,
        datasets: [{
            data: your-data-array,
            /*you can create random colors dynamically by ColorHash library [https://github.com/zenozeng/color-hash]*/
            backgroundColor: your-lables-array.map(function (item) {
                return colorHash.hex(item);
            })
        }]
    },
    options: {
        maintainAspectRatio: false,
        scales: {
            yAxes: [ { ticks: {beginAtZero: true} } ]
        },
        title: {display: true, fontSize: 16, text: 'chart title'},
        legend: {display: false}
    }
});

Supposons que vous souhaitiez mettre à jour complètement votre ensemble de données. C'est très simple. Veuillez regarder le code ci-dessus et voir comment est le chemin de votre variable de graphique aux données, puis suivez le chemin ci-dessous:

  • sélectionnez chartInstancevar.
  • Sélectionnez ensuite data nodedans le fichier chartInstance.
  • Sélectionnez ensuite datasets nodedans le fichier data node.
    (note: comme vous pouvez le voir, le datasets nodeest un tableau. vous devez donc spécifier quel élément de ce tableau vous voulez. ici, nous n'avons qu'un seul élément dans le datasets node. donc nous utilisonsdatasets[0]
  • Alors sélectionnez datasets[0]
  • Ensuite, sélectionnez à l' data nodeintérieur dans le datasets[0].


Cette étape vous donne chartInstance.data.datasets[0].dataet vous pouvez définir de nouvelles données et mettre à jour le graphique:

chartInstance.data.datasets[0].data = NEW-your-data-array
//finally update chart var:
chartInstance.update();


Remarque: En suivant l'algorithme ci-dessus, vous pouvez simplement atteindre chaque nœud souhaité .

Ghasem Sadeghi
la source
0

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

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

Cependant, cela me semble un peu hokey. Quelqu'un de meilleure solution plus standard?

trois
la source
1
Cela fonctionne à peu près pour moi sauf que vous devez d'abord faire myLineChart.destroy () pour vous débarrasser de l'ancien ou vous aurez un scintillement pendant qu'il se redessine.
user3413723
0

J'ai eu beaucoup de problèmes avec ça 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 l'affaire

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

Paul
la source
0

Il existe un moyen de le faire sans effacer le canevas ou recommencer, mais vous devez gérer la création du graphique afin que les données soient dans le même format lorsque vous mettez à 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;
        }

Je supprime essentiellement les données chargées lors de la création, puis je les reforme avec la méthode d'ajout de données. 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 également appeler update () sans animer complètement à partir de zéro.

Simon Unsworth
la source
0

Graphique JS 2.0

Définissez simplement 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();
Kevin van Boeckholtz
la source
0

Lors de la création de l'objet graphique, vous devez enregistrer l'instance dans une variable.

var currentChart = new Chart(ctx, ...);

Et avant de charger de nouvelles données, vous devez les détruire :

currentChart.destroy();
Omzer
la source