Race condition leading to Highcharts error #13

余生长醉 提交于 2019-12-10 22:37:49

问题


I have some tabs which are generated dynamically. Clicking on any of this tabs loads multiple charts(three or four) like a pie, column or a linechart simultaneously. I append this charts into dynamically generated html divs. All works good if i had to click a tab and wait for all the charts to be loaded. Problem happens when i keep on clicking tabs one after the other and not wait till all the charts are loaded. i get a javascript error inside highcharts.js file which logs Highcharts error #13. As far as i know i am doing proper document ready checks and then loading my charts into the divs. What seems to be the problem ? Is there a race condition happening or due to my code running asynchronously leading to problems? Here is the code:

//Function called on tablick:
function GetPod(podObj) {

        savedPortletsObj = [];
        var objtab = new Array();
        var htmlMarkup = '';
        $('#podHolder').empty();

        for (v = 0, pCount = podObj.length; v < pCount; v++) {
            htmlMarkup = "";
            // htmlMarkup = htmlMarkup + " <div  class='table-cell'>";
            htmlMarkup = htmlMarkup + " <article class='db-box bigFont' id='" + podObj[v].id + "_art' style='height: 100%;'>";
            htmlMarkup = htmlMarkup + " <div class='box-head' ><span> <strong>" + podObj[v].title.toString() + "</strong></span></div>";
            htmlMarkup = htmlMarkup + " <div class='dashboard-container'>";
            htmlMarkup = htmlMarkup + " <div class='tableContentDiv height250 fadeInBox' id='" + podObj[v].id + "'> "; // Charts are appended into this div
            htmlMarkup = htmlMarkup + " </div>";
            htmlMarkup = htmlMarkup + " </div>";
            htmlMarkup = htmlMarkup + " </article>";
            // htmlMarkup = htmlMarkup + " </div>";
            $(htmlMarkup).appendTo($('#podHolder')); // Finally appending the chart div to the parent div
            buildChart(podObj[v]);
            savedPortletsObj[v] = podObj[v];
        }

// Then i call buildChart

function buildChart(podObj) {
        switch (podObj.PodAttributes.type) {
            case "ColumnChart":
                // chartTypes[podObj.id] = podObj.PodAttributes.type;
              //  requirejs(["HTML5SpendDashboard/includes/js/views/column.chart.js"], function () {
                    var objChart = ColumnChart.getInstance();
                    onSuccessLoadChart(podObj, objChart);
              //  });
                break;
            case "dataGrid":
                //  chartTypes[podObj.id] = podObj.PodAttributes.type;
               // requirejs(["HTML5SpendDashboard/includes/js/views/grid.js"], function () {
                    var objChart = DataGrid.getInstance();
                    onSuccessLoadChart(podObj, objChart);
               // });

                break;
            case "lineChart":
               // //  chartTypes[podObj.id] = podObj.PodAttributes.type;
                //requirejs(["HTML5SpendDashboard/includes/js/views/line.chart.js"], function () {
                    var objChart = LineChart.getInstance();
                    onSuccessLoadChart(podObj, objChart);
               // });
                break;
            case "pieChart":
                //  chartTypes[podObj.id] = podObj.PodAttributes.type;
               // requirejs(["HTML5SpendDashboard/includes/js/views/pie.chart.js"], function () {
                    var objChart = PieChart.getInstance();
                    onSuccessLoadChart(podObj, objChart);
              //  });
                break;
        }
    }
    function onSuccessLoadChart(podObj, objChart) {

        objChart.BaseViewRef.Variables.ViewProperties = podObj;
        objChart.Build();

    }

// FInally Build is called after the instance was created for it , For eg: Column chart will be (Have created a separate js files for each chart)

var ColumnChart = (function () {
var instantiated;
var chart;
function init() {
    return {
        "ResultMethodName": "onResultHttpService",
        "Message": "ColumnChartdemo",
        "Build": function () {
            var objServiceLayer = $SL.getInstance();
            var param = {};
            param["QueryID"] = this.BaseViewRef.Variables.ViewProperties.InputParams;
            objServiceLayer.executeMethod("GetPodFilterData", param, "onResultHttpService", this, this.BaseViewRef.Variables.ViewProperties);

        },
        "BaseViewRef": $BV.getInstance(),
        "onResultHttpService": function (result, properties) {
            var json_str = Sys.Serialization.JavaScriptSerializer.deserialize(result);
            var data = [];
            var cat = [];
            var categoryField = properties.PodAttributes.categoryField;
            var valueField = properties.PodAttributes.valueField;
            for (var i in json_str) {
                var serie = new Array(json_str[i][categoryField], json_str[i][valueField]);
                var tmpCat = new Array(json_str[i][categoryField]);
                data.push(serie);
                cat.push(tmpCat);
            }

            $(document).ready(function () {
                chart = new Highcharts.Chart({
                    chart: {
                        renderTo: properties.id,
                        type: 'column'
                    },
                    credits: {
                        enabled: false
                    },
                    title: {
                        text: ''
                    },
                    subtitle: {
                        text: ''
                    },
                    xAxis: {
                        categories: cat
                    },
                    yAxis: {
                        labels: {
                            formatter: function () {
                                return this.value / properties.PodAttributes.divideBy
                            + properties.PodAttributes.dataTipUnitLabel.split('*')[1].toUpperCase();
                            }
                        },
                        min: 0,
                        title: {
                            text: ''
                        }
                    },
                    legend: {
                        layout: 'vertical',
                        backgroundColor: '#FFFFFF',
                        align: 'left',
                        verticalAlign: 'top',
                        x: 100,
                        y: 70,
                        floating: true,
                        shadow: true
                    },
                    tooltip: {
                        formatter: function () {
                            return '' +
                        this.x + ':' + '</br>' + properties.PodAttributes.dataTipUnitLabel.split('*')[0] +
                        Highcharts.numberFormat(this.y / properties.PodAttributes.divideBy, properties.PodAttributes.dPoint) +
                        properties.PodAttributes.dataTipUnitLabel.split('*')[1].toUpperCase();
                        }
                    },
                    plotOptions: {
                        series: {
                            allowPointSelect: true,
                            point: {
                                events: { click: function () {
                                    //                                    alert(this.category + ' : ' + Highcharts.numberFormat(this.y / properties.PodAttributes.divideBy, properties.PodAttributes.dPoint) +
                                    //                            properties.PodAttributes.dataTipUnitLabel.split('*')[1].toUpperCase());
                                    podsToRefresh = html5SpendDashboard.getInstance().getSavedPodObj();
                                    var objBuildChart = html5SpendDashboard.getInstance();
                                    for (var p = 0, pLen = podsToRefresh.length; p < pLen; p++) {
                                        objBuildChart.buildChart(podsToRefresh[p]);
                                    }
                                }
                                }
                            }
                        },
                        column: {
                            pointPadding: 0.2,
                            borderWidth: 0
                        }
                    },
                    series: [{
                        showInLegend: false,
                        data: data
                    }]
                });
            });         
        }

    };
};

return {
    getInstance: function () {
        return instantiated = init();
    }
};

})();


回答1:


I had a similar issue with updating charts in real time. I was able to avoid this scenario by first checking to make sure that the container exists before I would update the chart.

In your case you could do something like this to make sure that the container exists:

if($("#" + properties.id).length == 1) {
    chart = new Highcharts.Chart({
                 //code
            });
}


来源:https://stackoverflow.com/questions/12176201/race-condition-leading-to-highcharts-error-13

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!