chart.js memuat data yang benar-benar baru

89

API untukchart.js memungkinkan seseorang mengedit titik set data yang dimuat ke dalamnya, misalnya:

.update( )

Memanggil update () pada instance Chart Anda akan merender ulang grafik dengan nilai yang diperbarui, memungkinkan Anda untuk mengedit nilai dari beberapa titik yang ada, kemudian merendernya dalam satu animasi render loop.

.addData( valuesArray, label )

Memanggil addData (valuesArray, label) pada instance Chart Anda dengan meneruskan array nilai untuk setiap dataset, bersama dengan label untuk titik-titik tersebut.

.removeData( )

Memanggil removeData () pada instance Chart Anda akan menghapus nilai pertama untuk semua set data pada diagram.

Semua ini bagus, tetapi saya tidak tahu cara memuat kumpulan data yang benar-benar baru, menghapus yang lama. Dokumentasi tampaknya tidak mencakup ini.

dthree
sumber

Jawaban:

100

Saya punya masalah besar dengan ini

Pertama saya mencoba .clear()kemudian saya mencoba .destroy()dan saya mencoba mengatur referensi grafik saya ke null

Apa yang akhirnya memperbaiki masalah bagi saya: menghapus <canvas>elemen lalu menambahkan kembali yang baru <canvas>ke penampung induk


Ada jutaan cara untuk melakukan ini:

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);
};
neaumusik
sumber
20
Jawaban ini berfungsi, tetapi saya menemukan kehancuran juga berfungsi di versi terbaru. Direkomendasikan di posting ini - github.com/nnnick/Chart.js/issues/559
HockeyJ
itu akan membantu mengosongkan div wadah-grafik untuk menghapus iframe lama $ ('# results-graph'). remove (); $ ('# graph-container']. empty (); $ ('# graph-container'). append ('<canvas id = "results-graph"> <canvas>');
heyyan khan
66

Anda perlu menghancurkan:

myLineChart.destroy();

Kemudian inisialisasi ulang bagan:

var ctx = document.getElementById("myChartLine").getContext("2d");
myLineChart = new Chart(ctx).Line(data, options);
khrizenriquez.dll
sumber
2
gunakan saja seperti ini if ​​(window.myLine) {window.myLine.destroy (); } ATAU jika (myLineChart) {myLineChart.destroy (); }
jayant singh
Dapat mengonfirmasi bahwa penghancuran kemudian inisialisasi ulang tidak menyebabkan kedipan apa pun dan sepertinya titik data diperbarui secara dinamis
Titan
40

Dengan Chart.js V2.0 Anda dapat melakukan hal berikut:

websiteChart.config.data = some_new_data;
websiteChart.update();
moonflash
sumber
18
Persis apa yang diminta op.
Perry
2
Ketika saya melakukannya chart.config.data = newData, saya mengalami kesalahan ini: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') Seseorang memiliki masalah yang sama?
Benjamin Lucidarme
22

Ini adalah utas lama, tetapi dalam versi saat ini (mulai 1-feb-2017), mudah untuk mengganti kumpulan data yang diplot di chart.js:

misalkan nilai sumbu x baru Anda dalam larik x dan nilai sumbu y dalam larik y, Anda dapat menggunakan kode di bawah ini untuk memperbarui bagan.

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

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

chart.update();
pavan kumar
sumber
Terima kasih banyak, Man! Terbuang sepanjang hari. Akhirnya tersandung pada jawaban Anda. Terima kasih.
Dronacharya
Ini sangat membantu dan berhasil untuk saya. Bahkan hanya menggunakan [] untuk menyetel kumpulan data kosong, dan kemudian melakukan "push" baru akan melakukan triknya juga.
TS
17

ChartJS 2.6 mendukung penggantian referensi data (lihat Catatan dalam dokumentasi update (config)). Jadi ketika Anda memiliki Bagan Anda, pada dasarnya Anda bisa melakukan ini:

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

Itu tidak melakukan animasi yang Anda dapatkan dari menambahkan titik, tetapi titik yang ada pada grafik akan dianimasikan.

