73👍
With the approach you are taking (e.g. creating a new Chart object each time the date range changes), then you must first destroy the previous chart and then create the new one.
You can use the .destroy()
prototype method to do this. Here is exactly what the API states.
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. This
must be called before the canvas is reused for a new chart.
Therefore, your code would look something like this (notice that we destroy and re-create).
// define a variable to store the chart instance (this must be outside of your function)
var myChart;
function loadFTPRChart(startdate, enddate) {
var BCData = {
labels: [],
datasets: [{
label: "Pass %",
backgroundColor: "#536A7F",
data: [],
stack: 1
}, {
label: "Fail %",
backgroundColor: "#e6e6e6",
data: [],
stack: 1
}, {
label: "Auto %",
backgroundColor: "#286090",
data: [],
stack: 2
}, {
label: "Manual %",
backgroundColor: "#f0f0f0",
data: [],
stack: 2
}]
};
$.getJSON("content/FTPR_AM_Graph_ajax.php", {
startdate: startdate,
enddate: enddate,
location: "M"
})
.done(function(data) {
console.log("data", data);
$.each(data.aaData, function(key, val) {
if (val == "") {
return true
}
BCData.labels.push("Coater " + val[0]);
BCData.datasets[0].data.push(parseFloat(val[2]));
BCData.datasets[1].data.push(parseFloat(100 - val[2]));
BCData.datasets[2].data.push(parseFloat(val[1]));
BCData.datasets[3].data.push(parseFloat(100 - val[1]));
});
var option = {
responsive: true,
};
console.log("BCData", BCData);
// if the chart is not undefined (e.g. it has been created)
// then destory the old one so we can create a new one later
if (myChart) {
myChart.destroy();
}
var ctx = document.getElementById("mybarChart2").getContext("2d");
myChart = new Chart(ctx, {
type: 'groupableBar',
data: BCData,
options: {
scales: {
yAxes: [{
ticks: {
max: 100,
},
stacked: true,
}]
}
}
});
});
}
With that said, it’s expensive the destroy/create over and over and actually it isn’t even necessary. There is another prototype method called .update()
that you can use to just re-render the chart if you have changed it’s underlying data or label objects.
Here is a jsfiddle showing an example of changing the underlying data and labels and then re-rendering the chart. I would highly recommend you take this approach instead.
Here is how your code would look taking this better approach.
// define a variable to store the chart instance (this must be outside of your function)
var myChart;
function loadFTPRChart(startdate, enddate) {
var BCData = {
labels: [],
datasets: [{
label: "Pass %",
backgroundColor: "#536A7F",
data: [],
stack: 1
}, {
label: "Fail %",
backgroundColor: "#e6e6e6",
data: [],
stack: 1
}, {
label: "Auto %",
backgroundColor: "#286090",
data: [],
stack: 2
}, {
label: "Manual %",
backgroundColor: "#f0f0f0",
data: [],
stack: 2
}]
};
$.getJSON("content/FTPR_AM_Graph_ajax.php", {
startdate: startdate,
enddate: enddate,
location: "M"
})
.done(function(data) {
console.log("data", data);
$.each(data.aaData, function(key, val) {
if (val == "") {
return true
}
BCData.labels.push("Coater " + val[0]);
BCData.datasets[0].data.push(parseFloat(val[2]));
BCData.datasets[1].data.push(parseFloat(100 - val[2]));
BCData.datasets[2].data.push(parseFloat(val[1]));
BCData.datasets[3].data.push(parseFloat(100 - val[1]));
});
var option = {
responsive: true,
};
console.log("BCData", BCData);
// if the chart is not undefined (e.g. it has been created)
// then just update the underlying labels and data for each
// dataset and re-render the chart
if (myChart) {
myChart.data.labels = BCData.labels;
myChart.data.datasets[0].data = BCData.datasets[0].data;
myChart.data.datasets[1].data = BCData.datasets[1].data;
myChart.data.datasets[2].data = BCData.datasets[2].data;
myChart.data.datasets[3].data = BCData.datasets[3].data;
myChart.update();
} else {
// otherwise, this is the first time we are loading so create the chart
var ctx = document.getElementById("mybarChart2").getContext("2d");
myChart = new Chart(ctx, {
type: 'groupableBar',
data: BCData,
options: {
scales: {
yAxes: [{
ticks: {
max: 100,
},
stacked: true,
}]
}
}
});
}
});
}
15👍
This is chartjs trick i found
var ctxLine = document.getElementById("line-chart").getContext("2d");
if(window.bar != undefined)
window.bar.destroy();
window.bar = new Chart(ctxLine, {});
https://therichpost.com/solved-hovering-chartjs-bar-chart-showing-old-data
15👍
It will help you…
Check whether MyChart have already configurations or not, If it exist clear it with destroy(); method, And bind new configuration to canvas.
Sample Code..
if (window.MyChart != undefined)
{
window.MyChart.destroy();
}
window.MyChart = new Chart(ctx, MyChartconfig);
10👍
There is a simple solution for this, which can be done in JS itself.
let’s say your html has something like below
<div id="chartContainer">
<canvas id="mybarChart2"></canvas>
</div>
Then in your script, you can add below lines of code before updating the data.
document.getElementById("chartContainer").innerHTML = ' ';
document.getElementById("chartContainer").innerHTML = '<canvas id="mybarChart2"></canvas>';
var ctx = document.getElementById("mybarChart2").getContext("2d");
This solved my issue.
2👍
after stackoverflowing for so many hours i found and easy solution to it no need to do so many changes …
just add this line in options section
events:[]
in the options section it is an quick solution to get rid from Chartjs Bar Chart showing old data when hovering
if You need Hovering event also then try to reinitialise or re-render the canvas adding if conditions this will fix for sure
2👍
Declare myChart as a global variable
let mychart;
Before graph creation just write
function pieChart(pdata) {
// destroy previous created graph
if (myChart) {
myChart.destroy()
}
let ctx = document.getElementById("pie-chart").getContext('2d');
myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Count'],
datasets: [{
backgroundColor: [
"#2ecc71",
],
data: [pdata],
}]
},
});
}
why we adding this? Because, if we create any graph at first time the mychart create a object, in that case when we rander it, it won’t be change. that’s why we need to destroy previous object and create new object for newer visualization.
1👍
I was found the problem and my solution is remove them from html first and before load new chart then append canvas.
Html
$('#chart').empty();
$('#chart').html('<canvas id="survey_result" width="400" height="200"></canvas>'); // then load chart.
var ctx = document.getElementById("survey_result");
<div id="chart" class="display>
</div>
0👍
The code of the provided samples by chartjs.org have shown that they don’t destroy() the chart and create a new one. Instead, they pop() the existing data from the chart and push() the new dataset to the graph and then update() the chart.
This code is from the chartjs.org website which removes the dataset from the chart by POP().
document.getElementById('removeDataset').addEventListener('click', function() {
horizontalBarChartData.datasets.pop();
window.myHorizontalBar.update();
});
And this code is for adding the dataset to the chart by PUSH():
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[horizontalBarChartData.datasets.length % colorNames.length];
var dsColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + (horizontalBarChartData.datasets.length + 1),
backgroundColor: color(dsColor).alpha(0.5).rgbString(),
borderColor: dsColor,
data: []
};
for (var index = 0; index < horizontalBarChartData.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
horizontalBarChartData.datasets.push(newDataset);
window.myHorizontalBar.update();
});
The last step of these two code blocks is to update the chart.
Generally speaking, it is necessary to pop the data that you want to remove from the chart and then push the new data and finally update the chart. Therefore, the pervious data is not going to be shown when hovering.
0👍
I know this is old, but most of these didn’t work in my situation, so I’m posting what worked for me.
I had two charts exhibiting this behavior, a z-stacked bar chart and a pie chart. I tried these to no avail:
myChart.destroy()
: This would work to change the values, but for some reason also affected the size and display values for my chartsoptions: { events: [] }
: As said in that post, this removes all tooltips on hover, which I still wantedinnerHTML
: I don’t know if this is a newer feature of chartjs, but none of my charts ever had an innerHTML attribute apart from""
myChart.datasets.pop()
: This one is the spirit behind my solution, but in most cases I had more than one dataset, so I just removed them all:
if (myChart !== undefined) {
while (myChart.data.datasets.length > 0) {
myChart.data.datasets.pop();
}
}
I was also previously creating var myChart
with the function I was using to create the chart and organize the data. After moving that variable declaration outside the function and implementing the above within the function, they work like a charm!
0👍
What worked for me (maybe it’s ineffective but this isn’t a bit issue to me as it would only be done a few times per visit) – destroying and recreating the whole canvas object (using JQuery).
$("#canvasID").remove();
$("<canvas>").attr({
id: "canvasID"
}).appendTo("#canvasParent");
0👍
I could not get the "destroy()" to work at all. I struggled. I ended up removing the element altogether, then recreating on each update of data.
if(document.getElementById(chartID)) {
document.getElementById(chartID).remove();
}
var canvasParent;
// I had 2 charts, so a ternary to select the right element
chartID == 'fleet-fuel-chartComp1' ? canvasParent = document.getElementById('canvas-node1') : canvasParent = document.getElementById('canvas-node2');
var canvas = document.createElement('canvas');
canvas.id = chartID;
canvasParent.appendChild(canvas);
var ffc = document.getElementById(chartID);
0👍
Why this Problem Happened
This problem occurs, when we change the graph data by ajax. it will append the data in the graph. when we hover on that previous point it highligts the previous graph.
Soluctions: It will work 100%.
$('#chart').html('');
$('#chart').html('<canvas id="Chartcanvas" style="height: 350px;"></canvas>');
0👍
I tried all the suggestions above and they did not work, it turned out my function:
function initChart(data, label) {
if(!data){
data = sanitizeData({!! json_encode($subsequentSickdays) !!});
label = "Employees with X amount of sickdays";
}
$('#chartjs-custom').html('');
$('#chartjs-custom').html('<canvas id="chart-absence" class="js-chart"></canvas>');
return $.HSCore.components.HSChartJS.init($('#chart-absence'), {
"type": "pie",
"data": setChartData(data, label),
"options": options()
});
}
was being initialised twice on page load. One when i defined var chart = initChart()
and when i initialised it with initChart()
. After i removed initChart()
it worked. Don’t know why this would matter but hey, it works, hope this helps someone.
0👍
This is really a life saver.
I set chart to undefined.
let chart = undefined;
Then did this:
function drawChart(arr) {
if (chart != undefined) chart.destroy();
chart = new Chart(ctx, {
...
})
You guys solved it – man, this was kicking my butt ! I couldn’t understand it and felt like a complete idiot. The project was to display a default graph, then change the values in the graph. The original artifact of the original graph kept getting displayed. I couldn’t believe it and was ready to give up.
Thanks,
DB