Added piechart to ceilometer

Change-Id: Ifd48eb528859b0d1d8bb26a029fe4c27090e82cd
diff --git a/views/ngXosViews/ceilometerDashboard/mock/config.json b/views/ngXosViews/ceilometerDashboard/mock/config.json
new file mode 100644
index 0000000..3d64838
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/config.json
@@ -0,0 +1,19 @@
+{
+  "endpoints": [
+    {
+      "url": "xos-slice-service-mapping",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    },
+    {
+      "url": "meters",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    },
+    {
+      "url": "metersamples",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/meters.json b/views/ngXosViews/ceilometerDashboard/mock/data/meters.json
new file mode 100644
index 0000000..9a6451b
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/meters.json
@@ -0,0 +1,26 @@
+[
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.bst.egress-uc-queue",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  },
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.pt.packet-trace-lag-resolution",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  },
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.pt.packet-trace-ecmp-resolution",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json b/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json
new file mode 100644
index 0000000..4cb99eb
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json
@@ -0,0 +1,120 @@
+[
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:53:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 1111.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+   },
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:54:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 1345.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+   },
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:55:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 945.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+    },
+
+
+
+
+
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/1"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/1"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/2"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/3"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/4"
+      }
+    }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json b/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json
new file mode 100644
index 0000000..5e6ae23
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json
@@ -0,0 +1,11 @@
+[
+   {
+      "service":"service-a",
+      "slices":[
+         {
+            "project_id":"id-a-1",
+            "slice":"slice-a-1"
+         }
+      ]
+   }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/package.json b/views/ngXosViews/ceilometerDashboard/package.json
index 1f85623..a2fc0da 100644
--- a/views/ngXosViews/ceilometerDashboard/package.json
+++ b/views/ngXosViews/ceilometerDashboard/package.json
@@ -10,7 +10,8 @@
     "build": "gulp",
     "test": "karma start",
     "test:ci": "karma start --single-run",
-    "lint": "eslint src/js/"
+    "lint": "eslint src/js/",
+    "mock": "easy-mocker -d mock/data -c mock/config.json"
   },
   "keywords": [
     "XOS",
@@ -27,7 +28,7 @@
     "css-mqpacker": "^4.0.0",
     "csswring": "^4.2.1",
     "del": "^2.0.2",
-    "easy-mocker": "^1.2.0",
+    "easy-mocker": "^1.3.1",
     "eslint": "^1.8.0",
     "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
     "gulp": "^3.9.0",
diff --git a/views/ngXosViews/ceilometerDashboard/src/index.html b/views/ngXosViews/ceilometerDashboard/src/index.html
index 40bc603..6360fea 100644
--- a/views/ngXosViews/ceilometerDashboard/src/index.html
+++ b/views/ngXosViews/ceilometerDashboard/src/index.html
@@ -18,6 +18,8 @@
 <!-- bower:js -->
 <script src="vendor/jquery/dist/jquery.js"></script>
 <script src="vendor/angular/angular.js"></script>
+<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
+<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
 <script src="vendor/angular-mocks/angular-mocks.js"></script>
 <script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
 <script src="vendor/angular-cookies/angular-cookies.js"></script>
@@ -28,12 +30,11 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
-<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
-<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/stats.directive.js"></script>
 <script src="/.tmp/samples.directive.js"></script>
diff --git a/views/ngXosViews/ceilometerDashboard/src/js/rest.js b/views/ngXosViews/ceilometerDashboard/src/js/rest.js
index 11c22c0..bcd582b 100644
--- a/views/ngXosViews/ceilometerDashboard/src/js/rest.js
+++ b/views/ngXosViews/ceilometerDashboard/src/js/rest.js
@@ -41,10 +41,10 @@
         return deferred.promise;
       };
 
