简体   繁体   English

优化JavaScript DrillDown代码

[英]Optimize JavaScript DrillDown code

I have a drilldown map on my page which I would like to optimise. 我的页面上有一个向下钻取的地图,我想对其进行优化。 Right now I am loading every "drilldown" map even if it is not clicked. 现在,即使没有单击,我也会加载每个“向下钻取”地图。

Here is an example that shows how the data is load if the state is clicked.I would like to achieve that. 是一个示例,显示了单击状态后如何加载数据,我想实现这一点。

But this is my code and as you can see, I am loading all drilldown jsons even if the map is not clicked. 但这是我的代码,如您所见,即使未单击地图,我也会加载所有钻取json。 In my example I have only 2 drilldown option, but in my real life problem I have it like 15 so it really slows down a little bit everything. 在我的示例中,我只有2个向下钻取选项,但是在我的现实生活中,我有15个这样的选项,因此它确实使一切变慢了。

So this is my code: 这是我的代码:

// get main map
$.getJSON('json/generate_json_main_map.php', function(data) {

    // get region 1 map
    $.getJSON('json/generate_json_region_1.php', function(first_region) {

        // get region 2 map
        $.getJSON('json/generate_json_region_2.php', function(second_region) {

            // Initiate the chart
            $('#interactive').highcharts('Map', {
                title: {
                    text: ''
                },
                colorAxis: {
                    min: 1,
                    max: 10,
                    minColor: '#8cbdee',
                    maxColor: '#1162B3',

                    type: 'logarithmic'
                },
                series: [{
                    data: data,
                    "type": 'map',
                    name: st_ponudb,
                    animation: {
                        duration: 1000
                    },
                    states: {
                        //highlight barva
                        hover: {
                            color: '#dd4814'
                        }
                    }
                }],
                drilldown: {
                    drillUpButton: {
                        relativeTo: 'plotBox',
                        position: {
                            x: 0,
                            y: 0
                        },
                        theme: {
                            fill: 'white',
                            'stroke-width': 0,
                            stroke: 'white',
                            r: 0,
                            states: {
                                hover: {
                                    fill: 'white'
                                },
                                select: {
                                    stroke: 'white',
                                    fill: 'white'
                                }
                            }
                        }
                    },
                    series: [{
                        id: 'a',
                        name: 'First',
                        joinBy: ['hc-key', 'code'],
                        type: 'map',
                        data: first_region,
                        point: {
                            events: {
                                click: function() {
                                    var key = this.key;
                                    location.href = key;
                                }
                            }
                        }
                    }, {
                        id: 'b',
                        name: 'Second',
                        joinBy: ['hc-key', 'code'],
                        type: 'map',
                        data: second_region,
                        point: {
                            events: {
                                click: function() {
                                    var key = this.key;
                                    location.href = key;
                                }
                            }
                        }
                    }]
                }
            });
        });
    });
});

JSON from generate_json_main_map.php: 来自generate_json_main_map.php的JSON:

[{"drilldown":"a","name":"region 1","value":"1","path":""},{"drilldown":"b","name":"region 2","value":"2","path":""}]

JSON from generate_json_region_1.php: 来自generate_json_region_1.php的JSON:

[{"name":"Place 1","key":"place.php?id=1","value":"1","path":""},{"name":"Place 2","key":"place.php?id=2","value":"2","path":""}]

This is my attempt to make ajax calls load in parallel, but the map is not loading, I get just the coloraxis. 这是我尝试并行加载ajax调用的尝试,但是地图没有加载,我只得到了coloraxis。

$(function() {

        $.when($.getJSON('json/generate_json_main_map.php'), $.getJSON('json/generate_json_region_1.php'), $.getJSON('json/generate_json_region_2.php')).done(function(data,first_region,second_region){

                $('#interactive').highcharts('Map', {
                    title: {
                        text: ''
                    },
                    colorAxis: {
                        min: 1,
                        max: 10,
                        minColor: '#8cbdee',
                        maxColor: '#1162B3',

                        type: 'logarithmic'
                    },
                    series: [{
                        data: data,
                        "type": 'map',
                        name: st_ponudb,
                        animation: {
                            duration: 1000
                        },
                        states: {
                            hover: {
                                color: '#dd4814'
                            }
                        }
                    }],
                    drilldown: {
                        drillUpButton: {
                            relativeTo: 'plotBox',
                            position: {
                                x: 0,
                                y: 0
                            },
                            theme: {
                                fill: 'white',
                                'stroke-width': 0,
                                stroke: 'white',
                                r: 0,
                                states: {
                                    hover: {
                                        fill: 'white'
                                    },
                                    select: {
                                        stroke: 'white',
                                        fill: 'white'
                                    }
                                }
                            }
                        },
                        series: [{
                            id: 'a',
                            name: 'First',
                            joinBy: ['hc-key', 'code'],
                            type: 'map',
                            data: first_region,
                            point: {
                                events: {
                                    click: function() {
                                        var key = this.key;
                                        location.href = key;
                                    }
                                }
                            }
                        }, {
                            id: 'b',
                            name: 'Second',
                            joinBy: ['hc-key', 'code'],
                            type: 'map',
                            data: second_region,
                            point: {
                                events: {
                                    click: function() {
                                        var key = this.key;
                                        location.href = key;
                                    }
                                }
                            }
                        }]
                    }
                });
            });
        }); 

I can see that the jsons are loaded and there is no JS error shown by firebug. 我可以看到已加载json,firebug没有显示JS错误。

If you want to load on click, you need to call the state data on click_event (and not at startup). 如果要加载click,则需要在click_event上调用状态数据(而不是在启动时)。

