构建多个图表时,HighCharts加载数据的速度较慢

HighCharts is slow to load data when building multiple charts

本文关键字:数据 加载 速度 HighCharts 构建      更新时间:2023-09-26

我有一个页面,上面有两个highCharts,我想知道是否有办法加快图表的加载时间。第一个是有2个系列的主图表,第二个更像是"缩略图"图表,有4个系列。

我用日期列表填充一个列表框,当用户选择每个日期时,我会调用ajax来获取一些数据。

我像这样在构造函数中构建图表…

basicMaxChart = function() {        
    options = {
    chart: {},
    /*missed for brevity*/,
    series: [{},{}] 
    }; // options
    return options;
}; // Max
basicMiniChart = function() {       
    optionsMini = {
    chart: {},
    /*missed for brevity*/,
    series: [{},{},{},{}] 
    }; // optionsMini
    return optionsMini;
}; // Mini

我的文档准备功能,

// Globals
var options;
var optionsMini;
var chart;
var chartMini;
jQuery("document").ready(function() {
    function createChart() {
        options = $.extend({}, basicMaxChart options);
        chart = new Highcharts.Chart(options);  
    };
    function createMiniChart() {
        optionsMini = $.extend({}, basicMiniChart(), optionsMini);
        chartMini = new Highcharts.Chart(optionsMini);
    };
    // create some empty charts for place holders
    createChart();
    createMiniChart();
    function loadData(){
        // missed for brevity, but declare some vars and get some values from inputs
        var aLen = document.getElementById("someInput").value;
        var d1 ...
        var data = {
                compareD1   : d1,
                m1          : m1,
                someVal     : aLen
               };
            $.post("getSomeData.php", data, function(json) {
                /* Clearing the series first or ‘Destroying’ the chart only only serves to make things worse …
                if (typeof chartMini != 'undefined') {
                    while(chartMini.series.length > 0)
                    chartMini.series[0].remove();
                    //chartMini.destroy();
                }
                */
                options.series[0] = json[0]; 
                options.series[1] = json[1];
                optionsMini.series[0] = json[3];
                optionsMini.series[1] = json[4];
                optionsMini.series[2] = json[5];
                optionsMini.series[3] = json[6];
                chart = new Highcharts.Chart(options);              
                chartMini = new Highcharts.Chart(optionsMini);
                chart.series[0].options.color = 'blue';
                chart.series[0].update(chart.series[0].options);
                chart.series[1].options.color = 'red';
                chart.series[1].update(chart.series[1].options);
                chartMini.series[0].options.color = '#A9CBE9';
                ….
                ….
                chartMini.series[3].update(chartMini.series[3].options);
            }, "json");
}); // ready

loadData函数进行ajax调用并返回一个json对象,该对象包含大约500ms内两个图表的数据。(我对getSomeData.php脚本的速度感到满意)。

如果我从loadData函数中删除了与chartMini/optionsMini相关的所有内容,那么主图表的加载也会非常快。但当我把"Mini"扔回去时,事情就慢了下来,两张图表都没有显示大约5秒(事实上,我经常在FireFox中收到"没有回应"的消息)。json对象中的每个"Data"元素都有700个数据点(我不认为它特别大)。

我认为我对高线图缺乏经验是速度缓慢的原因。我想问你是否对我如何提高这两个图表的构建/加载时间的性能有什么建议。

感谢阅读。

从您显示的代码来看,代价高昂的部分是在您创建图表后,但要继续更新它。您进行的每个update方法调用都会强制执行redraw,这对资源要求很高。

理想情况下,在创建图表之前完成所有选项。这稍微取决于您的JSON是否正确,但想象一下这样的东西:

options.series[0] = json[0];
options.series[0].options.color = 'blue';   
options.series[1] = json[1];
options.series[1].options.color = 'red';
optionsMini.series[0] = json[3];
optionsMini.series[0].options.color = '#A9CBE9';
// ...
chart = new Highcharts.Chart(options);              
chartMini = new Highcharts.Chart(optionsMini);

如果JSON中还不存在options对象,则可能需要创建该对象。

另一种懒惰的变体是推迟当前代码中的redraw,然后再手动执行redraw

chart = new Highcharts.Chart(options);              
chartMini = new Highcharts.Chart(optionsMini);
chart.series[0].options.color = 'blue';
chart.series[0].update(chart.series[0].options, false); // false to prevent redraw
chart.series[1].options.color = 'red';
chart.series[1].update(chart.series[1].options, false); // false to prevent redraw
chartMini.series[0].options.color = '#A9CBE9';
chartMini.series[0].update(chartMini.series[0].options, false); // false to prevent redraw
// ...
chart.redraw(); // force redraw after all changes are made
chartMini.redraw(); // force redraw after all changes are made

请注意,这比第一种方法慢,因为它需要多次更新序列中的大量数据,并且还需要对每个图表进行一次redraw,这在第一种方法中是不会发生的。