| |
| /* |
| * Copyright 2017-present Open Networking Foundation |
| |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| /** |
| * © OpenCORD |
| * |
| * Visit http://guide.xosproject.org/devguide/addview/ for more information |
| * |
| * Created by teone on 3/21/16. |
| */ |
| |
| (function () { |
| 'use strict'; |
| |
| angular.module('xos.ceilometerDashboard') |
| .directive('ceilometerSamples', function(_, $stateParams, $interval){ |
| return { |
| restrict: 'E', |
| scope: {}, |
| bindToController: true, |
| controllerAs: 'vm', |
| templateUrl: 'templates/ceilometer-samples.tpl.html', |
| controller: function(Ceilometer) { |
| |
| this.chartColors = [ |
| '#286090', |
| '#F7464A', |
| '#46BFBD', |
| '#FDB45C', |
| '#97BBCD', |
| '#4D5360', |
| '#8c4f9f' |
| ]; |
| |
| this.chart = { |
| series: [], |
| labels: [], |
| data: [] |
| } |
| |
| Chart.defaults.global.colours = this.chartColors; |
| |
| this.chartType = 'line'; |
| |
| // TODO |
| // check for name, if |
| // - broadview.pt.packet-trace-lag-resolution |
| // - broadview.pt.packet-trace-ecmp-resolution |
| // draw a pie |
| |
| const pieStats = [ |
| 'broadview.pt.packet-trace-lag-resolution', |
| 'broadview.pt.packet-trace-ecmp-resolution' |
| ]; |
| let isApie = false; |
| |
| let refreshInterval = 60 * 1000; |
| |
| if($stateParams.name && $stateParams.tenant){ |
| this.name = $stateParams.name; |
| // TODO rename tenant in resource_id |
| this.tenant = $stateParams.tenant; |
| |
| if(pieStats.indexOf(this.name) > -1){ |
| isApie = true; |
| this.chartType = 'pie'; |
| refreshInterval = 10 * 1000; |
| } |
| } |
| else{ |
| throw new Error('Missing Name and Tenant Params!'); |
| } |
| |
| /** |
| * Goes trough the array and format date to be used as labels |
| * |
| * @param Array data |
| * @returns Array a list of labels |
| */ |
| |
| this.getLabels = (data) => { |
| return data.reduce((list, item) => { |
| let date = new Date(item.timestamp); |
| list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`); |
| return list; |
| }, []); |
| }; |
| |
| /** |
| * Goes trough the array and return a flat array of values |
| * |
| * @param Array data |
| * @returns Array a list of values |
| */ |
| |
| this.getData = (data) => { |
| return data.reduce((list, item) => { |
| list.push(item.volume); |
| return list; |
| }, []); |
| } |
| |
| /** |
| * Add a samples to the chart |
| * |
| * @param string resource_id |
| */ |
| this.chartMeters = []; |
| this.addMeterToChart = (resource_id) => { |
| const resourcePos = _.findIndex(this.chartMeters, m => m.resource_id === resource_id); |
| // if this meter is not yet rendered |
| if (resourcePos < 0) { |
| this.chart['data'].push(this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp'))); |
| this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp')); |
| this.chart['series'].push(resource_id); |
| this.chartMeters.push(this.samplesList[resource_id][0]); //use the 0 as are all samples for the same resource and I need the name |
| _.remove(this.sampleLabels, {id: resource_id}); |
| } |
| else { |
| this.chart['data'][resourcePos] = this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp')); |
| this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp')); |
| this.chart['series'][resourcePos] = resource_id; |
| } |
| } |
| |
| this.removeFromChart = (meter) => { |
| this.chart.data.splice(this.chart.series.indexOf(meter.resource_id), 1); |
| this.chart.series.splice(this.chart.series.indexOf(meter.resource_id), 1); |
| this.chartMeters.splice(_.findIndex(this.chartMeters, {resource_id: meter.resource_id}), 1); |
| this.sampleLabels.push({ |
| id: meter.resource_id, |
| name: meter.resource_name || meter.resource_id |
| }) |
| }; |
| |
| /** |
| * Format samples to create a list of labels and ids |
| */ |
| |
| this.formatSamplesLabels = (samples) => { |
| |
| return _.uniq(samples, 'resource_id') |
| .reduce((labels, item) => { |
| labels.push({ |
| id: item.resource_id, |
| name: item.resource_name || item.resource_id |
| }); |
| |
| return labels; |
| }, []); |
| } |
| |
| /** |
| * Format data series in pie chart val |
| */ |
| |
| this.formatPieChartData = (samples) => { |
| |
| this.chart['labels'] = samples[0].metadata['lag-members'].replace(/\[|\]|'| /g, '').split(','); |
| this.chart.options = { |
| legend: { |
| display: true |
| } |
| }; |
| samples = _.groupBy(samples, i => i.metadata['dst-lag-member']); |
| |
| // TODO show percentage in pie |
| Chart.defaults.global.tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>%'; |
| |
| let data = _.reduce(this.chart.labels, (data, item) => { |
| let length = samples[item] ? samples[item].length : 0; |
| data.push(length); |
| return data; |
| }, []); |
| |
| let total = _.reduce(data, (d, t) => d + t); |
| |
| let percent = _.map(data, d => Math.round((d / total) * 100)); |
| |
| console.log(total); |
| |
| this.chart['data'] = percent; |
| }; |
| |
| |
| /** |
| * Load the samples and format data |
| */ |
| |
| this.loader = true; |
| this.showSamples = () => { |
| // Ceilometer.getSamples(this.name, this.tenant) //fetch one |
| let p; |
| if (isApie){ |
| p = Ceilometer.getSamples(this.name, 30) //fetch all |
| } |
| else{ |
| p = Ceilometer.getSamples(this.name) //fetch all |
| } |
| |
| p.then(res => { |
| |
| // rename things in UI |
| res.map(m => { |
| m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC'); |
| m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD'); |
| m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter'); |
| return m; |
| }); |
| // end rename things in UI |
| |
| // if I have to draw a pie skip the rest |
| if(isApie){ |
| |
| // TODO format data as pie |
| this.formatPieChartData(res); |
| return; |
| } |
| |
| // setup data for visualization |
| this.samplesList = _.groupBy(res, 'resource_id'); |
| this.sampleLabels = this.formatSamplesLabels(res); |
| |
| // add current meter to chart |
| this.addMeterToChart(this.tenant); |
| |
| }) |
| .catch(err => { |
| this.error = err.data.detail; |
| }) |
| .finally(() => { |
| this.loader = false; |
| }); |
| }; |
| |
| $interval(() => { |
| this.showSamples(); |
| }, refreshInterval) |
| this.showSamples(); |
| } |
| } |
| }); |
| })(); |
| |