web-dev-qa-db-ja.com

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

Chartjsを使用して折れ線グラフを表示していますが、これは正常に機能します。

// get line chart canvas
var targetCanvas = document.getElementById('chartCanvas').getContext('2d');

// draw line chart
var chart = new Chart(targetCanvas).Line(chartData);

しかし、チャートのデータを変更しようとすると問題が発生します。新しいデータポイントを使用してグラフの新しいインスタンスを作成し、キャンバスを再初期化して、グラフを更新します。

これは正常に機能します。ただし、新しいチャートにカーソルを合わせると、古いチャートに表示されているポイントに対応する特定の場所に移動すると、ホバー/ラベルが引き続きトリガーされ、突然古いチャートが表示されます。マウスがこの位置にある間は表示されたままで、その場所から離れると消えます。古いチャートを表示したくありません。完全に削除したいです。

新しいグラフを読み込む前に、キャンバスと既存のグラフの両方をクリアしようとしました。のような:

targetCanvas.clearRect(0,0, targetCanvas.canvas.width, targetCanvas.canvas.height);

そして

chart.clear();

しかし、これらのどれも今のところ機能していません。これを防ぐ方法についてのアイデアはありますか?

87
Adam Jones

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

最初に.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');
  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);
};
113
neaumusic

私は数時間前に同じ問題に直面しました。

".clear()"メソッドは実際にキャンバスをクリアしますが、(明らかに)オブジェクトをアクティブかつリアクティブのままにします。

注意深く読む 公式ドキュメント 、「高度な使用法」セクションで、次のように説明されているメソッド「.destroy()」に気付きました。

「これを使用して、作成されたチャートインスタンスを破棄します。これにより、Chart.jsによってアタッチされた関連イベントリスナーとともに、Chart.js内のチャートオブジェクトに格納された参照がクリーンアップされます。」

それは実際にそれが主張することを行い、それは私のためにうまくいったので、試してみることをお勧めします。

31
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});
}
24
xchiltonx

これは私のために働いた唯一のものです:

document.getElementById("chartContainer").innerHTML = '&nbsp;';
document.getElementById("chartContainer").innerHTML = '<canvas id="myCanvas"></canvas>';
var ctx = document.getElementById("myCanvas").getContext("2d");
9
Eric

ここでも同じ問題がありました... destroy()およびclear()メソッドを使用しようとしましたが、成功しませんでした。

次の方法で解決しました:

HTML:

<div id="pieChartContent">
    <canvas id="pieChart" width="300" height="300"></canvas>
</div>

Javascript:

var pieChartContent = document.getElementById('pieChartContent');
pieChartContent.innerHTML = '&nbsp;';
$('#pieChartContent').append('<canvas id="pieChart" width="300" height="300"><canvas>');

ctx = $("#pieChart").get(0).getContext("2d");        
var myPieChart = new Chart(ctx).Pie(data, options);

それは私にぴったりです...私はそれが役立つことを願っています。

5
Javier Muñoz

これは私にとって非常にうまくいった

    var ctx = $("#mycanvas");
     var LineGraph = new Chart(ctx, {
        type: 'line',
        data: chartdata});
        LineGraph.destroy();

。destroy thisを使用して、作成されたチャートインスタンスを破棄します。これにより、Chart.js内のチャートオブジェクトに保存されている参照と、Ch​​art.jsによってアタッチされた関連イベントリスナーがクリーンアップされます。これは、キャンバスを新しいチャートに再利用する前に呼び出す必要があります。

4

Chart.js V2.0のチャートデータは次のように更新できます。

var myChart = new Chart(ctx, data);
myChart.config.data = new_data;
myChart.update();
3
Sam G

TypeScriptを使用してAngularプロジェクトでchart.jsを使用している場合、以下を試すことができます。

Import the library:
    import { Chart } from 'chart.js';

In your Component Class declare the variable and define a method:

  chart: Chart;

  drawGraph(): void {
    if (this.chart) {
      this.chart.destroy();
    }

    this.chart = new Chart('myChart', {
       .........
    });
  }


In HTML Template:
<canvas id="myChart"></canvas>

.destroy()を動作させることもできなかったので、これが私がやっていることです。 chart_parent divは、キャンバスを表示する場所です。毎回キャンバスのサイズを変更する必要があるため、この答えは上記の拡張です。

