chart.jsはまったく新しいデータをロードします


87

のAPIをchart.js使用すると、ロードされたデータセットのポイントを編集できます。次に例を示します。

.update( )

Chartインスタンスでupdate()を呼び出すと、更新された値でグラフが再レンダリングされ、既存の複数のポイントの値を編集して、それらを1つのアニメーションレンダリングループでレンダリングできます。

.addData( valuesArray, label )

ChartインスタンスでaddData(valuesArray、label)を呼び出して、各データセットの値の配列とそれらのポイントのラベルを渡します。

.removeData( )

ChartインスタンスでremoveData()を呼び出すと、チャート上のすべてのデータセットの最初の値が削除されます。

これらはすべて素晴らしいですが、古いデータセットを一掃して、まったく新しいデータセットを読み込む方法がわかりません。ドキュメントはこれをカバーしていないようです。

回答:


98

私はこれに大きな問題を抱えていました

最初に試し.clear()、次に.destroy()試し、チャート参照をnullに設定してみました

最終的に問題を修正したのは、<canvas>要素を削除して<canvas>から、親コンテナに新しい要素を再追加することです。


これを行うには、100万通りの方法があります。

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
この答えは機能しますが、destroyは最新バージョンでも機能することがわかりました。-この記事で推奨github.com/nnnick/Chart.js/issues/559
HockeyJ

グラフコンテナdivを空にして、古いiframeを削除するのに役立ちます$( '#results-graph')。remove(); $( '#graph-container')。empty(); $( '#graph-container')。append( '<canvas id = "results-graph"> <canvas>');
heyyan khan 2017

66

あなたは破壊する必要があります:

myLineChart.destroy();

次に、チャートを再初期化します。

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

2
if(window.myLine){window.myLine.destroy();のように使用してください。}またはif(myLineChart){myLineChart.destroy(); }
jayant singh 2016

破棄を確認してから再初期化してもちらつきは発生せず、データポイントが動的に更新されたように見えます
Titan

40

Chart.js V2.0を使用すると、次のことができます。

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

18
まさに作戦が求めたもの。
ペリー

2
私がそうするときchart.config.data = newData、私はこのエラーを持っています:TypeError: undefined is not an object (evaluating 'i.data.datasets.length') 誰かが同じ問題を抱えていますか?
ベンジャミンルシダルメ2017

21

これは古いスレッドですが、現在のバージョン(2017年2月1日現在)では、chart.jsにプロットされたデータセットを簡単に置き換えることができます。

新しいx軸の値が配列xにあり、y軸の値が配列yにあるとすると、以下のコードを使用してグラフを更新できます。

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

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

chart.update();

トンありがとう、男!一日中無駄になりました。ついにあなたの答えに出くわしました。ありがとうございました。
Dronacharya

これは役に立ち、私にとってはうまくいきました。[]を使用して空のデータセットを設定し、新しい「プッシュ」を実行するだけでも、このトリックは実行されます。
TS

17

ChartJS 2.6は、データ参照の置換をサポートしています(update(config)ドキュメントのを参照)。したがって、チャートがある場合は、基本的に次のようにすることができます。

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

ポイントを追加することで得られるアニメーションは実行されませんが、グラフ上の既存のポイントはアニメーション化されます。


12

これに対する私の解決策は非常に簡単です。(バージョン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 ...

ちらつきや問題はありません。getDataSet提示する必要のあるデータセットを制御する関数です


getDataSet()のコードスニペットも追加できますか?
Gotham's Reckoning 2016年

1
getDataSet()の例を追加
Henrique C.

8

私はここでこれに答えました。ホバーイベントをトリガーできないようにキャンバスからチャートをクリアする方法を参照してください

しかし、ここに解決策があります:

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

ドキュメントによるとclear()、キャンバスをクリアします。ペイントの消しゴムツールと考えてください。チャートインスタンスに現在ロードされているデータとは何の関係もありません。

インスタンスを破棄して新しいインスタンスを作成するのは無駄です。代わりに、APIメソッドremoveData()とを使用してくださいaddData()。これらは、チャートインスタンスに/から単一のセグメントを追加/削除します。したがって、完全に新しいデータをロードする場合は、グラフのデータ配列をループして呼び出しますremoveData(index)(配列インデックスは現在のセグメントインデックスに対応している必要があります)。次に、を使用addData(index)して新しいデータを入力します。単一のセグメントインデックスを想定しているため、データをループする2つのメソッドをラップすることをお勧めします。私は使用resetChartupdateChartます。続行する前に、Chart.js最新バージョンとドキュメントを確認してください。データを完全に置き換えるための新しい方法が追加された可能性があります


3
私はあなたの答えが好きで、私がオンラインで読んでいる情報と一致しています。あなたが示すことができて、例を示すことができれば、それは本当に役に立ちます。私がオンラインで見た類似の2つの例は、jsbin.com / yitep
html

唯一の問題は、グラフデータを本質的に完全に異なるデータセットに置き換える必要がある場合、グラフの更新が非常に面倒で非常に遅くなることです。手始めに、既存のx軸ラベルを更新する方法が見つかりませんでした。このような状況では、チャート全体を破棄して再インスタンス化することが唯一の実際の解決策です。
–deceze

残念ながら、私はドーナツグラフしか扱っていませんでした。これはそれほど複雑ではありません。最新のAPIをチェックしましたか?
adi518 2016

4

同じ問題が発生しました。1ページに6つの円グラフがあり、すべて同時に更新できます。次の関数を使用してチャートデータをリセットしています。

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


これは機能しますが、グラフを完全に再作成する場合に比べて(各ポイントを追加するときのアニメーションのために)はるかに遅いことがわかりました。
Danila Vershinin 2015年

3

neaumusicソリューションを試しましたが、後で、destroy唯一の問題はスコープであることがわかりました。

var chart;

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

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

チャート変数を関数スコープの外に移動して、機能させました。


3

上記の答えはどれも、最小限のコードで非常にクリーンな方法で私の特定の状況を助けませんでした。すべてのデータセットを削除してから、ループして複数のデータセットを動的に追加する必要がありました。したがって、これは、答えを見つけることなくページの一番下まで到達する人のためのものです:)

