在使用 C3 绘制图表之前同步调用加载 json 个文件

Synchronous call to load json files before draw the chart with C3

我遇到以下情况:在触发函数生成图表之前需要加载三个不同的 JSON 文件。这是代码:

<div id="jsonloading"></div>
<div id="chartc3"></div>
<script>
    var scene;
    var surchargedata;
    var ratiodata;
    var variables;

    $.getJSON('/assets/json/surcharge.json', function(data) {
        surchargedata = data;
        console.log(surchargedata);
    });

    $.getJSON('/assets/json/ratio.json', function(data) {
        ratiodata = data;
        console.log(ratiodata);
    });

    $.getJSON('/assets/json/variables.json', function(data) {
        variables = data;
        console.log(variables);
    });

    $.getJSON('/assets/json/chartc3.json', function(data) {
        console.log("chartc3");
        console.log(surchargedata);
        console.log(ratiodata);
        console.log(variables);
        //Max value for y-axis
        scene = data;
        var maxs = 0;
        for (var j = 0; j < scene.length; j++) {
            var maxtemp = Math.max(scene[j].Marketable, scene[j]['Your Bid'], scene[j]['Total Requested Capacity']);
            maxs = Math.max(maxs, maxtemp);
        }

        //Chart
        var chart = c3.generate({
            bindto: '#chartc3',
            data: {
                json: scene,
                selection: {
                    enabled: false
                },
                keys: {
                    x: 'round',
                    value: ['Marketable', 'Total Requested Capacity', 'Your Bid'],
                },
                types: {
                    Marketable: 'area'
                },
                colors: {
                    Marketable: '#EBEBEB',
                        'Total Requested Capacity': '#272E80',
                        'Your Bid': '#00888A'
                }
            },
            point: {
                show: false
            },
            axis: {
                x: {
                    type: 'category',
                    label: {
                        text: 'Round Number',
                        position: 'outer-center',
                    }
                },
                y: {
                    min: 0,
                    padding: {
                        bottom: 0
                    },
                    tick: {
                        values: [
                            [0],
                            [maxs]
                        ],
                        format: function(d) {
                            return d3.format(',f')(d) + " " + variables.unit
                        }
                    }
                }
            },
            grid: {
                y: {
                    lines: [{
                        value: 10000000,
                        text: 'Value'
                    }]
                },
            },
            legend: {
                position: 'right'
            },
            regions: [{
                axis: 'x',
                start: 29,
                end: 34,
                class: 'regionX'
            }, ],
            tooltip: {
                contents: function(d, defaultTitleFormat, defaultValueFormat, color) {
                    var $$ = this,
                        config = $$.config,
                        CLASS = $$.CLASS,
                        titleFormat = config.tooltip_format_title || defaultTitleFormat,
                        nameFormat = config.tooltip_format_name || function(name) {
                            return name;
                        },
                        valueFormat = config.tooltip_format_value || defaultValueFormat,
                        text, i, title, value, name, bgcolor;

                    var count = 0;
                    for (i = 0; i < d.length; i++) {
                        if (!(d[i] && (d[i].value || d[i].value === 0))) {
                            continue;
                        }

                        if (!text) {
                            title = 'Round:' + scene[d[i].index].round + ', Ratio: ' + ratiodata[d[i].index].ratio + " %";
                            text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
                        }

                        name = nameFormat(d[i].name);
                        value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
                        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);

                        text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
                        text += "<td class='name'><span style='background-color:" + bgcolor + "; border-radius: 5px;'></span>" + name + "</td>";
                        text += "<td class='value'>" + value + "</td>";
                        text += "</tr>";
                    } //for

                    text += "<tr class='" + CLASS.tooltipName + "-Surcharge" + "'>";
                    text += "<td id='footer'>" + "Surcharge: " + surchargedata[d[0].index].Surcharge + "</td>";
                    text += "<td id='footer'></td>";
                    text += "</tr></table>";

                    return text;
                }
            }

        }); //end chart
        //chart.select(['Marketable'], [31,32,33]);
    }); //end getjson
</script>

我知道 getJson() 是异步的,所以我不能确定在触发图表函数 (generate()) 之前加载所有数据。此外,我不能使用 async=false 属性,因为它已被弃用。

保证正确行为的最佳解决方案是什么?

您可以将 $.getJSON 调用返回的承诺存储在一个数组中。然后,您可以将此数组提供给 $.when,以便在所有请求完成后执行图表初始化代码。试试这个:

var promises = []
promises.push($.getJSON('/assets/json/surcharge.json', function(data) { 
    surchargedata = data;
}));
promises.push($.getJSON('/assets/json/ratio.json', function(data) { 
    ratiodata = data;
}));
promises.push($.getJSON('/assets/json/variables.json', function(data){ 
    variables = data;
}));

$.when.apply(this, promises).done(function() {
    $.getJSON('/assets/json/chartc3.json', function(data) { 
        // setup chart here...
    });
});

但是请注意,最好将 surcharge.jsonratio.jsonvariables.json 组合成一个可以在一次调用中检索的对象。

我是这样解决的:

   <script>

    var sceneround;
    var surcharge;
    var ratiodata;
    var variables;

 $.ajax({
            url: '/assets/json/surcharge.json',
            dataType: 'json',

            success: function (response) {
                surcharge=response;
              Ratio();
            }
        }); 

function Ratio() {
 $.ajax({
            url: '/assets/json/ratio.json',
            dataType: 'json',

            success: function (response) {
                ratiodata=response;
              Variables();
            }
        }); 
};

function Variables() {
 $.ajax({
            url: '/assets/json/variables.json',
            dataType: 'json',

            success: function (response) {
               variables=response; 
              DrawChart();
            }
        }); 
};


function DrawChart() {
$.getJSON('/assets/json/chartc3.json', function(data) 
{ 

    //Max value for y-axis
    sceneround=data;