如何从画布中清除图表,以便无法触发悬停事件?

问题描述 投票:87回答:15

我正在使用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();

但到目前为止,这些都没有奏效。关于如何阻止这种情况发生的任何想法?

javascript html5 charts chart.js
15个回答
119
投票

我有很大的问题

首先我尝试了.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');
  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);
};

1
投票

当您创建一个新的chart.js画布时,会生成一个隐藏的新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
投票

如果您在带有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>

0
投票

对我来说,这工作:

		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
投票

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
投票

这对我有用。在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
投票

由于破坏类型会破坏“一切”,当你真正想要的只是“重置数据”时,这是一种廉价而简单的解决方案。将数据集重置为空数组也可以完美地运行。因此,如果您有一个带标签的数据集,并且每侧都有一个轴:

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
投票

我们所做的是,在新图表初始化之前,删除/销毁预览图表实例,如果已存在,则创建一个新图表,例如

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

希望这可以帮助。


33
投票

几小时前我遇到了同样的问题。

“.clear()”方法实际上清除了画布,但(显然)它使对象保持活跃和反应。

仔细阅读the official documentation,在“高级用法”部分,我注意到了方法“.destroy()”,描述如下:

“使用它来销毁所创建的任何图表实例。这将清除Chart.js中存储到图表对象的任何引用,以及Chart.js附加的任何关联事件监听器。”

它实际上做了它声称的,它对我来说很好,我建议你尝试一下。


25
投票
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});
}

10
投票

这是唯一对我有用的东西:

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

5
投票

我在这里遇到了同样的问题...我尝试使用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
投票

这对我很有用

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

使用.destroy这可以销毁所创建的任何图表实例。这将清除Chart.js中存储到图表对象的任何引用,以及Chart.js附加的任何关联事件侦听器。必须在将画布重新用于新图表之前调用此方法。


3
投票

我们可以更新Chart.js V2.0中的图表数据,如下所示:

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

1
投票

使用CanvasJS,这适用于清除图表和其他所有内容,也适用于您,允许您在其他地方处理前完全设置画布/图表:

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

1
投票

我无法让.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>');
© www.soinside.com 2019 - 2024. All rights reserved.