blob: 393871442b5e53e450d2b5bdb5bed0cfbeee0da4 [file] [log] [blame]
Matteo Scandolof0577ac2016-03-21 17:27:42 -07001/**
2 * © OpenCORD
3 *
4 * Visit http://guide.xosproject.org/devguide/addview/ for more information
5 *
6 * Created by teone on 3/21/16.
7 */
8
9(function () {
10 'use strict';
11
12 angular.module('xos.ceilometerDashboard')
Matteo Scandolo02f44d62016-09-19 17:17:58 -070013 .directive('ceilometerSamples', function(_, $stateParams, $interval){
Matteo Scandolof0577ac2016-03-21 17:27:42 -070014 return {
15 restrict: 'E',
16 scope: {},
17 bindToController: true,
18 controllerAs: 'vm',
19 templateUrl: 'templates/ceilometer-samples.tpl.html',
20 controller: function(Ceilometer) {
21
Matteo Scandolof0577ac2016-03-21 17:27:42 -070022 this.chartColors = [
23 '#286090',
24 '#F7464A',
25 '#46BFBD',
26 '#FDB45C',
27 '#97BBCD',
28 '#4D5360',
29 '#8c4f9f'
30 ];
31
32 this.chart = {
33 series: [],
34 labels: [],
35 data: []
36 }
37
38 Chart.defaults.global.colours = this.chartColors;
39
40 this.chartType = 'line';
41
Matteo Scandolo02f44d62016-09-19 17:17:58 -070042 // TODO
43 // check for name, if
44 // - broadview.pt.packet-trace-lag-resolution
45 // - broadview.pt.packet-trace-ecmp-resolution
46 // draw a pie
47
48 const pieStats = [
49 'broadview.pt.packet-trace-lag-resolution',
50 'broadview.pt.packet-trace-ecmp-resolution'
51 ];
52 let isApie = false;
53
54 let refreshInterval = 60 * 1000;
55
Matteo Scandolof0577ac2016-03-21 17:27:42 -070056 if($stateParams.name && $stateParams.tenant){
57 this.name = $stateParams.name;
Matteo Scandolo8420f622016-03-24 11:38:50 -070058 // TODO rename tenant in resource_id
Matteo Scandolo02f44d62016-09-19 17:17:58 -070059 this.tenant = $stateParams.tenant;
60
61 if(pieStats.indexOf(this.name) > -1){
62 isApie = true;
63 this.chartType = 'pie';
64 refreshInterval = 10 * 1000;
65 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -070066 }
67 else{
68 throw new Error('Missing Name and Tenant Params!');
69 }
70
71 /**
72 * Goes trough the array and format date to be used as labels
73 *
74 * @param Array data
75 * @returns Array a list of labels
76 */
77
78 this.getLabels = (data) => {
79 return data.reduce((list, item) => {
80 let date = new Date(item.timestamp);
81 list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`);
82 return list;
83 }, []);
84 };
85
86 /**
87 * Goes trough the array and return a flat array of values
88 *
89 * @param Array data
90 * @returns Array a list of values
91 */
92
93 this.getData = (data) => {
94 return data.reduce((list, item) => {
95 list.push(item.volume);
96 return list;
97 }, []);
98 }
99
100 /**
101 * Add a samples to the chart
102 *
103 * @param string resource_id
104 */
105 this.chartMeters = [];
106 this.addMeterToChart = (resource_id) => {
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700107 this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp'));
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700108 this.chart['series'].push(resource_id);
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700109 this.chart['data'].push(this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp')));
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700110 this.chartMeters.push(this.samplesList[resource_id][0]); //use the 0 as are all samples for the same resource and I need the name
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700111 _.remove(this.sampleLabels, {id: resource_id});
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700112 }
113
114 this.removeFromChart = (meter) => {
115 this.chart.data.splice(this.chart.series.indexOf(meter.resource_id), 1);
116 this.chart.series.splice(this.chart.series.indexOf(meter.resource_id), 1);
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700117 this.chartMeters.splice(_.findIndex(this.chartMeters, {resource_id: meter.resource_id}), 1);
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700118 this.sampleLabels.push({
119 id: meter.resource_id,
120 name: meter.resource_name || meter.resource_id
121 })
122 };
123
124 /**
125 * Format samples to create a list of labels and ids
126 */
127
128 this.formatSamplesLabels = (samples) => {
129
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700130 return _.uniq(samples, 'resource_id')
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700131 .reduce((labels, item) => {
132 labels.push({
133 id: item.resource_id,
134 name: item.resource_name || item.resource_id
135 });
136
137 return labels;
138 }, []);
139 }
140
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700141 /**
142 * Format data series in pie chart val
143 */
144
145 this.formatPieChartData = (samples) => {
146
147 this.chart['labels'] = samples[0].metadata['lag-members'].replace(/\[|\]|'| /g, '').split(',');
148 this.chart.options = {
149 legend: {
150 display: true
151 }
152 };
153 samples = _.groupBy(samples, i => i.metadata['dst-lag-member']);
154
155 // TODO show percentage in pie
156 Chart.defaults.global.tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>%';
157
158 let data = _.reduce(this.chart.labels, (data, item) => {
159 let length = samples[item] ? samples[item].length : 0;
160 data.push(length);
161 return data;
162 }, []);
163
164 let total = _.reduce(data, (d, t) => d + t);
165
166 let percent = _.map(data, d => Math.round((d / total) * 100));
167
168 console.log(total);
169
170 this.chart['data'] = percent;
171 };
172
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700173
174 /**
175 * Load the samples and format data
176 */
177
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700178 this.loader = true;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700179 this.showSamples = () => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700180 // Ceilometer.getSamples(this.name, this.tenant) //fetch one
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700181 let p;
182 if (isApie){
183 p = Ceilometer.getSamples(this.name, 30) //fetch all
184 }
185 else{
186 p = Ceilometer.getSamples(this.name) //fetch all
187 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700188
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700189 p.then(res => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700190
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700191 // rename things in UI
192 res.map(m => {
193 m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC');
194 m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD');
195 m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter');
196 return m;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700197 });
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700198 // end rename things in UI
199
200 // if I have to draw a pie skip the rest
201 if(isApie){
202
203 // TODO format data as pie
204 this.formatPieChartData(res);
205 return;
206 }
207
208 // setup data for visualization
209 this.samplesList = _.groupBy(res, 'resource_id');
210 this.sampleLabels = this.formatSamplesLabels(res);
211
212 // add current meter to chart
213 this.addMeterToChart(this.tenant);
214
215 })
216 .catch(err => {
217 this.error = err.data.detail;
218 })
219 .finally(() => {
220 this.loader = false;
221 });
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700222 };
223
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700224 $interval(() => {
225 this.showSamples();
226 }, refreshInterval)
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700227 this.showSamples();
228 }
229 }
230 });
231})();
232