Состояние гонки, приводящее к ошибке Highcharts #13
У меня есть несколько вкладок, которые генерируются динамически. При нажатии на любую из этих вкладок одновременно загружаются несколько диаграмм (три или четыре), таких как круговая диаграмма, столбец или линейная диаграмма. Я добавляю эти диаграммы в динамически генерируемые HTML-элементы. Все работает хорошо, если мне нужно было щелкнуть вкладку и ждать загрузки всех графиков. Проблема возникает, когда я продолжаю нажимать на вкладки одна за другой и не жду, пока все диаграммы загрузятся. я получаю ошибку javascript внутри файла highcharts.js, который регистрирует ошибку Highcharts #13. Насколько я знаю, я делаю правильные проверки документов и затем загружаю свои диаграммы в div. В чем проблема? Происходит ли состояние гонки или из-за асинхронного выполнения моего кода возникают проблемы? Вот код:
//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];
}
// Затем я вызываю 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();
}
// Окончательно Build вызывается после того, как для него был создан экземпляр, например: Столбчатая диаграмма будет (Созданы отдельные js-файлы для каждой диаграммы)
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 ответ
У меня была похожая проблема с обновлением графиков в реальном времени. Мне удалось избежать этого сценария, сначала проверив, чтобы убедиться, что контейнер существует, прежде чем я обновлю график.
В вашем случае вы можете сделать что-то вроде этого, чтобы убедиться, что контейнер существует:
if($("#" + properties.id).length == 1) {
chart = new Highcharts.Chart({
//code
});
}