Automatic Reload without being precise

2

I have a question! I have a voting system, which has a page that shows the live results of the vote, this page uses to show the charts and Google Charts background has an ajax code that runs every 1 second, which is always going to the file .xml search the voting data, but whenever you update with a slight wink in the graphic, and I believe that there is this wink when there are updates on the number of votes!

Can anyone help me solve this problem?

Code js:

window.setInterval(ajax, 1000);
function ajax() {
var ajax = new XMLHttpRequest();
 ajax.onreadystatechange = function(){
  if(ajax.readyState == 4 && ajax.status == 200){
  var res = ajax.responseXML;
  var xml = this;
  var votos1 = res.getElementsByTagName("votos")[0].firstChild.nodeValue;
  var votos2 = res.getElementsByTagName("votos")[1].firstChild.nodeValue;
  var votos3 = res.getElementsByTagName("votos")[2].firstChild.nodeValue;
  var votos4 = res.getElementsByTagName("votos")[3].firstChild.nodeValue;
  grafico(votos1, votos2, votos3, votos4);
  }
 }
  ajax.open("POST", "votos.xml");
  ajax.send(null);
 }

 function grafico(votos1, votos2, votos3, votos4){
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
  ['', 'Numero de Votos'],
  ['Opção 1', votos1],
  ['Opção 2', votos2],
  ['Opção 3', votos3],
  ['Opção 4', votos4]
]);
var options = {
  chart: {
    title: 'Total Votações',
    subtitle: 'Ajuda: Publico',
  },
  bars: 'vertical'
};
var chart = new google.charts.Bar(document.getElementById('grafico'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}  
}

XML structure:

<geral>
   <opcao1>
      <votos>5</votos>
      <correta>true</correta>
   </opcao1>
   <opcao2>
      <votos>10</votos>
      <correta>false</correta>
   </opcao2>
   <opcao3>
      <votos>1</votos>
      <correta>false</correta>
   </opcao3>
   <opcao4>
      <votos>20</votos>
      <correta>false</correta>
   </opcao4>
</geral>
    
asked by anonymous 25.04.2018 / 21:43

2 answers

1

You can create a simple variable to save the concatenated values and on Ajax's return check for any changes. Ex.:

var voTos;
function ajax() {...

var votosAjax = votos1.concat(votos2, votos3, votos4);
// ficará: votosAjax = "510120"

So, whenever this string is different from the voTos variable, you call the function that updates the graph and also updates the value of voTos :

if(votosAjax != voTos){
   voTos = votosAjax;
   grafico(votos1, votos2, votos3, votos4);
}
  

As stated in the other answer, it is also important to use setTimeout()   only after Ajax returns, and not% with% as it was   done.

The code looks like this:

var voTos; // para guardar os valores vindos do Ajax
function ajax() {
   var ajax = new XMLHttpRequest();
   ajax.onreadystatechange = function(){
      if(ajax.readyState == 4 && ajax.status == 200){
         var res = ajax.responseXML;
         var xml = this;
         var votos1 = res.getElementsByTagName("votos")[0].firstChild.nodeValue;
         var votos2 = res.getElementsByTagName("votos")[1].firstChild.nodeValue;
         var votos3 = res.getElementsByTagName("votos")[2].firstChild.nodeValue;
         var votos4 = res.getElementsByTagName("votos")[3].firstChild.nodeValue;

         // valores concatenados vindos do Ajax
         var votosAjax = votos1.concat(votos2, votos3, votos4);

         // verifico se é diferente para chamar a função do gráfico
         if(votosAjax != voTos){
            voTos = votosAjax; // se for diferente, atualizo a variável
            grafico(votos1, votos2, votos3, votos4);
         }

         setTimeout(ajax, 1000);
      }
   }
   ajax.open("POST", "votos.xml");
   ajax.send(null);
}

function grafico(votos1, votos2, votos3, votos4){
   google.charts.load('current', {'packages':['bar']});
   google.charts.setOnLoadCallback(drawChart);
   function drawChart() {
      var data = google.visualization.arrayToDataTable([
      ['', 'Numero de Votos'],
      ['Opção 1', votos1],
      ['Opção 2', votos2],
      ['Opção 3', votos3],
      ['Opção 4', votos4]
      ]);
      var options = {
         chart: {
            title: 'Total Votações',
            subtitle: 'Ajuda: Publico',
         },
         bars: 'vertical'
      };
      var chart = new google.charts.Bar(document.getElementById('grafico'));
      chart.draw(data, google.charts.Bar.convertOptions(options));
   }  
}

$(document).ready(function(){
   ajax(); // chama a função
});
    
26.04.2018 / 20:56
2

First a suggestion to work better with Ajax that is looped, change setInterval to setTimeout , so it will not conflict two requests at the same time, since setInterval does not wait for the request to finish what it can

On checking whether or not there were changes you will need to create variables to keep the values (like a cache) and check them on the next Ajax request, for example:

  

Note: I've indented your code to make it easier to understand

//Esta variavel servirá para manter um "cache" dos resultados
var cacheVotos = {
    'votos1': 0,
    'votos2': 0,
    'votos3': 0,
    'votos4': 0
};

function ajax() {
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (ajax.readyState == 4) {
            if (ajax.status == 200) {
                var res = ajax.responseXML;
                var xml = this;
                var votos1 = res.getElementsByTagName("votos")[0].firstChild.nodeValue;
                var votos2 = res.getElementsByTagName("votos")[1].firstChild.nodeValue;
                var votos3 = res.getElementsByTagName("votos")[2].firstChild.nodeValue;
                var votos4 = res.getElementsByTagName("votos")[3].firstChild.nodeValue;

                //Se qualquer um deles mudar então grafico() é chamado, caso contrário não
                if (
                    cacheVotos.votos1 != votos1 ||
                    cacheVotos.votos2 != votos2 ||
                    cacheVotos.votos3 != votos3 ||
                    cacheVotos.votos4 != votos4
                ) {
                    //Atualiza os valores do "cache"
                    cacheVotos.votos1 = votos1;
                    cacheVotos.votos2 = votos2;
                    cacheVotos.votos3 = votos3;
                    cacheVotos.votos4 = votos4;

                    grafico(votos1, votos2, votos3, votos4);
                }
            }

            //Isto irá chamar novamente o Ajax após a requisição ter sido concluida
            setTimeout(ajax, 1000);
        }
    }
    ajax.open("POST", "votos.xml");
    ajax.send(null);
}

//Inicia a função
ajax();

function grafico(votos1, votos2, votos3, votos4) {
    google.charts.load('current', {
        'packages': ['bar']
    });
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
        var data = google.visualization.arrayToDataTable([
            ['', 'Numero de Votos'],
            ['Opção 1', votos1],
            ['Opção 2', votos2],
            ['Opção 3', votos3],
            ['Opção 4', votos4]
        ]);
        var options = {
            chart: {
                title: 'Total Votações',
                subtitle: 'Ajuda: Publico',
            },
            bars: 'vertical'
        };
        var chart = new google.charts.Bar(document.getElementById('grafico'));
        chart.draw(data, google.charts.Bar.convertOptions(options));
    }
}
    
25.04.2018 / 21:55