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