HTML:

<div class="main_section" > <div id="chart_parent"></div> <div id="legend"></div> </div>

JQuery:

  $('#chart').remove(); // this is my <canvas> element
  $('#chart_parent').append('<label for = "chart">Total<br /><canvas class="chart" id="chart" width='+$('#chart_parent').width()+'><canvas></label>');
1
Chris

CanvasJSを使用すると、これはチャートやその他すべてをクリアするのに役立ちます。他の場所で処理する前にキャンバス/チャートを完全に設定することもできます。

var myDiv= document.getElementById("my_chart_container{0}";
myDiv.innerHTML = "";
1
aggaton

1つの新しいchart.jsキャンバスを作成すると、1つの新しいiframeが非表示になります。キャンバスと古いiframeを削除する必要があります。

$('#canvasChart').remove(); 
$('iframe.chartjs-hidden-iframe').remove(); 
$('#graph-container').append('<canvas id="canvasChart"><canvas>'); 
var ctx = document.getElementById("canvasChart"); 
var myChart = new Chart(ctx, { blablabla });

参照: https://github.com/zebus3d/javascript/blob/master/chartJS_filtering_with_checkboxs.html

1
zebus3d

Destroyの種類は「すべて」を破壊するため、本当に必要なのは「データをリセットする」ことだけで、安価でシンプルなソリューションです。データセットを空の配列にリセットすることも同様に完璧に機能します。そのため、ラベル付きのデータセットと両側に軸がある場合:

window.myLine2.data.labels = [];
window.myLine2.data.datasets[0].data = [];
window.myLine2.data.datasets[1].data = [];

この後、単に呼び出すことができます:

window.myLine2.data.labels.Push(x);
window.myLine2.data.datasets[0].data.Push(y);

または、2Dデータセットを使用しているかどうかに応じて:

window.myLine2.data.datasets[0].data.Push({ x: x, y: y});

チャート/データセット全体を完全に破壊し、すべてを再構築するよりもはるかに軽量になります。

0
T.S

私たちがやったことは、新しいチャートの初期化の前に、すでに存在する場合はプレビューチャートインスタンスを削除/破棄してから、たとえば新しいチャートを作成します

if(myGraf != undefined)
    myGraf.destroy();
    myGraf= new Chart(document.getElementById("CanvasID"),
    { 
      ...
    }

お役に立てれば。

0
Qammar Feroz

私にとってこれはうまくいきました:

                var in_canvas = document.getElementById('chart_holder');
        //remove canvas if present
                        while (in_canvas.hasChildNodes()) {
                                  in_canvas.removeChild(in_canvas.lastChild);
                                } 
        //insert canvas
                        var newDiv = document.createElement('canvas');
                        in_canvas.appendChild(newDiv);
                        newDiv.id = "myChart";
0
Scrapie

Chart.jsにはバグがあります。Chart.controller(instance)は、グローバルプロパティChart.instances[]に新しいチャートを登録し、.destroy()のこのプロパティから削除します。

ただし、チャートの作成時に、Chart.jsは._metaプロパティをデータセット変数に書き込みます。

var meta = dataset._meta[me.id];
if (!meta) {
   meta = dataset._meta[me.id] = {
       type: null,
       data: [],
       dataset: null,
       controller: null,
       hidden: null,     // See isDatasetVisible() comment
       xAxisID: null,
       yAxisID: null
   };

destroy()のこのプロパティは削除されません。

._meta propertyを削除せずに古いデータセットオブジェクトを使用すると、Chart.jsは以前のデータを削除せずに新しいデータセットを._metaに追加します。したがって、各チャートの再初期化で、データセットオブジェクトは以前のすべてのデータを蓄積します。

これを回避するには、Chart.destroy()を呼び出した後にデータセットオブジェクトを破棄します。

0
Andrew Hudik

これは私のために働いた。 updateChart()の上部にclearChartへの呼び出しを追加します

`function clearChart() {
    event.preventDefault();
    var parent = document.getElementById('parent-canvas');
    var child = document.getElementById('myChart');          
    parent.removeChild(child);            
    parent.innerHTML ='<canvas id="myChart" width="350" height="99" ></canvas>';             
    return;
}`
0
Jay