chart.js carica dati completamente nuovi


89

L'API perchart.js consente di modificare i punti dei set di dati caricati al suo interno, ad esempio:

.update( )

La chiamata di update () sull'istanza del grafico eseguirà nuovamente il rendering del grafico con tutti i valori aggiornati, consentendo di modificare il valore di più punti esistenti, quindi renderizzarli in un ciclo di rendering animato.

.addData( valuesArray, label )

Chiamando addData (valuesArray, label) sull'istanza di Chart passando una matrice di valori per ogni set di dati, insieme a un'etichetta per quei punti.

.removeData( )

La chiamata a removeData () sull'istanza del grafico rimuoverà il primo valore per tutti i set di dati sul grafico.

Tutti questi sono fantastici, ma non riesco a capire come caricare un set di dati completamente nuovo, cancellando il vecchio. La documentazione non sembra coprire questo.

Risposte:


100

Ho avuto enormi problemi con questo

Prima ho provato .clear()poi ho provato.destroy() e ho provato a impostare il mio riferimento grafico su null

Cosa ha finalmente risolto il problema per me: eliminare l' <canvas>elemento e quindi riapplicarne uno nuovo <canvas>al contenitore padre


Ci sono un milione di modi per farlo:

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

20
Questa risposta funziona, ma ho scoperto che distruggi funziona anche nell'ultima versione. Consigliato in questo post - github.com/nnnick/Chart.js/issues/559
HockeyJ

sarebbe utile svuotare il div contenitore del grafico per rimuovere i vecchi iframe $ ('# risultato-grafico'). remove (); $ ('# contenitore-grafico'). empty (); $ ('# graph-container'). append ('<canvas id = "results-graph"> <canvas>');
heyyan khan

66

Devi distruggere:

myLineChart.destroy();

Quindi reinizializza il grafico:

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

2
usalo in questo modo se (window.myLine) {window.myLine.destroy (); } OPPURE if (myLineChart) {myLineChart.destroy (); }
jayant singh

Può confermare la distruzione, quindi la reinizializzazione non causa alcuno sfarfallio e sembra che i punti dati siano stati aggiornati dinamicamente
Titan

40

Con Chart.js V2.0 puoi fare quanto segue:

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

18
Esattamente quello che chiedeva l'operazione.
Perry

2
Quando lo faccio chart.config.data = newData, ho questo errore: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') Qualcuno ha lo stesso problema?
Benjamin Lucidarme

22

È un vecchio thread, ma nella versione corrente (a partire dal 1 febbraio 2017), è facile sostituire i set di dati tracciati su chart.js:

supponiamo che i nuovi valori dell'asse x siano nell'array xe i valori dell'asse y siano nell'array y, puoi usare il codice sottostante per aggiornare il grafico.

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

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

chart.update();

Grazie mille, amico! Sprecato tutto il giorno. Finalmente sono incappato nella tua risposta. Grazie.
Dronacharya

Questo è stato utile e ha funzionato per me. Anche solo usare [] per impostare un dataset vuoto e poi fare un nuovo "push" farà altrettanto.
TS

17

ChartJS 2.6 supporta la sostituzione dei dati di riferimento (vedere la nota nella documentazione di aggiornamento (configurazione)). Quindi, quando hai il tuo grafico, puoi fondamentalmente fare questo:

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

Non esegue l'animazione che otterresti aggiungendo punti, ma i punti esistenti sul grafico verranno animati.


12

