Problem in AJAX query in a loop

Asked

Viewed 150 times

0

I have a view that has several pie charts using the D3 plugin. Each chart should display different data.

With PHP I do a foreach on the screen, creating the div where the chart will be displayed, each with a id specific. Then with Javascript I get all these id, and from this, in each of the div I make a request AJAX in a query, and the results I bring, assemble each graph.

The problem is that because of AJAX be an asynchronous query, constantly, the display order of the charts changes, which should not happen.

How can I fix this?

$(document).ready(function () {
		
    $(".panel-pergunta").each(function () {

        var id = $(this).attr('pergunta');
        
        $.ajax({
            method: "GET",
            url: "/relatorios/chart/" + id,
            dataType: "json",
            success: function (r) {
                //console.log(r);
                pieChartData = [];
                total = 0;

                for (var i in r.pesquisas) {
                
                    pieChartData.push({
                        "label": r.pesquisas[i].resposta,
                        "value": r.pesquisas[i].total
                    });
                    total += r.pesquisas[i].total;
                }

                if (total > 0) {
                    nv.addGraph(function () {
                        var chart = nv.models.pieChart()
                                .x(function (d) {
                                    return d.label;
                                })
                                .y(function (d) {
                                    return d.value;
                                })
                                .valueFormat(d3.format(".0f"))
                                .showLabels(true)
                                .showLegend(true)
                                .legendPosition("right")
                                .labelThreshold(0.05)
                                .labelsOutside(true)
                                .labelType("percent")
                                .donut(false)
                                .color(['#EF5350', '#FFA726', '#4DB446'])
                                .donutRatio(0.35);

                        d3.select("#chartp" + id + " svg")
                                .datum(pieChartData)
                                .transition()
                                .duration(350)
                                .call(chart);

                        d3.selectAll('.nv-label text')
                                .each(function (d, i) {
                                    d3.select(this).style('font-weight', 700)
                                })

                        var positionX = 0;
                        var positionY = 0;
                        var verticalOffset = 20;

                        d3.selectAll('#chartp' + id + ' .nv-legend .nv-series')[0].forEach(function (d) {
                            positionY += verticalOffset;
                            d3.select(d).attr('transform', 'translate(' + positionX + ',' + positionY + ')');
                        });

                        return chart;
                    });
                } else {
                    $("#chartp" + id).html("<i class='fa fa-exclamation-triangle'></i> Não há dados suficientes para montar esse gráfico.");
                }
            },
            error: function (r) {
                console.log(r.responseText);
            }
        });
    });
});

  • Can you explain how the order of the charts changes? You are using a id only with var id = $(this).attr('pergunta');?

  • In the view code I do a foreach on div class panel-pergunta. In those div put an attribute pergunta, and the value of the same I bring from PHP. So let’s say, are 13 div, each of them with question attribute, from 1 to 13. So in javascript I iterate each of these values, and in each one div I populate the chart through the results of the queries. However, depending on the speed the query runs, it may happen that the 5th query displays in the 4th div, or the 8th, display on the 7th, reversing orders randomly, with each page load.

  • If each .panel-pergunta has a unique id/attribute it doesn’t make much sense to be mixed up. The only errors I see at first glance are not using var in the statement of pieChartData = []; total = 0; This is important. Fix this and say if solved.

1 answer

0

I believe that if working with Prefects solves your problem:

var deferred = new $.Deferred();
var pipe = deferred;
$(".panel-pergunta").each(function () {
  pipe = pipe.then(function () {
    ...seu código...
  });
});
deferred.resolve();

Browser other questions tagged

You are not signed in. Login or sign up in order to post.