简体   繁体   English

谷歌图表不断重绘内存增加

[英]Google Chart Constant Redrawing Memory Increase

I'm redrawing the chart based on new data each second, and it works and looks great, but I notice it increase memory like 1 MB usage each second. 我每秒都会根据新数据重新绘制图表,它的工作原理看起来很棒,但我注意到它每秒增加1 MB的使用量。 Any way to fix this? 有任何解决这个问题的方法吗? I notice if I just have static charts, then the memory stabilizes, but once I add constant redrawing (in order to update data), the memory usage never stops. 我注意到如果我只有静态图表,那么内存稳定,但一旦我添加不断的重绘(为了更新数据),内存使用永远不会停止。

At first I thought it was because I was creating a new instance of the chart each time, so I change the code so it was only redrawing the same instance each time, but that didn't help much at all. 起初我以为是因为我每次都在创建一个新的图表实例,所以我改变了代码,所以每次只重绘相同的实例,但这根本没有多大帮助。

Anyone know how to fix it? 谁知道怎么修它? Do I need to dump the old chart first somehow? 我是否需要先以某种方式转储旧图表?

google.setOnLoadCallback(test);

var chart;
var chartOptions;
var chartCreate;

function test() {
    chart = new google.visualization.DataTable();
    chart.addColumn('string', 'Lorem');
    chart.addColumn('number', 'Ipsum');
    chart.addRows([
            ['', 0]
    ]);
    chartOptions = {};
    chartCreate = new google.visualization.LineChart(document.getElementById('chartDiv'));
          chartCreate.draw(chart, chartOptions);
    ]);
}

function test2() {
    chart.removeRows(0, 5);
    for (var i = 0; i < dataSpaceArray.length; ++i) {
        chart.addRow([dataTimeArray[i], dataSpaceArray[i], dataSpeedArray[i]]);
    }
        chartCreate.draw(chart, chartOptions);
}

setTimeout(test2,1000)

I've solved this by globaly store the chart. 我通过全球存储图表解决了这个问题。 Before draw the chart, you need to check if chart has been instantiated. 在绘制图表之前,您需要检查图表是否已实例化。 If not, create the new chart object else call clearChart() method before draw it. 如果没有,请创建新的图表对象,然后在绘制之前调用clearChart()方法。 Like this: 像这样:

//Store all chart objects in a global array to avoid memory leak
var charts = [];

function drawChart(chartName, element, data, chartOptions) {
   if (charts[chartName] === undefined || charts[chartName] === null) {
          charts[chartName] = new google.visualization.LineChart(group);
   } else {
          charts[chartName].clearChart();
   }
   charts[chartName].draw(dataTable, chartOptions);
}

Had same issue, was able to fix it by adding a few lines to Google's clearChart() function. 有同样的问题,能够通过向Google的clearChart()函数添加几行来修复它。

W.clearChart = function() {

    //this fixes the leak
    hv = {};
    iv = {};
    jv = {};

    ...
};

More Details: 更多细节:

  1. Here's the Google file I made the change to: 这是我更改为的Google文件:

https://www.google.com/uds/api/visualization/1.0/4086f2e8fc632adc52e6d6795a5637a4/format+en,default,corechart.I.js https://www.google.com/uds/api/visualization/1.0/4086f2e8fc632adc52e6d6795a5637a4/format+en,default,corechart.I.js

  1. Download this file, make the change mentioned above. 下载此文件,进行上述更改。 In your code, add a script tag to load above file from your webserver and comment out the following line: 在您的代码中,添加一个脚本标记以从您的网络服务器加载上述文件并注释掉以下行:

    // google.load('visualization', '1', { packages: ['corechart'] }); // google.load('visualization','1',{packages:['corechart']});

  2. The memory will go up but will come back down on it's own after a few minutes. 记忆力会上升但几分钟后会自行恢复。

  3. I'm using clearChart() but if you don't want to clear the chart, then create your own function (eg memoryLeakFix()) and call it periodically. 我正在使用clearChart()但是如果你不想清除图表,那么创建你自己的函数(例如memoryLeakFix())并定期调用它。

  4. Here's a test page (the 1.js is the modified file from step 1). 这是一个测试页面(1.js是步骤1中的修改文件)。 It basically creates new chart and redraws every 100ms. 它基本上每100毫秒创建一个新图表和重绘。 You will see memory go up but hit "Stop" link to stop the redrawing and wait a few minutes and memory will come down. 你会看到内存上升,但点击“停止”链接停止重绘并等待几分钟,内存将会下降。

 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js" type="text/javascript"></script> <script src="https://www.google.com/jsapi" type="text/javascript"></script> <script src="1.js" type="text/javascript"></script> <script type="text/javascript"> //init google charts // google.load('visualization', '1', { packages: ['corechart'] }); google.load('visualization', '1', { packages: ['table'] }); </script> </head> <body> <a href='#' onclick='stop()'>Stop</a> <div class='chart'></div> <script> var chart; var table; function createChart(container) { if(chart != undefined) chart.clearChart(); //init chart chart = new google.visualization.LineChart(container[0]); //init chart data if(table == undefined) { table = new google.visualization.DataTable(); table.addColumn('datetime', 'Time'); table.addColumn('number', 'Value'); var count = 0; //periodically add rows setInterval(function() { //add row table.addRows([ [new Date(), count++]]); }, 1000); } } //start redrawing var id = setInterval(function() { createChart($('.chart')); drawChart(); }, 100); //stop redrawing function stop() { clearInterval(id); } //draw chart function drawChart() { chart.draw(table, { curveType: "function", width: 250, height: 250, pointSize: 1, legend: { position: 'none' }, chartArea: { 'width': '90%', left: 50 }, }); } </script> </body> </html> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM