Произвольное количество диаграмм Google на странице с разными наборами данных и один обратный вызов

#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});
}