hi all
here is my app : http://codepen.io/spyshow/pen/WGZRvv?editors=0010
it's an weather app ... when i press the F/C button it will redraw another chart with new dataset over the old one . but if you hover the mouse over the point of the old chart the old chart will come forward .
how can i delete the old chart and redraw the new one after that?
thanks
@spyshow call destroy on the old chart before creating a new one
i've tried but it hide the hole chart and give me an error in the console
Uncaught TypeError: Cannot read property 'currentStyle' of null
I have got a similar problem.
I draw a chart, then using a datepicker button, I select a different time range to update the chart.
I call destroy() first, but in some cases I get the following error:
Chart.js:5756 Uncaught TypeError: Cannot read property 'querySelector' of null
This happens at line 5756 which I copy here (the line starting with var hiddenIframe), because that is undefined.
helpers.removeResizeListener = function(node) {
var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
// Remove the resize detect iframe
if (hiddenIframe) {
hiddenIframe.parentNode.removeChild(hiddenIframe);
}
Any ideas how to solve that?
Thanks.
@micheledallatorre which version are you using?
@etimberg last one, i.e. v. 2.2.2
@etimberg I can look at this since I'm cleaning stuff around the canvas and iframe?
@simonbrunel go for it
@micheledallatorre @spyshow I can't reproduce it, can you post a fiddle that shows these errors?
you can see my app on codepen : http://codepen.io/spyshow/pen/WGZRvv?editors=0010
Your example works fine, no "Uncaught TypeError". However, since the config and chart type never changes, I don't think that destroying and recreating the chart every time is the best approach. Instead, the chart should be created at the beginning, then in loadWeather, the data should be updated.
@simonbrunel it took me a while to create a test case, and it was very useful to better understand where the problem could be.
Here you can find the fiddle: https://jsfiddle.net/mdt86/2vf30fer/9/
As far as I understood, calling destroy() multiple times, even on the same chart, does not cause errors.
Hovewer, in the test case linked above, the error seems to be caused when entering the second time in the each() loop (line 108), but don't understand why...
To support this, see also https://jsfiddle.net/mdt86/2vf30fer/10/ where I edited line 57:
<!-- <canvas id="chart2canvas"></canvas> -->
so that the $('canvas').parent().each loop (line 108) is called once. In this case, no error is thrown.
Any help is greatly appreciated! :)
UPDATE: to test the fiddle above, click on the REDRAW CHART button.
@micheledallatorre you create myBarChart (line 87) always with chart1canvas, then you loop on all canvases, destroy 2 times myBarChart and remove canvases. The second time, canvs chart1canvas is not anymore accessible. Your second fiddle works because then there is only one canvas to iterate on.
Actually as soon as I remove a canvas, I add it again via append() (line 123)... so why do you think canvas chart1canvasis not anymore accessible?
Thanks a lot.
Btw this is clearly my bug, nothing related to ChartJS.
Your code basically do:
chart1canvas);chart1canvas)chart1canvas) _<- myChart.canvas == null_chart1canvas) _<- myChart.canvas still null_chart2canvas)chart2canvas)chart2canvas)chart1canvas);Note that you never create a chart for the second canvas (chart2canvas). Anyway, you should never call destroy twice on the same chart and I would recommend the same method as I suggested above: create your charts only one time, then call update() after updating the data.
@simonbrunel thanks a lot for your detailed answer. I still don't understand why append(chart1canvas) results in myChart.canvas being null though...
Anyway, I totally agree on your point: better to use update()method.
Thanks a lot.
myChart.canvas points to the DOM element, not the id. When calling append("HTML"), a new DOM element is created, different from the previous one, which has been destroyed by the remove() call.
Cheers! :+1:
@simonbrunel so how could you point to the newly created DOM element, if possible?
You can't really replace the chart canvas because it requires some initialization done at the chart construction time but also because you should not use the chart object after calling destroy(). So if you still want to use that approach, you need to create a new chart each time you re-create the canvas:
charts[childCanvasId].destroy();
$('#' + childCanvasId).remove();
$(this).append('<canvas id="' + childCanvasId + '"></canvas>');
charts[childCanvasId] = new Chart($("#" + childCanvasId), config);
But again, if your chart type doesn't change, update() is the best approach :)
Thanks man! :+1:
Closing as resolved
This is how I fixed the issue with the flickering
function fixFlicker(docid, tname) {
var eDoc = document.getElementById(docid);
var cNode = eDoc.getElementsByTagName(tname);
//Copy All the Tag Name
var arr = [];
for (var i = 0; i < cNode.length; i++) {
arr.push(cNode[i].id);
} //End for loop
//Delete the Container Elements
eDoc.innerHTML = "";
//Add back each element
for (var j = 0; j < arr.length; j++) {
var newElement = {};
var newElement = document.createElement(tname);
newElement.setAttribute("id", arr[j]);
eDoc.appendChild(newElement)
console.log(newElement);
}
}//End of Flicker Clean Up
fixFlicker("div", "canvas");
I was the same problem.
"destroy()" method works to me!
Many thanks
Most helpful comment
You can't really replace the chart canvas because it requires some initialization done at the chart construction time but also because you should not use the chart object after calling
destroy(). So if you still want to use that approach, you need to create a new chart each time you re-create the canvas:But again, if your chart type doesn't change,
update()is the best approach :)