Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line chart causes browser memory leak #462

Closed
jconnor34 opened this issue Jul 17, 2014 · 14 comments
Closed

Line chart causes browser memory leak #462

jconnor34 opened this issue Jul 17, 2014 · 14 comments

Comments

@jconnor34
Copy link

I am updating a Line chart using ajax. It works great, however the browser memory ramps up to where it causes the browser to crash. I have tested on Chrome, Firefox on both Windows and Linux.
My technique is to get the JSON dataset and create a new chart every 10 seconds.

myCanvas = document.getElementById("lineCanvas");
myContext = myCanvas.getContext('2d');
myLineChart = new Chart(myContext).Line(myJSON,myOptions);

Is there a way to just update the Line Chart with the new myJSON data received and not create a new Chart object every time? I see the ".update()" function, but I can't seem to get it to work.

I can make the memory leak go away by simply not creating a new Chart object, but that doesn't allow me to chart anything....

UPDATE:
I have tried the ".destroy()" and I am still getting the memory wind up to crash, although it seems to ramp up slower now. I am also seeing a high amount of CPU usage. The browser indicates the e.Scale.Draw() is using the most CPU time. Not sure what that means.

@ganna-shmatova
Copy link

While this is a problem...

update seems like just a call to re-read the cached data in the chart.
set data first, then call update:

myLineChart.datasets[0].points[2].value = 50;
myLineChart.update();

Also, I've been using add...

if(cpuChart.datasets[0].points.length > 20)
    cpuChart.removeData();
cpuChart.addData([firstLineNum, secondLineNum], 'label');

but my charts are eating CPU like no one's business regardless

@danielhunt
Copy link

The biggest problem with the .value approach, is that the initial object that is created when you instantiate the object, it doesn't add .any.points[y] for data points that are null.

This means that no amount of .update() will fix the data, resulting in a required .destroy(), which, as already pointed out, results in a memory leak

@ganna-shmatova
Copy link

Yeah I ran into that problem too at some point. I kind of hacked my way around it.
I gave the value of 0.001
then in the template I rounded:

tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= parseFloat(value).toFixed(2) + ' " + symbol + "'%>"

@danielhunt
Copy link

I'm overlaying multiple days worth of information, along with today's real-time line.
The data for later in the day (naturally enough) doesn't exist yet, but dropping a 0 or 0.001 in there will make the graphs appear to plummet when really, it should just cease to exist, so that workaround is not a runner for me I'm afraid.

@nnnick
Copy link
Member

nnnick commented Jul 20, 2014

I've actually been working on a PR which changes how we add points for catering with sparse datasets.

Check out #435 for progress on this.

Memory leaks are always a bit tricky to isolate - but I'd appreciate any test cases etc showing the issue happening and I'l be able to debug a bit futher.

@danielhunt
Copy link

re: memory leak:
I have 4 Line() graphs on display, with each graph having a total of 3 lines within it.
2 showing historical data, along with a third line representing the current day (which is constantly moving forward in time.)
Because I can't just populate the dataset using the .points array, I need to call .destroy(), followed by recreating the Line() entirely from scratch.

Each graph is updated every 5 seconds (resulting in a destroy & new Line() for each graph, every time)
Each of the graphs contain a different number of points-per-line, but each graph represents:

  • 1 day (24 hours, so 24 datapoints per line)
  • 1 day (24 hours, 24 datapoints per line) - different data
  • 1 week (7 days - 7 datapoints per line)
  • 1 month (up to 31 days - up to 31 datapoints per line)

It's clear after just a couple of minutes that there's a memory leak, but beyond that, I'm afraid I don't have much more detail.
Does that help?

@jconnor34
Copy link
Author

My graphs are using roughly 1200 points each. It is an engineering based application and all the points are required (no aggregation). They are analog values from instruments like conductivity and temperature sensors. I am currently rendering 6 of these line charts on one screen and Graph.js does an amazing job rendering them, with the exception of the memory leak.

What kind of information would help in resolving the issue? Would profiler dumps from the web browser help?

I would like to help any way I can because I believe this graphing library is one of the best out there!

@jconnor34
Copy link
Author

I put my JSON dataset on dropbox if you would like to use it for troubleshooting. I believe that you can just use this same data over and over and experience the memory leak first hand.

https://www.dropbox.com/s/pyktgt88n3m0sdp/data.json

@nnnick
Copy link
Member

nnnick commented Jul 21, 2014

If you could make a JSbin that shows an example of what you're trying to do, that'd be most helpful for me to debug the issue.

@nnnick
Copy link
Member

nnnick commented Jul 21, 2014

I must admit I haven't stress tested Chart.js to quite that many individual data points on an indexed Line chart instance.

I'm planning to add a series chart instance to cope a little better with those sorts of demands, but I'm still interested to look into possible memory leaks in the core.

@makerlabs
Copy link

Guys first of all show us your code or at least a test case which prove that there is a memory leak. First of all check if your code isn't fault because that is the usual problem. I've been using also line chart with real-time update and I don't experience any memory leak in my application.
jconnor34 1200 points with 6 lines each it's a huge chart... I will consider to narrow your chart because I highly doubt that you will be able to analyze all of the points in one pass. It's better to represent the data in a data table with a chart and select a part of the data not the whole. If you want of course represent the whole chart I would consider to use some kind of sampling to narrow your chart series.
If you can't do it I will consider to disable animations because they are the first thing which will eat up your CPU in seconds...

@nnnick
Copy link
Member

nnnick commented Aug 17, 2014

Closing as there hasn't been any follow up or examples

@nnnick nnnick closed this as completed Aug 17, 2014
@gert789
Copy link

gert789 commented Dec 17, 2014

Hey guys,

I think I can provide an example of this problem.

Every 10 seconds I'm cloning a template, adding it to the body of my html. In this template, I got an empty canvas in which I draw a new line graph.

code that draws this graph:

graphData = {
        labels: dummyLabels(message.value.length),
        datasets: [
            {
                fillColor: "rgba(151,187,205,0.2)",
                strokeColor: "rgba(151,187,205,1)",
                pointColor: "rgba(151,187,205,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(151,187,205,1)",
                data: message.value
            }
        ]
    };

    var chart = new Chart($view.find('.graph-chart')[0].getContext('2d'));
    var charType = chart.Line(graphData, {
        labelAlign: 'center',
        skipLabels: true,
        bezierCurve: false,
        scaleBeginAtZero: true,
        scaleOverride: true,
        scaleSteps: 8,
        scaleStepWidth: scaleStepWidth,
        scaleStartValue: 0,
        scaleFontSize: 30,
        scaleFontStyle: 'bold',
        animationSteps: 20
    });

My application is a monitoring app that runs day and night, whitout refresh.

After a few hours, the browser crashes because of memory usage.
I did some monitoring with Chrome and this came out: http://i58.tinypic.com/1239k53.png

The ChartType for every chart stays in memory, while the graph itself gets deleted.

@juliepiq
Copy link

Hi,

I have same issue with my script : Memory leak using chart.js and setinterval.
Did you finally found a solution ?

Thanks

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants