ningwentao 2012-09-12
jqPlot是一个十分强大、功能丰富的图表插件,能够显示走势图、柱形图等常用的图表类型,相信国内用的人很多。
大家在使用jqPlot动态更新图表时,也许会碰到过在IE中出现内存溢出的问题,下面我们来看看集中动态更新jqPlot图表的方式:
方式一:通过重建图表实现动态显示。
var series = [{'test'}]; var axes = { xaxis : { renderer : $.jqplot.CategoryAxisRenderer, ticks : [] }, yaxis : { min : 0, max : 10, tickInterval : 2 } }; var plotConfig = createBarChartOptions(axes, series); resizeGlobalMonitorChartContainer(containerId); var plot = $.jqplot(g_channelDivId, chartData, plotConfig);
实际上我们通过重复的创建图表,确实可以实现动态更新,不过在IE下,我们会发现内存增长很厉害,起初,通过尝试在重新创建图表时,提前销毁旧的图表来释放内存:
/** * 将plot图表从容器中销毁。 * * @param containerId * 容器ID。 * @param plot * 在容器中的图表。 */ function releasePlotChart(containerId, plot) { if (plot) { plot.destroy(); var elementId = '#' + containerId; $(elementId).unbind(); // for iexplorer $(elementId).empty(); plot = null; } }
当我们观察内存变化的时候,会发现销毁图表时内存减少了,但是重建之后,内存会比原来多出一些,一定时间以后,内存就会不断的增加,最后导致内存溢出。
方式二:通过动态数据加载,重绘实现。
/** * 重绘plot图表。 * * @param containerId * 容器ID。 * @param chartData * 图表数据。 * @param plotConfig * 图表配置信息。 * @returns 返回重绘后的图表对象。 */ function replotChart(plot, chartData) { setChartDataToPlot(plot, chartData); plot.replot({ resetAxes : true }); return plot; } /** * 将最新的数据设置到plot图表中。 * * @param plot * @param chartData */ function setChartDataToPlot(plot, chartData) { for ( var i = 0; i < plot.series.length; i++) { for ( var j = 0; j < plot.series[i].data.length; j++) { try { plot.series[i].data[j][1] = chartData[i][j]; } catch (e) { } } } }
通过运用这种方式,再次观察内存变化,会发现内存溢出问题已经不存在了。
从中我们发现,只要重建Plot图表,内存就会出现递增的现象,因此,当我们需要切换图表的时候,最好将原来的图表隐藏起来,当再次需要显示的时候,再恢复显示,从而避免重复创建图表,从而导致内存溢出。