Release notes for R1/Amsterdam/1.3.0
[portal.git] / docs / tutorials / portal-sdk / google-charts.rst
1 Google Charts
2 =============
3  
4 Now that we've established our database connection and can request and retrieve data from our tables, we can focus on our web application.
5
6 Installing
7 ----------
8
9 First, we'll need to grab the Angular-ized Google Charts. Do this:
10
11 ::
12
13   cd sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage  
14   wget https://raw.githubusercontent.com/angular-google-chart/angular-google-chart/development/ng-google-chart.min.js
15
16 .. note:: The "min" in the file name indicates that any and all unnecessary spaces, newlines, etc. have been removed from the file to "min"imize the size.
17
18 Now, add a reference to Google Charts in your :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/myfirstpage.html` file:
19
20 ::
21
22   .
23   .
24   .
25   <!-- Page specific items -->
26   <script src="app/fusion/scripts/myapp/myfirstpage/controller.js"></script>
27   <script src="app/fusion/scripts/myapp/myfirstpage/route.js"></script>
28   <script src="app/fusion/scripts/myapp/myfirstpage/data-service.js"></script>
29   <!-- Google Charts -->
30   <script src="app/fusion/scripts/myapp/myfirstpage/ng-google-chart.min.js"></script> 
31   .
32   .
33   .
34
35 Now, make sure we tell our app that we'll need to use this dependency by adding a reference to it in :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/app.js`:
36
37 .. code-block:: javascript
38
39   var appDS2=angular.module("abs", ['ngRoute', 'ngMessages','modalServices', 'ngCookies', 'b2b.att','gridster','ui.bootstrap','ui.bootstrap.modal','googlechart']);
40
41 Configuring our chart
42 ---------------------
43
44 Change the initialization of the :code:`$scope.state` variable by using the following inside the init function in your :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/controller.js` file:
45
46 .. code-block:: javascript
47
48   $scope.state = {
49     // Holds a message string for testing
50     message: "Hello from myFirstPageController",
51     // Holds the desired direction of the chart
52     direction: "download",
53     chart: {
54       type: "LineChart",
55       data: {
56         cols: [{id: "dt", label: "Date", type: "date"},
57                {id: "c1", label: "Bandwidth", type: "number"},
58                {type: "string", role: "tooltip"}],
59         rows:[] // These change for every chart
60       },
61       options: {
62         title: "",
63         hAxis: {title: "Date", format: "MM/dd/yyyy"},
64         vAxis: {title: "Bandwidth (Mbps)", minValue: 0},
65         colors: ['blue'],
66         defaultColors: ['blue'],
67         legend: {position: "top", maxLines: 2},
68         isStacked: false,
69         pointSize: 2
70       }
71     }
72   };
73
74 The configuration options are self-explanatory. Experiment with them to get a better idea of what's possible.
75
76 Populating our chart
77 --------------------
78
79 Add the following function to your :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/controller.js` file:
80
81 .. code-block:: javascript
82
83   $scope.getChartData = function(direction) {
84     dataService.getChartData(encodeURI(direction)).then(function(rv) {
85       var arr = JSON.parse(angular.toJson(rv));
86       
87       // Clear out our rows
88       $scope.state.chart.data.rows = [];
89
90       for (var i=0; i<arr.length; i++) {
91         var t = arr[i].data_date.split(/[-]/);
92         var d = new Date(t[0], t[1]-1, t[2], 0, 0, 0);
93         var row = {};
94   
95         row.c = [{v: d},
96                  {v: arr[i].speedmbps, f: "speed"},
97                  {v: arr[i].speedmbps + " Mbps"}];
98   
99         $scope.state.chart.options.title = "Avg Bandwith in Mbps (" + direction + ")"
100         $scope.state.chart.data.rows.push(row);
101       }
102     });
103    }
104
105 When our call to :code:`getChartData` returns (and only then) do we populate the rows of our Google Chart. Each row in a Google Chart, as defined in our :code:`init` function, consists of a date, speed, and finally a special annotation called a "tooltip" that pops up a small window with some text whenever the user hovers over a data point. You can also use these special annotations to change the style of the point being displayed. See the `Google Charts`_ documentation for more info.
106
107 One subtle but important piece of the code above is that we wrap :code:`direction` in :code:`encodeURI`. This ensures that the arguments passed in the HTTP request are acceptable and mean what you think they mean when they are caught and decoded in your Spring controller. That framework will automatically handle the decoding.
108
109 Now, add a call to :code:`getChartData` in your :code:`init` function, just before the closing curly bracket:
110
111 .. code-block:: javascript
112
113   $scope.getChartData("download");
114
115 Updating the template
116 ---------------------
117
118 Finally, we'll need to add a placeholder for the chart in :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/template.html`. Here's what it looks like:
119
120 .. code-block:: html
121
122   <div id="page-content" class="content"  style="padding: 25px;">
123     <p>{{state.message}}</p>
124     <div class="md-media-lg" align="center" google-chart chart="state.chart" style="height: 400px;"></div>
125   </div>
126
127 Recompile, install, and try it out.
128
129 .. _Google Charts: https://developers.google.com/chart/interactive/docs/points