注:すべての新しいデータをデータセットオブジェクトにロードしたら、必ずchart.update()を呼び出してください。これが誰かに役立つことを願っています

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

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

2

古いデータをクリーンアップする必要があります。再初期化する必要はありません:

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

1

誰かがReactでこれを行う方法を探しているなら。折れ線グラフの場合、グラフの周りにラッパーコンポーネントがあると仮定します。

(これは、v2を使用していることを前提としています。使用する必要はありませんreact-chartjs。これはchart.jsnpmの通常のパッケージを使用しています。)

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

このcomponentDidUpdate機能を使用すると、からデータを更新、追加、または削除できますthis.props.data


1

チャートを破壊する必要はありません。これで試してください

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

Chart.js(ここではバージョン2)がどのように機能するかを学び、必要な属性に対してそれを実行してください。


1.HTMLに次のような棒グラフがあるとします。

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

2.チャートを最初に埋めるjavascriptコードがあると仮定してください(たとえば、ページがロードされたとき):

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

データセットを完全に更新したいとします。とても簡単です。上記のコードを見て、チャート変数からデータへのパスがどのようになっているのかを確認してから、以下のパスに従ってください。

  • chartInstancevarを選択します。
  • 次に、data node内を選択しますchartInstance
  • 次に、datasets node内を選択しますdata node
    (注:ご覧のとおり、これdatasets nodeは配列です。したがって、この配列のどの要素が必要かを指定する必要があります。ここでは、要素が1つしかないdatasets nodeため、を使用します。datasets[0]
  • だから選択 datasets[0]
  • 次に、でdata node内部を選択しますdatasets[0]


この手順によりchartInstance.data.datasets[0].data、新しいデータを設定してグラフを更新できます。

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


注: 上記のアルゴリズムに従うことで、必要な各ノードに簡単に到達できます


0

私がこれまでに見つけた唯一の解決策は、チャートを最初から再初期化することです。

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

しかし、これは私には少し厄介なようです。より良い、より標準的なソリューションはありますか?


1
これは、古いものを取り除くために最初にmyLineChart.destroy()を実行する必要があることを除いて、私にとってはほとんど機能します。そうしないと、再描画時にちらつきが発生します。
user3413723 2014

0

私もこれでたくさんのトラブルを抱えていました。データとラベルが別々の配列にあるので、グラフデータを再初期化します。line.destroy();を追加しました。上で示唆したように、それはトリックをしました

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


0

キャンバスをクリアしたり、最初からやり直したりせずにこれを行う方法あります、更新時にデータが同じ形式になるように、グラフの作成を手動で処理する必要があります。

これが私がそれをした方法です。

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

基本的に、作成時に読み込まれたデータを廃棄してから、adddataメソッドでリフォームします。これは、すべてのポイントにアクセスできることを意味します。次の方法で作成されたデータ構造にアクセスしようとしたときはいつでも:

Chart(ctx).Bar(dataNew);

コマンド、必要なものにアクセスできません。つまり、作成したのと同じ方法ですべてのデータポイントを変更でき、完全に最初からアニメーション化することなくupdate()を呼び出すこともできます。


0

チャートJS2.0

chart.data.labels = [];を設定するだけです。

例えば:

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

チャートオブジェクトを作成するときは、インスタンスを変数に保存する必要があります。

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

そして、新しいデータをロードする前に、それを破棄する必要があります。

currentChart.destroy();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.