You must be logged in to post your query.
Home › Forums › Report Bugs › Weird Chart Behaviour in IOS Browser on mobile?
We can only reproduce this in ios browsers on mobile devices
I have included a link to a repl.it
a simple example demonstrating the problem at the bottom of this post.
(make sure you click the open in new tab popout thing to get just the webpage in your iPad or iPhone)
there are 12 charts (without much data), when you click the add datapoint button, it will render fine for several clicks(between 2-10… probably never more than 20 before the error occurs), then it will stop rendering traces, and eventually stop rendering the entire chart.
even when the chart is not rendering you can still see the hover popups (and sometimes the chart title)
sometimes click to update the last point, or add a new point will cause traces to come back in some charts (and disappear in others)
(you can also reproduce just by refreshing the page several times)
(to make it occur faster you can increase the NUM_CHARTS
variable in the javascript(if you have a newish iPad PRO it takes more clicks and charts to reproduce))
simple example @ https://repl.it/repls/SpicyUnfinishedCryptos
this example is based off https://canvasjs.com/docs/charts/basics-of-creating-html5-chart/updating-chart-options/
SUCESSFULLY REPRODUCED on iPhone X and iPhone XS and iPad 5th GEN, (it took about 20 charts to reproduce on Gen2 iPad PRO)
Earlier WebKit allowed 448MB of canvas buffer memory whereas now they have dropped it to 224MB. Because of this, there was some memory issue with CanvasJS Charts in the latest iOS. However, we had optimized memory consumption in CanvasJS v2.3 – please check out this release blog for more info.
Also, we will further optimize it in future releases.
—-
Manoj Mohan
Team CanvasJS
Thanks for getting back to me… Im not sure how to check the “canvas buffer memory” , however the (linked example) site only reports about 17mb of “VM memory” use-age in chrome developer tools … can you tell me how to monitor the buffer memory? or inspect it?
also i found this that might be of interest https://stackoverflow.com/a/52586606/541038 that claims the memory of canvas is not freed on reload or destroy, so you can work around it by setting the width and height of the canvas element(s?) to zero … Im not sure if i can hook into your overlay canvas or _prerenderCanvas or whatever to do this on my end (maybe i can im going to try tomorrow)
OK so some further information I found today (I used the safari dev tools panel which includes a canvas tab)
chart.destroy();chart = null
had did not release the earlier canvases memory
[HTMLCanvasElement].height = 0; [HTMLCanvasElement].width = 0; [HTMLCanvasElement].style.width = 0; [HTMLCanvasElement].style.height = 0
before calling destroychart.ctx.canvas, chart.overlayCanvas, chart.legend.ghostCtx.canvas, chart._preRenderCtx.canvas
here is the code i used to clean up before calling chart.destroy;chart = null
const ele = document.getElementById("chartContainer"); const c = chartsInstances[chartId] c.legend.ghostCtx.canvas.style.height = 0; c.legend.ghostCtx.canvas.height = 1; c.legend.ghostCtx.canvas.style.width = 0; c.legend.ghostCtx.canvas.width = 1; c._preRenderCtx.canvas.width = 1; c._preRenderCtx.canvas.height = 1; c._preRenderCtx.canvas.style.width = 0; c._preRenderCtx.canvas.style.height = 0; const canvases = ele.querySelectorAll('canvas'); for (const canvas of canvases) { canvas.width = 1; canvas.height = 1; canvas.style.width = 0; canvas.style.height = 0; }
Thanks for your suggestion. We will further improve this behaviour in future releases.
—-
Manoj Mohan
Team CanvasJS
thanks for the response :)
can you help suggest where i might be able to find the 5th canvas element? or how to capture it… I just can’t find it and the datastructure is big…. im probably looking right past it
– Joran
I found it
this line
this._preRenderCanvas = createCanvas(this.width, this.height);
@ roughly line 5044 in CanvasJS.js
overwrites the canvas instance that already exists for variable this._preRenderCanvas
effectivly orphaning the old canvas (which IOS will not GC because its not size 0)
I fixed it by patching it to
if(this._preRenderCanvas){
setCanvasSize(this._preRenderCanvas,0,0)
}
this._preRenderCanvas = createCanvas(this.width, this.height,"_preRenderCanvas");
You must be logged in to reply to this topic.