Javascript 销毁chart.js条形图以重新绘制同一图形<;帆布>;
我正在使用Chart.js库绘制一个条形图,它工作正常,但现在我想销毁条形图,并在同一个画布中制作一个线形图。我尝试了以下两种方法来清除画布:Javascript 销毁chart.js条形图以重新绘制同一图形<;帆布>;,javascript,canvas,graph,chart.js,Javascript,Canvas,Graph,Chart.js,我正在使用Chart.js库绘制一个条形图,它工作正常,但现在我想销毁条形图,并在同一个画布中制作一个线形图。我尝试了以下两种方法来清除画布: var grapharea = document.getElementById("barChart").getContext("2d"); grapharea.destroy(); var myNewChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOpt
var grapharea = document.getElementById("barChart").getContext("2d");
grapharea.destroy();
var myNewChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });
第二种方式:
var grapharea = document.getElementById("barChart").getContext("2d");
grapharea.clear();
var myNewChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });
我说得对吗?OnButton单击我调用这个使用相同画布的函数。为了能够在同一画布上绘制另一个图表,正确的方法是
.destroy()
。必须在先前创建的图表对象上调用它。您也可以对两个图表使用相同的变量
var grapharea = document.getElementById("barChart").getContext("2d");
var myChart = new Chart(grapharea, { type: 'bar', data: barData, options: barOptions });
myChart.destroy();
myChart = new Chart(grapharea, { type: 'radar', data: barData, options: barOptions });
直截了当地说:
.销毁
使用此选项可以销毁创建的任何图表实例。这将清除存储在chart.js中的对chart对象的任何引用,以及chart.js附加的任何关联事件侦听器。必须在画布重新用于新图表之前调用此函数
它明确指出,必须先调用此方法,才能将画布重新用于新图表
.clear()
在后面的同一节中还提到了函数“将清除图表画布。在动画帧之间广泛使用,但您可能会发现它很有用。”调用此方法后,图表将处于活动状态,因此这不是要调用的方法,如果您想为一个全新的图表重复使用画布
不过,老实说,在像您这样的情况下,我经常使用容器
div
来包装我的canvas
,每当我需要创建新图表时,我都会在div
中放置一个新的canvas
元素。然后,我将这个新创建的画布
用于新图表。如果您遇到奇怪的行为,可能与当前图表之前占据画布的图表有关,也要记住这种方法。每次调用图表后都要移除画布,这对我来说很有效
$("canvas#chartreport").remove();
$("div.chartreport").append('<canvas id="chartreport" class="animated fadeIn" height="150"></canvas>');
var ctx = document.getElementById("chartreport").getContext("2d");
chartreport= new Chart(ctx, { .... });
$(“画布#图表报告”).remove();
$(“div.chartreport”)。附加(“”);
var ctx=document.getElementById(“chartreport”).getContext(“2d”);
chartreport=新图表(ctx,{…});
对于ChartJS v2.x您可以使用更新图表数据,而无需显式销毁和创建画布
var chart_ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(chart_ctx, {
type: "pie",
data: {},
options: {}
});
$.ajax({
...
}).done(function (response) {
chart.data = response;
chart.update();
});
我现在正在使用Chart.js 2.7.2。在我的应用程序中,我正在创建多个图表,需要一种方法来访问它们,以便正确地“替换”它们的数据,并修复悬停时显示的“旧图表”。我试过的答案都不正确 以下是一种使用一个或多个图表进行管理的方法: 在全球范围内存储图表
var charts=[]; // global
函数创建图表
function createChart(id, type, labels, data)
{
// for multiple datasets
var datasets=[];
data.forEach(function(set) {
datasets.push({
label: set.label,
data: set.data
});
});
var config = {
type: type,
data: {
labels: labels,
datasets: datasets
}
};
if(typeof charts[id] == "undefined") // see if passed id exists
{
// doesn't, so create it
charts[id]= new (function(){
this.ctx=$(id); // canvas el
this.chart=new Chart(this.ctx, config);
})();
console.log('created chart '+charts[id].chart.canvas.id);
}
else
{
charts[id].chart.destroy(); // "destroy" the "old chart"
charts[id].chart=new Chart(charts[id].ctx, config); // create the chart with same id and el
console.log('replaced chart '+charts[id].chart.canvas.id);
}
// just to see all instances
Chart.helpers.each(Chart.instances, function(instance){
console.log('found instance '+instance.chart.canvas.id)
})
}
对于每个画布元素,如:
<canvas id="thiscanvasid"></canvas>
为了解决这个问题,我使用了jQuery的
add()
和remove()
方法来清除画布。我正在移除组件,在再次绘制之前,我将使用jQuery的append()
方法以相同的id再次添加画布
redraw(){
$("#myChart").remove();// removing previous canvas element
//change the data values or add new values for new graph
$("#chart_box").after("<canvas id='myChart'></canvas>");
// again adding a new canvas element with same id
generateGraph();// calling the main graph generating function
}
redraw(){
$(“#myChart”).remove();//删除上一个画布元素
//更改数据值或为新图形添加新值
$(“#图表框”)。在(“)之后;
//再次添加具有相同id的新画布元素
generateGraph();//调用主图形生成函数
}
也许有更好的方法,但没有适合我的答案
document.querySelector("#chartReport").innerHTML = '<canvas id="myChart"></canvas>';
document.querySelector(“#chartReport”).innerHTML=”;
我的HTML部分是
<div class="col-md-6 col-md-offset-3">
<div id="chartReport">
<canvas id="myChart"></canvas>
</div>
</div>
您可以对此进行测试
$('#canvas').replaceWith($('<canvas id="canvas" height="320px"></canvas>'));
$('#canvas')。替换为($('');
)() 我总是只使用一张图表/页。他解决了这些问题
if (
window.myLine !== undefined
&&
window.myLine !== null
) {
window.myLine.destroy();
}
window.myLine = new Chart(graphCanvasCtx, config);
2020年的简单编辑:
这对我有用。通过将图表设置为窗口所有,将其更改为全局(将声明从var myChart
更改为window myChart
)
检查图表变量是否已初始化为图表,如果已初始化,请销毁它并创建一个新的,即使您可以使用相同的名称创建另一个。代码如下:
if(window.myChart instanceof Chart)
{
window.myChart.destroy();
}
var ctx = document.getElementById('myChart').getContext("2d");
希望它能起作用 创建全局对象:
window['chart-' + chartId] = new Chart(...);
通过重新绘制访问和销毁过程:
if ( window['chart-' + chartId] != undefined ) {
window['chart-' + chartId].destroy();
}
这将解决在多个ajax调用中多次更新图表时图表速度变慢的问题: 只需在启动图表之前添加以下代码:
$('.chartjs-size-monitor').each(function(){
$(this).remove();
})
var grapharea = document.getElementById("barChart").getContext("2d");
我遇到了同样的问题,我删除了canvas元素并重新创建了canvas元素,然后再次延迟渲染
var element = document.getElementById("canvasId");
element.parentNode.removeChild(element);
var canv = document.createElement("canvas");
canv.setAttribute("id","canvasId");
canv.style.height = "20vw"; // give height and width as per the requirement
canv.style.width = "20vw";
setTimeout(()=>{
var grapharea = document.getElementById("canvasId").getContext("2d");
},500)
我设法找到了一个解决方案,它与destroy方法一起工作,并允许在不删除和重新创建画布的情况下重用画布,同时它也是资源消耗较少的用户 首先,将var-chart声明为全局,并创建一个布尔值来检查js是否已加载
var chart;
var graphScriptLoaded = false;
下一部分很好,因为它在需要图形时加载js,节省了加载页面的时间,同时它允许您了解它是否是第一次执行
//load graph just when needed and destry existing istances
if (!Boolean(graphScriptLoaded)) {
loadScript('https://cdn.jsdelivr.net/npm/chart.js@2.8.0', function(){
graphScriptLoaded = true;
chart=graphs_init(i_arr, spent_arr);
});
} else {
chart.destroy();
chart=graphs_init(i_arr, spent_arr);
}
然后,在创建图形的函数中,只需返回chart var
var chart = new Chart(ctx, {
[.....]
});
return chart;
函数“loadscript”是根据以下答案定制的:
这是:
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
它的工作方式很有魅力。对于我来说,它在核心javascript中的工作方式如下(假设chart min js已经加载):
这对我来说很有用
removeHTML() {
let chart = <HTMLCanvasElement>document.getElementById("myChart");
let chart2 = <HTMLCanvasElement>document.getElementById("myChart2");
if(chart){
chart.remove()
}
if(chart2){
chart2.remove()
}
}
ngOnDestroy(): void {
this.removeHTML();
}
removeHTML(){
让chart=document.getElementById(“myChart”);
让chart2=document.getElementById(“myChart2”);
如果(图表){
图表。删除()
}
如果(图2){
图2.删除()
}
}
ngOnDestroy():void{
this.removeHTML();
}
以下是我的策略,在创建一个新图表之前,针对给定的画布ID销毁一个ChartJS图表。这有点暴力,但可以完成任务
我创建了一个对象,该对象跟踪从画布id到关联的ChartJS对象的映射,在创建新对象之前,我将检查该对象是否有任何现有的ChartJS对象要销毁
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
const data = {
labels : graphDataLabels,
datasets: [{
label: 'Sentiment Intensity Distribution',
data: dataValues, //[300, 50, 100],
backgroundColor: [
"#0D5265",
"#32DAC8",
"#FF8300"
],
hoverOffset: 4
}]
};
const config = {
type: 'pie',
data: data
};
var ctx = document.getElementById('pieChart').getContext('2d');
if(ctx.pieChart){
pieChart = null;
}else{
pieChart = new Chart(ctx, config);
}
removeHTML() {
let chart = <HTMLCanvasElement>document.getElementById("myChart");
let chart2 = <HTMLCanvasElement>document.getElementById("myChart2");
if(chart){
chart.remove()
}
if(chart2){
chart2.remove()
}
}
ngOnDestroy(): void {
this.removeHTML();
}
// Helper object and functions
const chartsByCanvasId = {};
const destroyChartIfNecessary = (canvasId) => {
if (chartsByCanvasId[canvasId]) {
chartsByCanvasId[canvasId].destroy();
}
}
const registerNewChart = (canvasId, chart) => {
chartsByCanvasId[canvasId] = chart;
}
destroyChartIfNecessary(canvasId);
const myChart = new Chart(ctx, config);
registerNewChart(canvasId, myChart);