La mia soluzione a questo è piuttosto semplice. (VERSIONE 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 ...

Nessuno sfarfallio o problemi. getDataSetè una funzione per controllare quale set di dati devo presentare


Puoi aggiungere anche lo snippet di codice di getDataSet ()?
Gotham's Reckoning

1
Aggiunto l'esempio getDataSet ()
Henrique C.


6

Secondo i documenti, clear()cancella la tela. Consideralo come lo strumento Gomma in Paint. Non ha nulla a che fare con i dati attualmente caricati nell'istanza del grafico.

Distruggere l'istanza e crearne una nuova è uno spreco. Utilizza invece metodi API removeData()e addData(). Questi aggiungeranno / rimuoveranno un singolo segmento alla / dall'istanza del grafico. Quindi, se si desidera caricare dati completamente nuovi, è sufficiente eseguire il ciclo di un array di dati del grafico e chiamare removeData(index)(gli indici degli array dovrebbero corrispondere agli indici dei segmenti correnti). Quindi, usa addData(index)per riempirlo con i nuovi dati. Suggerisco di racchiudere i due metodi per il ciclo dei dati, poiché si aspettano un indice di segmento singolo. Io uso resetCharte updateChart. Prima di continuare, assicurati di controllare la Chart.jsversione e la documentazione più recenti. Potrebbero aver aggiunto nuovi metodi per sostituire completamente i dati .


3
Mi piace la tua risposta ed è coerente con le informazioni che ho letto online. Se sei in grado di mostrare un esempio, sarebbe davvero utile. I due esempi che ho visto online che sono simili sono: jsbin.com/yitep/5/edit?html,js,output e jsbin.com/yitep/4/edit?html,js,output
Rethabile

L'unico problema è che l'aggiornamento di un grafico diventa estremamente macchinoso e super lento se devi sostituire i dati del grafico con essenzialmente un set di dati completamente diverso. Per i principianti, non ho trovato un modo per aggiornare le etichette dell'asse x esistenti . Distruggere e ristabilire l'intero grafico è l'unica vera soluzione in tali circostanze.
inganno

Sfortunatamente, mi sono occupato solo di un grafico ad anello, che è meno complesso. Hai controllato l'ultima API?
adi518

4

Mi sono imbattuto nello stesso problema, ho 6 grafici a torta su una pagina che possono essere aggiornati tutti allo stesso tempo. Sto usando la seguente funzione per ripristinare i dati del grafico.

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


Anche se funziona, ho scoperto che è molto più lento (a causa dell'animazione quando si aggiunge ogni punto) rispetto alla creazione totale del grafico.
Danila Vershinin

3

Ho provato la soluzione neaumusic , ma in seguito ho scoperto che l' unico problema con la distruzione è l'ambito .

var chart;

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

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

Spostando la mia variabile del grafico al di fuori dell'ambito della funzione, ha funzionato per me.


3

Nessuna delle risposte precedenti ha aiutato la mia situazione particolare in modo molto pulito con un codice minimo. Avevo bisogno di rimuovere tutti i set di dati e quindi eseguire il ciclo per aggiungere dinamicamente diversi set di dati. Quindi questo frammento è per coloro che arrivano fino in fondo alla pagina senza trovare la loro risposta :)

Nota: assicurati di chiamare chart.update () dopo aver caricato tutti i tuoi nuovi dati nell'oggetto dataset. Spero che questo aiuti qualcuno

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

function addData(chart, data) {
  chart.data.datasets.push(data);
}

2

Devi pulire i vecchi dati. Non è necessario reinizializzare:

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

1

Se qualcuno sta cercando come farlo in React. Per un grafico a linee, supponendo che tu abbia un componente wrapper attorno al grafico:

(Questo presuppone che tu stia usando v2. Non è necessario che tu lo usi react-chartjs. Questo sta usando il normale chart.jspacchetto di 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 componentDidUpdatefunzionalità consente di aggiornare, aggiungere o rimuovere qualsiasi dato dal file this.props.data.


1

Non è necessario distruggere il grafico. Prova con questo

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

1

Per favore, scopri come funziona Chart.js (versione 2 qui) e fallo per qualsiasi attributo tu voglia:


1. Supponi di avere un grafico a barre come il seguente nel tuo HTML:

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

2.Si prega di supporre di avere un codice javascript che riempie il grafico per la prima volta (ad esempio quando la pagina viene caricata):

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

Supponi di voler aggiornare completamente il tuo set di dati. È molto semplice. Si prega di guardare il codice sopra e vedere come è il percorso dalla variabile del grafico ai dati, quindi seguire il percorso seguente:

  • seleziona chartInstancevar.
  • Quindi seleziona data nodeall'interno del file chartInstance.
  • Quindi seleziona datasets nodeall'interno del file data node.
    (nota: come puoi vedere, datasets nodeè un array. quindi devi specificare quale elemento di questo array desideri. qui abbiamo solo un elemento in datasets node. quindi usiamodatasets[0]
  • Quindi seleziona datasets[0]
  • Quindi seleziona data nodeall'interno del file datasets[0].


Questo passaggio ti dà chartInstance.data.datasets[0].datae puoi impostare nuovi dati e aggiornare il grafico:

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


Nota: seguendo l'algoritmo di cui sopra, puoi semplicemente raggiungere ogni nodo che desideri .


0

L'unica soluzione che riesco a trovare finora per me stesso è reinizializzare il grafico da zero:

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

Tuttavia questo mi sembra un po 'sciocco. Qualcuno ha una soluzione migliore e più standard?


1
Questo praticamente funziona per me tranne che devi prima fare myLineChart.destroy () per sbarazzarti di quello vecchio o avrai uno sfarfallio mentre si ridisegna.
user3413723

0

Ho avuto un sacco di problemi anche con questo. Ho dati ed etichette in array separati, quindi reinizializzo i dati del grafico. Ho aggiunto la riga.destroy (); come suggerito sopra che ha fatto il trucco

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


0

è un modo per farlo senza cancellare la tela o ricominciare, ma si deve gestire l'uomo la creazione del grafico in modo che i dati sono nello stesso formato per quando si aggiorna.

Ecco come l'ho fatto.

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

Fondamentalmente elimino i dati caricati al momento della creazione, quindi riformulo con il metodo di aggiunta dei dati. Ciò significa che posso quindi accedere a tutti i punti. Ogni volta che ho provato ad accedere alla struttura dati che viene creata da:

Chart(ctx).Bar(dataNew);

comando, non riesco ad accedere a ciò di cui ho bisogno. Ciò significa che puoi modificare tutti i punti dati, nello stesso modo in cui li hai creati, e anche chiamare update () senza animare completamente da zero.


0

Grafico JS 2.0

Basta impostare chart.data.labels = [];

Per esempio:

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

Quando si crea l'oggetto grafico è necessario salvare l'istanza in una variabile.

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

E prima di caricare nuovi dati, devi distruggerli :

currentChart.destroy();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.