优化JavaScript DrillDown代码

时间:2015-08-14 21:10:14

标签: javascript json optimization highcharts

我的页面上有一个钻取地图,我想优化。 现在我正在加载每一个" drilldown"即使没有点击也会映射。

Here是一个示例,显示了在单击状态时如何加载数据。我希望实现这一点。

但这是我的代码,正如你所看到的,即使未点击地图,我也会加载所有向下钻取的jsons。在我的例子中,我只有2个向下钻取选项,但在我的现实生活中遇到的问题我就像15一样,所以它确实减慢了一切。

所以这是我的代码:

// 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;
                                }
                            }
                        }
                    }]
                }
            });
        });
    });
});

generate_json_main_map.php中的JSON:

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

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":""}]

这是我试图让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;
                                    }
                                }
                            }
                        }]
                    }
                });
            });
        }); 

我可以看到jsons已加载,并且firebug没有显示JS错误。

2 个答案:

答案 0 :(得分:1)

如果要加载点击,则需要在click_event上调用状态数据(而不是在启动时)。

就像您的JSFiddle示例:

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

或者正如@Whymarrh建议的那样,你可以将它们全部并行加载(而不是一个接一个地加载),一旦它们全部被检索,就可以计算你的地图。

有关如何在所有ajax调用完成后执行代码的示例,请参阅https://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/

答案 1 :(得分:1)

按照以下方式加载地图数据时:

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

效果就是这样 - 当三个请求中的任何一个失败时,所有承诺都将被拒绝,最终,您的地图永远不会被初始化。

更好的方法可以是独立地请求所有数据,结果将按如下方式处理:

  • 如果对主数据的请求失败,则无条件地中止其他请求(如果主数据不存在则不需要向下钻取)。
  • 如果对主数据的请求成功,您可以在数据可用时继续初始化地图。虽然钻取数据的请求可能成功也可能不成功(但是半面包比没有面包好?)。假设一切顺利,那么在用户启动向下钻取操作的情况下,您将显示加载消息并最终在可用时添加向下钻取系列。

这是我提供的方法的实现:

$(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();
        });
    });
});

由于我不了解您的代码的每个细节,因此您可以找到适合您的解决方案的方法。