Felix Jassler
sumber
12

Solusi saya untuk ini cukup sederhana. (VERSI 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 ...

Tidak ada kedipan atau masalah. getDataSetadalah fungsi untuk mengontrol kumpulan data apa yang perlu saya sajikan

Henrique C.
sumber
Bisakah Anda menambahkan cuplikan kode getDataSet () juga?
Perhitungan Gotham
1
Menambahkan contoh getDataSet ()
Henrique C.
6

Menurut dokumen, clear()bersihkan kanvas. Anggap saja sebagai alat Penghapus di Paint. Ini tidak ada hubungannya dengan data yang saat ini dimuat dalam contoh grafik.

Menghancurkan instance dan membuat yang baru itu sia-sia. Sebagai gantinya, gunakan metode API removeData()dan addData(). Ini akan menambah / menghapus satu segmen ke / dari contoh grafik. Jadi jika Anda ingin memuat data yang benar-benar baru, cukup putar larik data bagan, dan panggil removeData(index)(indeks larik harus sesuai dengan indeks segmen saat ini). Kemudian, gunakan addData(index)untuk mengisinya dengan data baru. Saya sarankan untuk membungkus dua metode untuk perulangan data, karena mereka mengharapkan indeks segmen tunggal. Saya menggunakan resetChartdan updateChart. Sebelum melanjutkan, pastikan Anda memeriksa Chart.jsversi dan dokumentasi terbaru. Mereka mungkin telah menambahkan metode baru untuk mengganti data sepenuhnya .

adi518
sumber
3
Saya suka jawaban Anda dan konsisten dengan informasi yang saya baca online. Jika Anda dapat menunjukkan dan memberi contoh, itu akan sangat membantu. Dua contoh yang saya lihat online yang serupa adalah: jsbin.com/yitep/5/edit?html,js,output dan jsbin.com/yitep/4/edit?html,js,output
Rethabile
Satu-satunya masalah adalah memperbarui bagan menjadi sangat rumit dan sangat lambat jika Anda harus mengganti data bagan dengan kumpulan data yang sangat berbeda. Sebagai permulaan, saya belum menemukan cara untuk memperbarui label sumbu x yang ada . Menghancurkan dan memulihkan seluruh bagan adalah satu-satunya solusi nyata dalam keadaan seperti itu.
menipu
Sayangnya, saya hanya berurusan dengan bagan Donat, yang tidak terlalu rumit. Apakah Anda memeriksa API terbaru?
adi518
4

Saya mengalami masalah yang sama, saya memiliki 6 diagram lingkaran di halaman yang semuanya dapat diperbarui pada waktu yang sama. Saya menggunakan fungsi berikut untuk mengatur ulang data grafik.

// 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
sumber
Sementara ini berfungsi, saya menemukan bahwa itu jauh lebih lambat (karena animasi saat menambahkan setiap titik) dibandingkan dengan membuat ulang grafik sama sekali.
Danila Vershinin
3

Saya mencoba solusi neaumus , tetapi kemudian menemukan bahwa satu - satunya masalah dengan penghancuran adalah ruang lingkupnya .

var chart;

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

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

Memindahkan variabel bagan saya di luar ruang lingkup fungsi, membuatnya berfungsi untuk saya.

lony
sumber
3

Tak satu pun dari jawaban di atas membantu situasi khusus saya dengan cara yang sangat bersih dengan kode minimal. Saya perlu menghapus semua dataset dan kemudian mengulang untuk menambahkan beberapa dataset secara dinamis. Jadi potongan ini untuk mereka yang berhasil sampai ke bagian bawah halaman tanpa menemukan jawabannya :)

Catatan: pastikan untuk memanggil chart.update () setelah Anda memuat semua data baru Anda ke dalam objek dataset. Semoga ini bisa membantu seseorang

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

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

Anda perlu membersihkan data lama. Tidak perlu menginisialisasi ulang:

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

Jika ada yang mencari cara melakukan ini di React. Untuk linechart, dengan asumsi Anda memiliki komponen pembungkus di sekitar diagram:

