Monday, 2 March 2015

Display Live data with Google Charts, Ajax (through JSON file), and AngularJS

The Google-developers website is the good place to start in order to know how to use of Google-charts within a HTML page :
see https://google-developers.appspot.com/chart/
The on-line JavaScript library that you will need for Google chart is http://www.google.com/jsapi

If you want to use ajax, the best way is to use jquery (the on-line JavaScript library is http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js)


To draw a pie chart (cf. https://google-developers.appspot.com/chart/interactive/docs/quick_start), here is an example of HTML/JS file :
       
<html>
    <head>
        <!--Load the AJAX API-->
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script>

    <script type='text/javascript'>

            function drawChart() {
                var json = $.ajax({
                    url: "http://localhost/angularjs/get_repartition_order_status_todaygoogle_pie.php?type=graph",
                    dataType:"json",
                    async: false
                }).responseText;
                jsondata = eval(json);
                // Create the data table.
                var data = new google.visualization.DataTable();
                data.addColumn('string', 'Topping');
                data.addColumn('number', 'Slices');
                data.addRows(jsondata);

                // Set chart options
                var options = {'title':'Order Status for today ',
                    'width':400,
                    'height':300};

                // Instantiate and draw our chart, passing in some options.
                var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
                chart.draw(data, options);
            }

            // Set a callback to run when the Google Visualization API is loaded.
            google.setOnLoadCallback(drawChart);
            // Load the Visualization API and the piechart package.
            google.load('visualization', '1.0', {'packages':['corechart']});

            // Callback that creates and populates a data table,
            // instantiates the pie chart, passes in the data and
            // draws it.
        </script>
    </head>

    <body>
        <!--Div that will hold the pie chart-->
        <div id="chart_div"></div>
    </body>
</html>

You may have noticed that I had to convert the JSON output in order to pass the data through addRows method using eval();

The format of the json data is  ([ ["label",value]....] ):
[
   ["new",2955],["processing",721],["shipped",162],[],["cancelled",109],["restocking",11]

]

Now, if you would like to introduce a Google Chart when using AngularJS,

<!DOCTYPE html>
<html>
    <script type="text/javascript" src="http://code.angularjs.org/1.1.0/angular.min.js"></script>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type='text/javascript'>
        //http://snippetrepo.com/snippets/google-charts-with-angularjs
        var app = angular.module('myApp', []);
        app.directive('chart', function() {
            return {
                restrict: 'A',
                link: function($scope, $elm, $attr) {
                    var json = $.ajax({
                        url: "http://localhost/angularjs/get_repartition_order_status_todaygoogle_pie.php?type=graph",
                        dataType:"json",
                        async: false
                    }).responseText;
                    jsonData = eval(json);
                    // Create the data table.
                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'Topping');
                    data.addColumn('number', 'Slices');
                   
                    data.addRows(jsonData);
                    // Set chart options
                    var options = {'title':'Order Status for today ',
                        'width':400,
                        'height':300};

                    // Instantiate and draw our chart, passing in some options.
                    var chart = new google.visualization.PieChart($elm[0]);
                    chart.draw(data, options);
                }
            }
        });

        google.setOnLoadCallback(function() {
            angular.bootstrap(document.body, ['myApp']);
        });
        google.load('visualization', '1', {packages: ['corechart']});

    </script>
    <body> 
        <!--Div that will hold the pie chart-->
            <div chart></div>

    </body>

</html>

I've shown in "aqua" the few lines that need to be changed when integrating the pie chart within AngularJS: in both cases, the output will look like the above graph.

You can also add 3D effects changing the options value, doing so:
 
var options = {'title':'Order Status for today ',
                        'width':400,
                        'height':300,'is3D': true};


Nota : You can also change the location of the legend (by adding : 'legend':'left')










Another way is presented at http://www.frangular.com/2013/01/google-chart-tools-avec-angularjs.html (that seems more complex at least right now!!) :

Here below, you will fact respectively, the HTML, and JS files giving the same output than above (with 3D option graph):

<!DOCTYPE html>
<html ng-app="angularjs-starter">

    <head lang="en">
        <meta charset="utf-8">
        <title>GoogleCharts in AngularJS</title>

    </head>

    <body ng-controller="MainCtrl">        

        <div style="float: left; width: 600px" ng:model="data"  qn:columns="[{type:'string', name: 'Topping'}, {type:'number', name: 'Slices'}]" qn:piechart="{legend : {alignment: 'center'}, chartArea: {height: 400},backgroundColor: '#F7F7F7'}"></div>
           
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>    
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script src="pieGCharts.js"></script>
        <script type="text/javascript" src="https://www.google.com/jsapi"> </script>
        <script type="text/javascript">
            google.load('visualization', '1.0', { 'packages': ['corechart'] });
        </script>
    </body>

</html>


with pieGCharts.js :
var app = angular.module('angularjs-starter', [
    'charts.pie'
]); 

app.controller('MainCtrl', function($scope) {
    var json = $.ajax({
        url: "http://localhost/angularjs/get_repartition_order_status_todaygoogle_pie.php?type=graph",
        dataType:"json",
        async: false
    }).responseText;
    $scope.data = eval(json);
});

angular.module('charts.pie', [
])
.directive('qnPiechart', [
    function() {
        return {
            require: '?ngModel',
            link: function(scope, element, attr, controller) {
                var settings = {
                    is3D: true
                };

                var getOptions = function() {
                    return angular.extend({ }, settings, scope.$eval(attr.qnPiechart));
                };

                // creates instance of datatable and adds columns from settings
                var getDataTable = function() {
                    var columns = scope.$eval(attr.qnColumns);
                    var data = new google.visualization.DataTable();
                    angular.forEach(columns, function(column) {
                        data.addColumn(column.type, column.name);
                    });
                    return data;
                };

                var init = function() {
                    var options = getOptions();
                    if (controller) {

                        var drawChart = function() {
                            var data = getDataTable();
                            // set model
                            data.addRows(controller.$viewValue);

                            // Instantiate and draw our chart, passing in some options.
                            var pie = new google.visualization.PieChart(element[0]);
                            pie.draw(data, options);
                        };

                        controller.$render = function() {
                            drawChart();
                        };
                    }

                    if (controller) {
                        // Force a render to override
                        controller.$render();
                    }
                };

                // Watch for changes to the directives options
                scope.$watch(getOptions, init, true);
                scope.$watch(getDataTable, init, true);
            }
        };
    }

]);