-      this.getSamples = (name, tenant) => {
+      this.getSamples = (name, limit = 10) => {
         let deferred = $q.defer();
 
-        $http.get(`/api/tenant/monitoring/dashboard/metersamples/`, {params: {meter: name, tenant: tenant}})
+        $http.get(`/api/tenant/monitoring/dashboard/metersamples/`, {params: {meter: name, limit: limit}})
           .then((res) => {
             deferred.resolve(res.data)
           })
diff --git a/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js b/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
index 9f2dcea..3938714 100644
--- a/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
+++ b/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
@@ -10,7 +10,7 @@
   'use strict';
 
   angular.module('xos.ceilometerDashboard')
-  .directive('ceilometerSamples', function(_, $stateParams){
+  .directive('ceilometerSamples', function(_, $stateParams, $interval){
     return {
       restrict: 'E',
       scope: {},
@@ -39,10 +39,30 @@
 
         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;
-          this.tenant = $stateParams.tenant;
           // 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!');
@@ -118,42 +138,92 @@
             }, []);
         }
 
+        /**
+        * 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 = () => {
-          this.loader = true;
           // Ceilometer.getSamples(this.name, this.tenant) //fetch one
-          Ceilometer.getSamples(this.name) //fetch all
-            .then(res => {
+          let p;
+          if (isApie){
+            p = Ceilometer.getSamples(this.name, 30) //fetch all
+          }
+          else{
+            p = Ceilometer.getSamples(this.name) //fetch all
+          }
 
-              // 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
+          p.then(res => {
 
-              // 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;
+            // 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();
       }
     }
diff --git a/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html b/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
index b279123..8df2a29 100644
--- a/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
+++ b/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
@@ -16,7 +16,7 @@
   </div>
 </div>
 <section ng-if="!vm.loader && !vm.error">
-  <div class="row">
+  <div class="row" ng-if="vm.chartType !== 'pie'">
     <form class="form-inline col-xs-8" ng-submit="vm.addMeterToChart(vm.addMeterValue)">
       <select ng-model="vm.addMeterValue" class="form-control" ng-options="resource.id as resource.name for resource in vm.sampleLabels"></select>
       <button class="btn btn-success"> 
@@ -36,8 +36,25 @@
       <canvas ng-if="vm.chartType === 'bar'" id="bar" class="chart chart-bar" chart-data="vm.chart.data"
         chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">
       </canvas>
-      <!-- <pre>{{vm.chartMeters | json}}</pre> -->
     </div>
+    <!-- PIE CHART -->
+    <div class="col-xs-8" ng-if="vm.chartType === 'pie'">
+      <canvas id="pie" class="chart chart-pie"
+        chart-data="vm.chart.data" chart-labels="vm.chart.labels" chart-options="vm.chart.options">
+      </canvas> 
+    </div>
+    <div class="col-xs-4" ng-if="vm.chartType === 'pie'">
+      <div class="row" ng-repeat="item in vm.chart.labels">
+        <div class="col-xs-12">
+          <span 
+            class="btn btn-chart"
+            ng-style="{'background-color': vm.chartColors[$index]}">
+            {{item}}: {{vm.chart.data[$index]}}%
+          </span>
+        </div>
+      </div>
+    </div>
+    <!-- END PIE CHART -->
   </div>
   <div class="row" ng-if="!vm.loader">
     <div class="col-xs-12">
diff --git a/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us b/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
deleted file mode 100644
index 8e990a2..0000000
--- a/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
+++ /dev/null
@@ -1,20 +0,0 @@
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<meta name="viewport" content="width=device-width, initial-scale=1, max-scale=1">
-<!-- browserSync -->
-
-<!-- inject:css -->
-<link rel="stylesheet" href="/css/ceilometerDashboard.css">
-<link rel="stylesheet" href="/css/dev.css">
-<!-- endinject -->
-<link rel="stylesheet" href="css/ceilometerDashboard.css">
-<div id="xosCeilometerDashboard">
-  <div ui-view ng-class="stateName"></div>
-</div>
-
-
-<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
-<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
-<!-- inject:js -->
-<script src="/../../static/js/vendor/xosCeilometerDashboardVendor.js"></script>
-<script src="/../../static/js/xosCeilometerDashboard.js"></script>
-<!-- endinject -->