web-dev-qa-db-ja.com

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

chart.jsのAPI は、ロードされたデータセットのポイントを編集できるようにします。例:

.update( )

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

.addData( valuesArray, label )

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

.removeData( )

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

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

75
dthree

これには大きな問題がありました

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

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


これを行うための無数の方法があります。

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

破壊する必要があります:

myLineChart.destroy();

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

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

Chart.js V2.0では、次のことができます。

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

これは古いスレッドですが、現在のバージョン(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();
16
pavan kumar

これに対する私の解決策は非常に簡単です。 (バージョン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は、提示する必要があるデータセットを制御する関数です

11
Henrique C.

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

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

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

10
Felix Jassler

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

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

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

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

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

6
adi518

私は同じ問題に出くわしました。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();
4
Piper0804

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

var chart;

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

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

グラフ変数を関数スコープの外に移動すると、機能しました。

3
lony

古いデータを消去する必要があります。再初期化する必要はありません:

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

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

注:新しいデータをすべてデータセットオブジェクトに読み込んだら、chart.update()を呼び出してください。これが誰かを助けることを願っています

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

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

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

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

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
Matthew Herbst

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

これが私がやった方法です。

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

基本的に、作成時に読み込まれたデータを破棄し、データの追加メソッドで再構築します。これは、すべてのポイントにアクセスできることを意味します。私が作成したデータ構造にアクセスしようとしたときはいつでも:

Chart(ctx).Bar(dataNew);

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

0
Simon Unsworth

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

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

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

0
dthree

これにも多くの問題がありました。データとラベルを別々の配列に入れてから、チャートデータを再初期化します。 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
Paul

チャートJS 2.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();