Optimize JavaScript DrillDown Code

I have a summary map on my page that I would like to optimize. Right now I am loading every sweep card, even if it is not pressed.

Here is an example showing how the data is loaded when the state is clicked. I would like to achieve this.

But this is my code, and as you can see, I load all U-turn units, even if the card is not pressed. In my example, I only have 2 options for detailing, but in my real life problem I have it looks like 15, so it really slows things down.

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:

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

JSON from generate_json_region_1.php:

 [{"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 load ajax calls in parallel, but the map does not load, I only get 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 see that jsons are loaded and there is no JS error shown by firebug.

+8
optimization json javascript highcharts
source share
2 answers

If you want to load by click, you need to call the state data on click_event (and not at startup).

Like your JSFiddle example:

 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 (and not one by one), and as soon as they are all restored, figure out your map.

See https://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/ , for example, on how to execute code after all ajax calls have completed.

+1
source share

When you download map data in the same way as you do, as follows:

 $.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 fails, all promises will be rejected and, ultimately, your card will never be initialized.

The best approach would be to query all the data independently, and the results will be processed as follows:

  • If the request for master data fails, cancel the rest of the requests unconditionally (there is no need for details if the primary data does not exist).
  • If the request for master data has been completed, you can continue and initialize the card when the data becomes available. A request for data granularity may or may not be successful (but is half the bread better than none?). Assuming everything is going well, then if the user initiates a drilling action, you display a boot message and ultimately add a drilling series when it becomes available.

Here is the implementation of the method I proposed:

 $(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 no need for auxilliary data loadRegionData[name].abort(); }); }); }); 

Since I don’t know every detail of your code, it left you the opportunity to find a way to put it in your solution.

+1
source share

All Articles