#javascript #charts #promise #google-visualization
#javascript #Диаграммы #обещание #google-визуализация
Вопрос:
Я пытаюсь создать произвольное количество диаграмм визуализации Google с разными источниками данных. Поскольку существует произвольное число, я перебираю элементы по имени класса, запрашиваю данные для каждого, а затем рисую диаграмму в запросе.отправить обратный вызов. Этот обратный вызов не принимает никаких параметров, поэтому у меня нет способа передать элемент, для которого должна быть нарисована диаграмма. Итак, я попытался сделать это с глобальными переменными; однако цикл повторяется, перезаписывая переменные до возврата запроса. Как правильно это сделать?
let cwraggbgraphs = [];
let cwraggbgraph = "";
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(initializeData);
function initializeData() {
cwraggbgraphs = document.getElementsByClassName("cwraggbp");
// loop through each of the divs by class name
for (var i = 0; i < cwraggbgraphs.length; i ) {
// set the global variable to the element we need to target
cwraggbgraph = cwraggbgraphs.item(i);
var opts = {sendMethod: 'auto',
csvColumns: ['string', 'number', 'number'],
csvHasHeader: true};
// the URL from which to grab the data is set in a data attribute on the element
var query = new google.visualization.Query(
cwraggbgraph.dataset.cwraggbpSrc,
opts);
query.send(handleQueryResponse);
}
}
// when we get a response, draw the chart
function handleQueryResponse(response) {
console.log("Got response ", response);
// this works, I get all of the responses back
console.log("Using element ", cwraggbgraph);
// but by the time the 1st response returns, the for loop has completed,
// so this is always the last element :(
if (response.isError()) {
alert('Error in query: '
response.getMessage()
' '
response.getDetailedMessage());
return;
}
let data = response.getDataTable();
let chart = new google.visualization.PieChart(cwraggbgraph);
chart.draw(data, {width: 400, height: 240, is3D: true});
}
Изначально я пытался сделать это, передав элемент обратному вызову, но он принимает только один параметр. Это то, что заставило меня попытаться сделать это с глобальными переменными, но затем я столкнулся с проблемой синхронизации. Есть идеи, как это сделать?
Ответ №1:
вы можете использовать «промежуточную» анонимную функцию…
query.send(function (response) {
handleQueryResponse(response, cwraggbgraph);
});
смотрите следующий фрагмент…
google.charts.setOnLoadCallback(initializeData);
function initializeData() {
var cwraggbgraphs = document.getElementsByClassName("cwraggbp");
// loop through each of the divs by class name
for (var i = 0; i < cwraggbgraphs.length; i ) {
// set the global variable to the element we need to target
var cwraggbgraph = cwraggbgraphs.item(i);
var opts = {sendMethod: 'auto',
csvColumns: ['string', 'number', 'number'],
csvHasHeader: true};
// the URL from which to grab the data is set in a data attribute on the element
var query = new google.visualization.Query(
cwraggbgraph.dataset.cwraggbpSrc,
opts);
query.send(function (response) {
handleQueryResponse(response, cwraggbgraph);
});
}
}
// when we get a response, draw the chart
function handleQueryResponse(response, cwraggbgraph) {
if (response.isError()) {
alert('Error in query: '
response.getMessage()
' '
response.getDetailedMessage());
return;
}
let data = response.getDataTable();
let chart = new google.visualization.PieChart(cwraggbgraph);
chart.draw(data, {width: 400, height: 240, is3D: true});
}