Just like your JSFiddle example: 就像您的JSFiddle示例:

chart : {
        events: {
            drilldown: function (e) {
// Load you data
// show it with  chart.addSeriesAsDrilldown(e.point, {...});
            }
        }
}

Or as @Whymarrh suggests, you can load them all in parallel (instead of one after the other) and once they are all retrieved, compute your map. 或者如@Whymarrh所建议的,您可以并行加载它们(而不是一个接一个地加载),一旦它们全部被检索,就可以计算地图。

See https://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/ for example on how to execute a code after all ajax calls have completed. 有关所有ajax调用完成后如何执行代码的信息,请参见https://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/

When you load your map data as you did, in the following manner: 当您按以下方式加载地图数据时,可以通过以下方式进行:

$.when(
    $.getJSON('json/generate_json_main_map.php'),
    $.getJSON('json/generate_json_region_1.php'),
    $.getJSON('json/generate_json_region_2.php')
).done(...);

The effect is this - when any of the three requests fail, all promises will be rejected and ultimately, your map never gets to be initialised. 结果是-当三个请求中的任何一个失败时,所有的诺言都会被拒绝,最终,您的地图将永远不会被初始化。

A better approach could be to request all data independently, and the outcomes would be handled as follows: 更好的方法可能是独立请求所有数据,结果将按以下方式处理:

  • If the request for the main data fails, abort the other requests unconditionally (there would be no need for a drill down if the primary data is non-existent). 如果对主数据的请求失败,则无条件中止其他请求(如果不存在主数据,则无需进行深入分析)。
  • If request for main data succeeds, you may go on and initialise the map as data becomes available. 如果对主要数据的请求成功,您可以继续进行并在数据可用时初始化地图。 The request for drill down data may or may not succeed though (but half bread is better than none?). 向下钻取数据的请求可能成功也可能不会成功(但是半面包总比没有好?)。 Assuming everything goes well, then in the event that user initiates a drill down action, you show a loading message and ultimately add the drill down series when it becomes available. 假设一切顺利,那么在用户启动向下钻取操作的情况下,您会显示一条加载消息,并在可用时最终添加向下钻取系列。

Here's an implementation of the method I offered: 这是我提供的方法的实现:

$(function () {        
    // immediately trigger requests for data
    var loadMainData = $.getJSON("json/generate_json_main_map.php");
    var loadRegionData = {
        "region-1-name": $.getJSON("json/generate_json_region_1.php"),
        "region-2-name": $.getJSON("json/generate_json_region_2.php")
    };

    // region drilldown options
    var regionalSeriesOptions = {
        "region-1-name": {
            id: 'a',
            name: 'First',
            joinBy: ['hc-key', 'code'],
            type: 'map',
            point: {
                events: {
                    click: function () {
                        var key = this.key;
                        location.href = key;
                    }
                }
            }
        },
        "region-2-name": {
            id: 'b',
            name: 'Second',
            joinBy: ['hc-key', 'code'],
            type: 'map',
            point: {
                events: {
                    click: function () {
                        var key = this.key;
                        location.href = key;
                    }
                }
            }
        },
        // ...
        "region-(n-1)-name": {
            // series options for region 'n-1'
        },
        "region-n-name": {
            // series options for region 'n'
        },
        "region-(n+1)-name": {
            // series options for region 'n+1'
        }
    };

    // main options
    var options = {
        title: {
            text: ""
        },
        series: [{
                type: "map",
                name: st_ponudb,
                animation: {
                    duration: 1000
                },
                states: {
                    hover: {
                        color: "#dd4814"
                    }
                }
            }],
        events: {
            drilldown: function (e) {
                var regionName, request, series, chart;

                if (e.seriesOptions) {
                    // drilldown data is already loaded for the currently
                    // selected region, so simply return
                    return;
                }

                regionName = e.point.name;
                request = loadRegionData[regionName];
                series = regionalSeriesOptions[regionName];
                chart = this;

                chart.showLoading("Loading data, please wait...");

                request.done(function (data) {
                    // series data has been loaded successfully
                    series.data = data;
                    chart.addSeriesAsDrilldown(e.point, series);
                });

                request.fail(function () {
                    if (loadMainData.readyState !== 4) {
                        // do you really want to cancel main request
                        // due to lack of drilldown data?
                        // Maybe half bread is better than none??
                        loadMainData.abort();
                    }
                });

                // whether success or fail, hide the loading UX notification
                request.always(chart.hideLoading);
            }
        },
        colorAxis: {
            min: 1,
            max: 10,
            minColor: '#8cbdee',
            maxColor: '#1162B3',
            type: 'logarithmic'
        },
        drilldown: {
            drillUpButton: {
                relativeTo: 'plotBox',
                position: {
                    x: 0,
                    y: 0
                },
                theme: {
                    fill: 'white',
                    'stroke-width': 0,
                    stroke: 'white',
                    r: 0,
                    states: {
                        hover: {
                            fill: 'white'
                        },
                        select: {
                            stroke: 'white',
                            fill: 'white'
                        }
                    }
                }
            },
            series: []
        }
    };

    loadMainData.done(function (data) {
        options.series[0].data = data;
        $("#interactive").highcharts("Map", options);
    }).fail(function () {
        Object.keys(loadRegionData).forEach(function (name) {
            // if primary data can't be fetched,
            // then there's no need for auxilliary data
            loadRegionData[name].abort();
        });
    });
});

Since I don't know every detail of your code, it's left for you to find a way to fit it into your solution. 由于我不了解您代码的每个细节,因此您可以找到一种方法将其适合您的解决方案。

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

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