score:175
I had huge problems with this
First I tried .clear()
then I tried .destroy()
and I tried setting my chart reference to null
What finally fixed the issue for me: deleting the <canvas>
element and then reappending a new <canvas>
to the parent container
My specific code (obviously there's a million ways to do this):
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);
};
score:0
For me this worked:
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";
score:0
Chart.js has a bug:
Chart.controller(instance)
registers any new chart in a global property Chart.instances[]
and deletes it from this property on .destroy()
.
But at chart creation Chart.js also writes ._meta
property to dataset variable:
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
};
and it doesn't delete this property on destroy()
.
If you use your old dataset object without removing ._meta property
, Chart.js will add new dataset to ._meta
without deletion previous data. Thus, at each chart's re-initialization your dataset object accumulates all previous data.
In order to avoid this, destroy dataset object after calling Chart.destroy()
.
score:0
for those who like me use a function to create several graphics and want to update them a block too, only the function .destroy() worked for me, I would have liked to make an .update(), which seems cleaner but ... here is a code snippet that may help.
var SNS_Chart = {};
// IF LABELS IS EMPTY (after update my datas)
if( labels.length != 0 ){
if( Object.entries(SNS_Chart).length != 0 ){
array_items_datas.forEach(function(for_item, k_arr){
SNS_Chart[''+for_item+''].destroy();
});
}
// LOOP OVER ARRAY_ITEMS
array_items_datas.forEach(function(for_item, k_arr){
// chart
OPTIONS.title.text = array_str[k_arr];
var elem = document.getElementById(for_item);
SNS_Chart[''+for_item+''] = new Chart(elem, {
type: 'doughnut',
data: {
labels: labels[''+for_item+''],
datasets: [{
// label: '',
backgroundColor: [
'#5b9aa0',
'#c6bcb6',
'#eeac99',
'#a79e84',
'#dbceb0',
'#8ca3a3',
'#82b74b',
'#454140',
'#c1502e',
'#bd5734'
],
borderColor: '#757575',
borderWidth : 2,
// hoverBackgroundColor : '#616161',
data: datas[''+for_item+''],
}]
},
options: OPTIONS
});
// chart
});
// END LOOP ARRAY_ITEMS
}
// END IF LABELS IS EMPTY ...
score:0
just declare let doughnut = null
before creating your chart
const doughnutDriverStatsChartCanvas = $('#dougnautChartDriverStats').get(0).getContext('2d')
const doughnutOptionsDriverStats = {
maintainAspectRatio: false,
responsive: true,
}
let doughnut = null
doughnut = new Chart(doughnutDriverStatsChartCanvas, {
type: 'doughnut',
data: doughnutChartDriverStats,
options: doughnutOptionsDriverStats
})
score:1
Using CanvasJS, this works for me clearing chart and everything else, might work for you as well, granting you set your canvas/chart up fully before each processing elsewhere:
var myDiv= document.getElementById("my_chart_container{0}";
myDiv.innerHTML = "";
score:1
I couldn't get .destroy() to work either so this is what I'm doing. The chart_parent div is where I want the canvas to show up. I need the canvas to resize each time, so this answer is an extension of the above one.
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>');
score:1
When you create one new chart.js canvas, this generate one new iframe hidden, you need delete the canvas and the olds iframes.
$('#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 });
reference: https://github.com/zebus3d/javascript/blob/master/chartJS_filtering_with_checkboxs.html
score:1
This worked for me. Add a call to clearChart, at the top oF your updateChart()
`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;
}`
score:1
Since destroy kind of destroys "everything", a cheap and simple solution when all you really want is to just "reset the data". Resetting your datasets to an empty array will work perfectly fine as well. So, if you have a dataset with labels, and an axis on each side:
window.myLine2.data.labels = [];
window.myLine2.data.datasets[0].data = [];
window.myLine2.data.datasets[1].data = [];
After this, you can simply call:
window.myLine2.data.labels.push(x);
window.myLine2.data.datasets[0].data.push(y);
or, depending whether you're using a 2d dataset:
window.myLine2.data.datasets[0].data.push({ x: x, y: y});
It'll be a lot more lightweight than completely destroying your whole chart/dataset, and rebuilding everything.
score:1
If you are using chart.js in an Angular project with Typescript, the you can try the following;
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>
score:1
What we did is, before initialization of new chart, remove/destroy the previews Chart instance, if exist already, then create a new chart, for example
if(myGraf != undefined)
myGraf.destroy();
myGraf= new Chart(document.getElementById("CanvasID"),
{
...
}
Hope this helps.
score:1
First put chart in some variable then history it next time before init
#Check if myChart object exist then distort it
if($scope.myChart) {
$scope.myChart.destroy();
}
$scope.myChart = new Chart(targetCanvas
score:1
You should save the chart as a variable. On global scope, if its pure javascript, or as a class property, if its Angular.
Then you'll be able to use this reference to call destroy().
Pure Javascript:
var chart;
function startChart() {
// Code for chart initialization
chart = new Chart(...); // Replace ... with your chart parameters
}
function destroyChart() {
chart.destroy();
}
Angular:
export class MyComponent {
chart;
constructor() {
// Your constructor code goes here
}
ngOnInit() {
// Probably you'll start your chart here
// Code for chart initialization
this.chart = new Chart(...); // Replace ... with your chart parameters
}
destroyChart() {
this.chart.destroy();
}
}
score:2
Complementing Adam's Answer
With Vanilla JS:
document.getElementById("results-graph").remove(); //canvas
div = document.querySelector("#graph-container"); //canvas parent element
div.insertAdjacentHTML("afterbegin", "<canvas id='results-graph'></canvas>"); //adding the canvas again
score:3
It's best to use Chart.js specific functionalities to initially check for the existing chart instance and then perform destroy or clear in order to reuse the same canvas element for rendering another chart, instead of handlding HTML elements from within JS.
ChartJs's getChart(key) - finds the chart instance from the given key.
- If the key is a string, it is interpreted as the ID of the Canvas element for the Chart.
- The key can also be a CanvasRenderingContext2D or an HTMLDOMElement.
Note: This will return undefined if no Chart is found. If the instance of the chart is found, it signifies that the chart must have previously been created.
// JS - Destroy exiting Chart Instance to reuse <canvas> element
let chartStatus = Chart.getChart("myChart"); // <canvas> id
if (chartStatus != undefined) {
chartStatus.destroy();
//(or)
// chartStatus.clear();
}
//-- End of chart destroy
var chartCanvas = $('#myChart'); //<canvas> id
chartInstance = new Chart(chartCanvas, {
type: 'line',
data: data
});
<!-- HTML -Line Graph - Chart.js -->
<div class="container-fluid" id="chartContainer">
<canvas id="myChart" width="400" height="150"> </canvas>
</div>
This approach would save you from remove - create - append a Canvas element into DIV from inside JS.
score:4
Simple edit for 2020:
This worked for me. Change the chart to global by making it window owned (Change the declaration from var myChart
to window myChart
)
Check whether the chart variable is already initialized as Chart, if so, destroy it and create a new one, even you can create another one on the same name. Below is the code:
if(window.myChart instanceof Chart)
{
window.myChart.destroy();
}
var ctx = document.getElementById('myChart').getContext("2d");
Hope it works!
score:5
This worked very well for me
var ctx = $("#mycanvas");
var LineGraph = new Chart(ctx, {
type: 'line',
data: chartdata});
LineGraph.destroy();
Use .destroy this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js. This must be called before the canvas is reused for a new chart.
score:9
I had the same problem here... I tried to use destroy() and clear() method, but without success.
I resolved it the next way:
HTML:
<div id="pieChartContent">
<canvas id="pieChart" width="300" height="300"></canvas>
</div>
Javascript:
var pieChartContent = document.getElementById('pieChartContent');
pieChartContent.innerHTML = ' ';
$('#pieChartContent').append('<canvas id="pieChart" width="300" height="300"><canvas>');
ctx = $("#pieChart").get(0).getContext("2d");
var myPieChart = new Chart(ctx).Pie(data, options);
It works perfect to me... I hope that It helps.
score:9
We can update the chart data in Chart.js V2.0 as follows:
var myChart = new Chart(ctx, data);
myChart.config.data = new_data;
myChart.update();
score:15
This is the only thing that worked for me:
document.getElementById("chartContainer").innerHTML = ' ';
document.getElementById("chartContainer").innerHTML = '<canvas id="myCanvas"></canvas>';
var ctx = document.getElementById("myCanvas").getContext("2d");
score:36
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});
}
score:42
I have faced the same problem few hours ago.
The ".clear()" method actually clears the canvas, but (evidently) it leaves the object alive and reactive.
Reading carefully the official documentation, in the "Advanced usage" section, I have noticed the method ".destroy()", described as follows:
"Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js."
It actually does what it claims and it has worked fine for me, I suggest you to give it a try.
Source: stackoverflow.com
Related Query
- How to clear a chart from a canvas so that hover events cannot be triggered?
- How can I trigger the hover mode from outside the chart with charts.js 2?
- How to create Bar chart that gets updated from new ajax requests with ChartJS?
- How can I build a double doughnut chart that spins when triggered
- How to limit chart JS hover to take only one value from each line chart when zoomed out?
- How to set the data of chart in angular which is taken from the backend nodejs api that is store in mongodb and showing on the html page
- How to take data from an API and create a chart on that using Chart.js and Angular 8?
- how to remove old data from Chart js on mouse hover using mvc c#?
- How to prevent first/last bars from being cut off in a chart with time scale
- Chart.js Bar Chart - how to chart bars from 0
- Detecting hover events over parts of a chart using Chart.js
- chart js tooltip how to control the data that show
- How to add datas to chart js from javascript array itself?
- How can I remove extra whitespace from the bottom of a line chart in chart.js?
- How to use 'time' (data from database, data type: timestamp ) for plotting graph in Chart JS
- (Vue, ChartJS) Create gradient background for chart from child component canvas context
- How to start the line graph from the left Y axis in a line/bar mixed chart (Chart.js)?
- How to disable canvas elements from hijacking mouse wheel when scrolling through a page?
- ChartJs - Pie Chart - how to remove labels that are on the pie chart
- ChartJS (React) Line Chart - How to show single tooltip with data and labels from 3 (multiple) dataset?
- How to make inner paddings from canvas in chart.js?
- How to remove border from stacked column chart in Chartkick - Chart.js
- How to create chartjs chart with data from database C#
- How to create a chart that uses strings for both the X and Y axes?
- chart.js add second line in a Line chart that starts from end of first line
- How do I add time sourced from an external source as an X axis to a ChartJS graph?
- How to get chart from data points (arrays) with inconsistent time intervals and chart.js?
- How to make aspecific API call from within a Line Chart class in ReactJS using react-chartjs-2?
- How to Remove axis Lines from chart in chart js
- How do I remove cartesian axes from chart js?
More Query from same tag
- ChartJS - Issues with positioning and viewing various components of horizontal bar
- Chartjs tooltip location when enlarged
- Unable to separate elements of JSON
- Is there a way to filter data in Chart.js?
- (Lifecycle problem?) React Chart js-2 not updating data from componentDidMount
- Chart js loading screen
- How to change the Y-Axis to show $ in graph
- Implementing range slider in Chart.js
- How to display label on side of doughnut in chart js
- Chart.js hidden property
- Horizontal scroll in vue-chartjs
- Vue and Chartjs - Running a simple example of vue-chartjs
- Chart.js: Combined Line and Bar Data
- How to set a full length background color for each bar in chartjs bar
- In Chart.js multibar graph, is there a way to highlight a single category?
- Chart.js - cannot fetch result from MySQL via PHP
- Ember.Computed is not a function
- Angular 9 chartJs is not updating view after data update
- How to get click event in Chart.js
- Regarding stacked chart in chart.js
- How to put back the data with a switch?
- How to specify hover color angular-chart.js
- Chartjs custom dynamic legend overflowing
- How to make rectangle in chart.js
- How to realtime plotting firebase data to ChartJS
- Vertical lines for custom events and notes
- How to align Chart JS "legend" on right-center
- How to combine lines with different starting points in chartjs
- dynamically update Chart.js draw line chart dataset data
- chart resizing in ng2-google-charts