blob: 73aba056f6f4ab5916a11a4f900a4e9bdb91c0a0 [file] [log] [blame]
Matteo Scandolo686547a2017-08-08 13:05:25 -07001
2/*
3 * Copyright 2017-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
Matteo Scandoloa5d03d52016-07-21 11:35:46 -070019/**
20 * © OpenCORD
21 *
22 * Visit http://guide.xosproject.org/devguide/addview/ for more information
23 *
24 * Created by teone on 3/24/16.
25 */
26
27(function () {
28 'use strict';
29
30 angular.module('xos.uiComponents')
31 /**
32 * @ngdoc directive
33 * @name xos.uiComponents.directive:xosSmartPie
34 * @restrict E
35 * @description The xos-table directive
36 * @param {Object} config The configuration for the component,
37 * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
38 * and a field name that is used to group the data.
39 * ```
40 * {
41 resource: 'Users',
42 groupBy: 'fieldName',
43 classes: 'my-custom-class',
44 labelFormatter: (labels) => {
45 // here you can format your label,
46 // you should return an array with the same order
47 return labels;
48 }
49 }
50 * ```
51 * @scope
52 * @example
53
54 Displaying Local data
55
56 <example module="sampleSmartPieLocal">
57 <file name="index.html">
58 <div ng-controller="SampleCtrlLocal as vm">
59 <xos-smart-pie config="vm.configLocal"></xos-smart-pie>
60 </div>
61 </file>
62 <file name="script.js">
63 angular.module('sampleSmartPieLocal', ['xos.uiComponents'])
64 .factory('_', function($window){
65 return $window._;
66 })
67 .controller('SampleCtrlLocal', function($timeout){
68
69 this.datas = [
70 {id: 1, first_name: 'Jon', last_name: 'aaa', category: 2},
71 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 1},
72 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2}
73 ];
74
75 this.configLocal = {
76 data: [],
77 groupBy: 'category',
78 classes: 'local',
79 labelFormatter: (labels) => {
80 return labels.map(l => l === '1' ? 'North' : 'Dragon');
81 }
82 };
83
84 $timeout(() => {
85 // this need to be triggered in this way just because of ngDoc,
86 // otherwise you can assign data directly in the config
87 this.configLocal.data = this.datas;
88 }, 1)
89 });
90 </file>
91 </example>
92
93 Fetching data from API
94
95 <example module="sampleSmartPieResource">
96 <file name="index.html">
97 <div ng-controller="SampleCtrl as vm">
98 <xos-smart-pie config="vm.config"></xos-smart-pie>
99 </div>
100 </file>
101 <file name="script.js">
102 angular.module('sampleSmartPieResource', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
103 .controller('SampleCtrl', function(){
104 this.config = {
105 resource: 'SampleResource',
106 groupBy: 'category',
107 classes: 'resource',
108 labelFormatter: (labels) => {
109 return labels.map(l => l === '1' ? 'North' : 'Dragon');
110 }
111 };
112 });
113 </file>
114 <file name="backendPoll.js">
115 angular.module('sampleSmartPieResource')
116 .run(function($httpBackend, _){
117 let datas = [
118 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
119 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
120 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1}
121 ];
122
123 $httpBackend.whenGET('/test').respond(200, datas)
124 })
125 .factory('_', function($window){
126 return $window._;
127 })
128 .service('SampleResource', function($resource){
129 return $resource('/test/:id', {id: '@id'});
130 })
131 </file>
132 </example>
133
134 Polling data from API
135
136 <example module="sampleSmartPiePoll">
137 <file name="index.html">
138 <div ng-controller="SampleCtrl as vm">
139 <xos-smart-pie config="vm.config"></xos-smart-pie>
140 </div>
141 </file>
142 <file name="script.js">
143 angular.module('sampleSmartPiePoll', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
144 .controller('SampleCtrl', function(){
145 this.config = {
146 resource: 'SampleResource',
147 groupBy: 'category',
148 poll: 2,
149 labelFormatter: (labels) => {
150 return labels.map(l => l === '1' ? 'Active' : 'Banned');
151 }
152 };
153 });
154 </file>
155 <file name="backend.js">
156 angular.module('sampleSmartPiePoll')
157 .run(function($httpBackend, _){
158 let mock = [
159 [
160 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
161 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
162 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
163 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 1}
164 ],
165
166 [
167 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
168 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
169 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2},
170 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
171 ],
172
173 [
174 {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
175 {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
176 {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
177 {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
178 ]
179 ];
180 $httpBackend.whenGET('/test').respond(function(method, url, data, headers, params) {
181 return [200, mock[Math.round(Math.random() * 3)]];
182 });
183 })
184 .factory('_', function($window){
185 return $window._;
186 })
187 .service('SampleResource', function($resource){
188 return $resource('/test/:id', {id: '@id'});
189 })
190 </file>
191 </example>
192 */
Arpit Agarwal34b63832016-08-08 11:59:45 -0700193 .component('xosSmartPie', {
194 restrict: 'E',
195 bindings: {
196 config: '='
197 },
198 template: `
199 <canvas
200 class="chart chart-pie {{vm.config.classes}}"
201 chart-data="vm.data" chart-labels="vm.labels"
202 chart-legend="{{vm.config.legend}}">
203 </canvas>
204 `,
205 bindToController: true,
206 controllerAs: 'vm',
207 controller: function($injector, $interval, $scope, $timeout, _){
Matteo Scandoloa5d03d52016-07-21 11:35:46 -0700208
Arpit Agarwal34b63832016-08-08 11:59:45 -0700209 if(!this.config.resource && !this.config.data){
210 throw new Error('[xosSmartPie] Please provide a resource or an array of data in the configuration');
Matteo Scandoloa5d03d52016-07-21 11:35:46 -0700211 }
Arpit Agarwal34b63832016-08-08 11:59:45 -0700212
213 const groupData = (data) => _.groupBy(data, this.config.groupBy);
214 const formatData = (data) => _.reduce(Object.keys(data), (list, group) => list.concat(data[group].length), []);
215 const formatLabels = (data) => angular.isFunction(this.config.labelFormatter) ? this.config.labelFormatter(Object.keys(data)) : Object.keys(data);
216
217 const prepareData = (data) => {
218 // group data
219 let grouped = groupData(data);
220 this.data = formatData(grouped);
221 // create labels
222 this.labels = formatLabels(grouped);
223 }
224
225 if(this.config.resource){
226
227 this.Resource = $injector.get(this.config.resource);
228 const getData = () => {
229 this.Resource.query().$promise
230 .then((res) => {
231
232 if(!res[0]){
233 return;
234 }
235
236 prepareData(res);
237 });
238 }
239
240 getData();
241
242 if(this.config.poll){
243 $interval(() => {getData()}, this.config.poll * 1000)
244 }
245 }
246 else {
247 $scope.$watch(() => this.config.data, (data) => {
248 if(data){
249 prepareData(this.config.data);
250 }
251 }, true);
252 }
253
254 $scope.$on('create', function (event, chart) {
255 console.log(`create: ${chart.id}`);
256 });
257
258 $scope.$on('destroy', function (event, chart) {
259 console.log(`destroy: ${chart.id}`);
260 });
261
262 }
Matteo Scandoloa5d03d52016-07-21 11:35:46 -0700263 });
264})();