Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Charts - Gauge Graph animation not working

I'm trying to create some GAUGE graphs with Google Graphs. My goal is to load the data from a php page and have an auto refresh. I was able to do that, but when the data is refreshed, the Gauge lines are not animated, but instead they are redrawn from new. I would like to see the cool animation like this: https://jsfiddle.net/api/post/library/pure/. Actually I'm loading the data from a static file, then I'll create the data from a MySQL database (tested and worked). Here my code:

temperature.php

<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">        </script>
<script type="text/javascript">
    google.charts.load('current', {'packages':['gauge']});
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {

        var jsonData = $.ajax({
        url: "http://URL/fetch_data3.php?type=gauge",
        dataType:"json",
        async: false
    }).responseText;


    var data = new google.visualization.DataTable(jsonData);

    var options = {
        width: 600, height: 300,
        redFrom: 35, redTo: 50,
        yellowFrom: 24, yellowTo: 35,
        greenFrom: 18, greenTo: 24,
        majorTicks : ['-10', '0', '10','20','30','40','50'], minorTicks: 10,
        animation:{
        duration: 1000,
        easing: 'inAndOut',
        },
        max: 50, min: -10
        };

        var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

    chart.draw(data, options);
    clearChart();

}

setInterval(function() {
    drawChart();
}, 5000);

</script>

</head>
<body>
<div id="chart_div" style="width: 500px; height: 400px;"></div>
</body>
</html>

and here the fetch_data3.php

<?php
if ($_REQUEST["type"] == "gauge") {
    $sec = date('s');
if ($sec % 2 == 0) {
    $string = file_get_contents("sampleData.json");
} else {
    $string = file_get_contents("sampleData2.json");
}
echo $string;
}
?>

sampleData.json:

{
  "cols": [
        {"id":"","label":"Label","pattern":"","type":"string"},
        {"id":"","label":"Value","pattern":"","type":"number"}
      ],
  "rows": [
        {"c":[{"v":"Esterno","f":null},{"v":0,"f":null}]},
        {"c":[{"v":"Soggiorno","f":null},{"v":0,"f":null}]},
        {"c":[{"v":"Stanza","f":null},{"v":0,"f":null}]}
      ]
}

sampleData2.json:

{
  "cols": [
        {"id":"","label":"Label","pattern":"","type":"string"},
        {"id":"","label":"Value","pattern":"","type":"number"}
      ],
  "rows": [
        {"c":[{"v":"Esterno","f":null},{"v":10,"f":null}]},
        {"c":[{"v":"Soggiorno","f":null},{"v":40,"f":null}]},
        {"c":[{"v":"Stanza","f":null},{"v":20,"f":null}]}
      ]
}

The graph loads randomly sampleData2.json or sampleData.json but there is no anomation on the graph.

What's wrong?

Thanks!

Simon

like image 356
Simon Avatar asked Oct 18 '22 03:10

Simon


1 Answers

according to the supported modifications for a Gauge chart,
animation only occurs when a value in the data changes

since the chart doesn't animate on startup,
draw the chart initially with the values set to the min value,
or the value at which the animation should begin

then use a one time 'ready' event listener to draw the chart with the real data
this will cause the chart to animate

see following working snippet...

google.charts.load('current', {
  callback: function () {
    drawChart();

    setInterval(function() {
      drawChart();
    }, 5000);

    function drawChart() {
      var initData = {
        "cols": [
          {"id":"","label":"Label","pattern":"","type":"string"},
          {"id":"","label":"Value","pattern":"","type":"number"}
        ],
        "rows": [
          {"c":[{"v":"Esterno","f":null},{"v":-10,"f":null}]},
          {"c":[{"v":"Soggiorno","f":null},{"v":-10,"f":null}]},
          {"c":[{"v":"Stanza","f":null},{"v":-10,"f":null}]}
        ]
      };

      var data = new google.visualization.DataTable(initData);

      var options = {
        width: 600, height: 300,
        redFrom: 35, redTo: 50,
        yellowFrom: 24, yellowTo: 35,
        greenFrom: 18, greenTo: 24,
        majorTicks : ['-10', '0', '10','20','30','40','50'], minorTicks: 10,
        animation:{
          duration: 1000,
          easing: 'inAndOut'
        },
        max: 50, min: -10
      };

      var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

      google.visualization.events.addOneTimeListener(chart, 'ready', function () {
        var jsonData = {
          "cols": [
            {"id":"","label":"Label","pattern":"","type":"string"},
            {"id":"","label":"Value","pattern":"","type":"number"}
          ],
          "rows": [
            {"c":[{"v":"Esterno","f":null},{"v":10,"f":null}]},
            {"c":[{"v":"Soggiorno","f":null},{"v":40,"f":null}]},
            {"c":[{"v":"Stanza","f":null},{"v":20,"f":null}]}
          ]
        };

        var data = new google.visualization.DataTable(jsonData);
        chart.draw(data, options);
      });

      chart.draw(data, options);
    }
  },
  packages:['gauge']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

as mentioned, the above charts will animate...

from the default values set -- to the real data received

in order to get the chart to animate...

from the previous real data -- to the new data received

you would need to save a reference to the chart
instead of creating a new chart, everytime it is drawn

also, highly recommend not using async: false on the $.ajax call
use the success handler instead

recommend this setup, which will animate on the initial draw using default values
then animate from the previous data, to the new data on each interval

google.charts.load('current', {
  callback: function () {
    // save reference to chart
    var chart = null;

    drawChart();

    setInterval(function() {
      drawChart();
    }, 5000);

    function drawChart() {
      $.ajax({
        url: 'http://URL/fetch_data3.php?type=gauge',
        dataType: 'json',
        success: function (jsonData) {
          var options = {
            width: 600, height: 300,
            redFrom: 35, redTo: 50,
            yellowFrom: 24, yellowTo: 35,
            greenFrom: 18, greenTo: 24,
            majorTicks : ['-10', '0', '10','20','30','40','50'], minorTicks: 10,
            animation:{
              duration: 1000,
              easing: 'inAndOut'
            },
            max: 50, min: -10
          };

          var data;
          if (chart === null) {
            chart = new google.visualization.Gauge(document.getElementById('chart_div'));

            // data with min values
            data = new google.visualization.DataTable({
              "cols": [
                {"id":"","label":"Label","pattern":"","type":"string"},
                {"id":"","label":"Value","pattern":"","type":"number"}
              ],
              "rows": [
                {"c":[{"v":"Esterno","f":null},{"v":-10,"f":null}]},
                {"c":[{"v":"Soggiorno","f":null},{"v":-10,"f":null}]},
                {"c":[{"v":"Stanza","f":null},{"v":-10,"f":null}]}
              ]
            });

            google.visualization.events.addOneTimeListener(chart, 'ready', function () {
              data = new google.visualization.DataTable(jsonData);
              chart.draw(data, options);
            });
          } else {
            data = new google.visualization.DataTable(jsonData);
          }

          chart.draw(data, options);
        }
      });
    }
  },
  packages:['gauge']
});
like image 123
WhiteHat Avatar answered Oct 20 '22 22:10

WhiteHat