(Ini mengasumsikan Anda menggunakan v2. Anda tidak perlu menggunakan react-chartjs. Ini menggunakan chart.jspaket normal dari 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>
  );
}

The componentDidUpdatefungsi memungkinkan Anda untuk memperbarui, menambah, atau menghapus data dari this.props.data.

Matthew Herbst
sumber
1

Tidak perlu merusak grafik. Coba dengan ini

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();
    }
Jose Andres Beltran Ruiz
sumber
1

Harap Pelajari cara kerja Chart.js (versi 2 di sini) dan lakukan untuk atribut apa pun yang Anda inginkan:


1. Misalkan Anda memiliki diagram batang seperti di bawah ini di HTML Anda:

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

2. Misalkan Anda memiliki kode javascript yang mengisi grafik Anda untuk pertama kali (misalnya saat halaman dimuat):

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

Misalkan Anda ingin memperbarui set data Anda sepenuhnya. Ini sangat sederhana. Silakan lihat kode di atas dan lihat bagaimana jalur dari variabel grafik Anda ke data dan kemudian ikuti jalur di bawah ini:

  • pilih chartInstancevar.
  • Kemudian pilih data nodedi dalam chartInstance.
  • Kemudian pilih datasets nodedi dalam data node.
    (catatan: Seperti yang Anda lihat, datasets nodeis adalah sebuah array. jadi Anda harus menentukan elemen mana dari array ini yang Anda inginkan. di sini kita hanya memiliki satu elemen di datasets node. jadi kami menggunakandatasets[0]
  • Jadi pilih datasets[0]
  • Kemudian pilih data nodedi dalam datasets[0].


Langkah-langkah ini memberi Anda chartInstance.data.datasets[0].datadan Anda dapat mengatur data baru dan memperbarui grafik:

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


Catatan: Dengan mengikuti algoritma di atas, Anda dapat dengan mudah mencapai setiap node yang Anda inginkan .

Ghasem Sadeghi
sumber
0

Satu-satunya solusi yang dapat saya temukan sejauh ini untuk diri saya sendiri adalah menginisialisasi ulang bagan dari awal:

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

Namun ini tampaknya agak tipu bagi saya. Adakah solusi yang lebih baik dan lebih standar?

dthree
sumber
1
Ini cukup banyak berfungsi untuk saya kecuali Anda harus terlebih dahulu melakukan myLineChart.destroy () untuk menyingkirkan yang lama atau Anda akan memiliki flicker saat menggambar ulang.
pengguna3413723
0

Saya juga mengalami banyak masalah dengan ini. Saya memiliki data dan label dalam array terpisah kemudian saya menginisialisasi ulang data grafik. Saya menambahkan baris.destroy (); seperti yang disarankan di atas yang telah berhasil

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

Paul
sumber
0

Ada adalah cara untuk melakukan hal ini tanpa membersihkan kanvas atau mulai lagi dari awal, tapi Anda harus pria pegangan penciptaan grafik sehingga data tersebut dalam format yang sama ketika Anda memperbarui.

Inilah cara saya melakukannya.

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

Saya pada dasarnya membuang data yang dimuat saat pembuatan, dan kemudian mereformasi dengan metode tambah data. Ini berarti saya kemudian dapat mengakses semua poin. Setiap kali saya mencoba mengakses struktur data yang dibuat oleh:

Chart(ctx).Bar(dataNew);

perintah, saya tidak dapat mengakses apa yang saya butuhkan. Ini berarti Anda dapat mengubah semua titik data, dengan cara yang sama seperti Anda membuatnya, dan juga memanggil update () tanpa menganimasikan sepenuhnya dari awal.

Simon Unsworth
sumber
0

Bagan JS 2.0

Cukup setel chart.data.labels = [];

Sebagai contoh:

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
sumber
0

Saat membuat objek bagan, Anda perlu menyimpan instance dalam variabel.

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

Dan sebelum memuat data baru, Anda perlu menghancurkannya :

currentChart.destroy();
omzer
sumber