Review for Xos Ceilometer Statistics
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json b/xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json
index 22da52a..c11ad13 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json
@@ -15,7 +15,8 @@
"tests"
],
"dependencies": {
- "angular-chart.js": "~0.8.7"
+ "angular-chart.js": "~0.8.7",
+ "angular-animate": "~1.4.8"
},
"devDependencies": {
"jquery": "~2.1.4",
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/env/srikanth.js b/xos/core/xoslib/ngXosViews/ceilometerDashboard/env/srikanth.js
new file mode 100644
index 0000000..c7b051d
--- /dev/null
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/env/srikanth.js
@@ -0,0 +1,13 @@
+// This is a default configuration for your development environment.
+// You can duplicate this configuration for any of your Backend Environments.
+// Different configurations are loaded setting a NODE_ENV variable that contain the config file name.
+// `NODE_ENV=local npm start`
+//
+// If xoscsrftoken or xossessionid are not specified the browser value are used
+// (works only for local environment as both application are served on the same domain)
+
+module.exports = {
+ host: 'http://130.127.133.87:9999',
+ xoscsrftoken: 'z0Ddap4Cx0v7onhXuqq1cIyp1NbYFUjA',
+ xossessionid: 'c93iufpoe8e7vbo6uesrh8j5xnvb6fva'
+};
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
index 56ae00f..b2c5d50 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
@@ -84,40 +84,129 @@
}
}
- /* Split.js */
+ /* VIEW ANIMATION */
- html, body {
- height: 100%;
+ [ui-view] {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 100%;
}
- body {
- box-sizing: border-box;
+ /* FROM DASHBOARD TO DETAIL */
+
+ /* dash out */
+ [ui-view].ceilometerDashboard.ng-leave {
+ animation:1s bounceOutLeft ease;
+ }
+ /* samples in */
+ [ui-view].samples.ng-enter {
+ animation:1s bounceInRight ease;
}
- .split {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- overflow-y: auto;
- overflow-x: hidden;
+ /* FROM DETAIL TO DASHBOARD */
+
+ /* samples out */
+ [ui-view].samples.ng-leave {
+ animation:1s bounceOutRight ease;
}
- .gutter {
- background-color: transparent;
- background-repeat: no-repeat;
- background-position: 50%;
- }
- .gutter.gutter-horizontal {
- cursor: col-resize;
- background-image: url('grips/vertical.png');
- }
- .gutter.gutter-vertical {
- cursor: row-resize;
- background-image: url('grips/horizontal.png');
- }
- .split.split-horizontal, .gutter.gutter-horizontal {
- height: 100%;
- float: left;
+ /* dash in */
+ [ui-view].ceilometerDashboard.ng-enter {
+ animation:1s bounceInLeft ease;
}
+ /* COLUMS ANIMATION */
+
+ /* when showing the thing */
+ .animate .animate-slide-left.ng-hide-remove {
+ animation:0.5s bounceInRight ease;
+ }
+
+ /* when hiding the picture */
+ .animate .animate-slide-left.ng-hide-add {
+ animation:0.5s bounceOutRight ease;
+ }
+
+ /* ANIMATIONS */
+
+ @keyframes bounceInRight {
+ from, 60%, 75%, 90%, to {
+ animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ from {
+ opacity: 0;
+ transform: translate3d(3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ transform: translate3d(-25px, 0, 0);
+ }
+
+ 75% {
+ transform: translate3d(10px, 0, 0);
+ }
+
+ 90% {
+ transform: translate3d(-5px, 0, 0);
+ }
+
+ to {
+ transform: none;
+ }
+ }
+
+ @keyframes bounceInLeft {
+ from, 60%, 75%, 90%, to {
+ animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ transform: translate3d(-3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ transform: translate3d(25px, 0, 0);
+ }
+
+ 75% {
+ transform: translate3d(-10px, 0, 0);
+ }
+
+ 90% {
+ transform: translate3d(5px, 0, 0);
+ }
+
+ to {
+ transform: none;
+ }
+ }
+
+ @keyframes bounceOutRight {
+ 20% {
+ opacity: 1;
+ transform: translate3d(-20px, 0, 0);
+ }
+
+ to {
+ opacity: 0;
+ transform: translate3d(2000px, 0, 0);
+ }
+ }
+
+ @keyframes bounceOutLeft {
+ 20% {
+ opacity: 1;
+ transform: translate3d(20px, 0, 0);
+ }
+
+ to {
+ opacity: 0;
+ transform: translate3d(-2000px, 0, 0);
+ }
+ }
/*}
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html
index adaa2ee..de89045 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html
@@ -10,16 +10,15 @@
<link rel="stylesheet" href="/css/dev.css">
<!-- endinject -->
<link rel="stylesheet" href="css/ceilometerDashboard.css">
-
<div ng-app="xos.ceilometerDashboard" id="xosCeilometerDashboard">
- <div ui-view></div>
+ <div ui-view ng-class="stateName"></div>
</div>
<!-- bower:js -->
-<script src="vendor/Split.js/split.js"></script>
<script src="vendor/angular/angular.js"></script>
<script src="vendor/Chart.js/Chart.js"></script>
<script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
+<script src="vendor/angular-animate/angular-animate.js"></script>
<script src="vendor/jquery/dist/jquery.js"></script>
<script src="vendor/angular-mocks/angular-mocks.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js
index 75c7eaa..c2daf7f 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js
@@ -6,10 +6,10 @@
'ngLodash',
'ui.router',
'xos.helpers',
- // 'angularCharts',
+ 'ngAnimate',
'chart.js'
])
-.config(($stateProvider) => {
+.config(($stateProvider, $urlRouterProvider) => {
$stateProvider
.state('ceilometerDashboard', {
url: '/',
@@ -29,16 +29,26 @@
},
templateUrl: 'templates/split.html'
});
+ $urlRouterProvider.otherwise('/');
})
.config(function($httpProvider){
$httpProvider.interceptors.push('NoHyperlinks');
})
+.run(function($rootScope){
+ $rootScope.stateName = 'ceilometerDashboard';
+ $rootScope.$on('$stateChangeStart', (event, toState) => {
+ console.log(toState.name);
+ $rootScope.stateName = toState.name;
+ })
+})
.service('Ceilometer', function($http, $q){
this.getMeters = () => {
let deferred = $q.defer();
- $http.get('/xoslib/meters/', {cache: true})
+ // $http.get('/xoslib/meters/', {cache: true})
+ $http.get('../meters_mock.json', {cache: true})
.then((res) => {
+ console.log(res.data);
deferred.resolve(res.data)
})
.catch((e) => {
@@ -91,6 +101,35 @@
this.loadMeters();
+ /**
+ * Select Resources for a slice
+ *
+ * @param Array resources The list of selected resources
+ * @returns void
+ */
+ this.selectedResources = null;
+ this.selectResources = (resources, slice) => {
+ //cleaning
+ this.selectedResources = null;
+ this.selectedResource = null;
+ this.selectedMeters = null;
+
+ this.selectedResources = resources;
+ this.selectedSlice = slice;
+ }
+
+ /**
+ * Select Meters for a resource
+ *
+ * @param Array meters The list of selected resources
+ * @returns void
+ */
+ this.selectedMeters = null;
+ this.selectMeters = (meters, resource) => {
+ this.selectedMeters = meters;
+ this.selectedResource = resource;
+ }
+
}
};
})
@@ -106,30 +145,21 @@
templateUrl: 'templates/ceilometer-samples.tpl.html',
controller: function(Ceilometer) {
+ this.chartType = 'line';
+
if($stateParams.name && $stateParams.tenant){
this.name = $stateParams.name;
this.tenant = $stateParams.tenant;
}
- this.formatDateLabels = (date) => {
- // date = new Date(date);
- // return `${date.getMonth()}/${date.getYear()}`
- return date;
- };
+ // Mock
- this.formatSamplesData = (data) => {
-
- let formatted = [];
-
- lodash.forEach(data, (item) => {
- formatted.push({
- x: this.formatDateLabels(item.timestamp),
- y: [item.volume]
- });
- });
-
- return lodash.sortBy(formatted, 'timestamp');
- }
+ /**
+ * Goe 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) => {
@@ -139,6 +169,13 @@
}, []);
};
+ /**
+ * Goe 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);
@@ -146,13 +183,24 @@
}, []);
}
+ this.addMeterToChart = (project_id) => {
+ this.chart['series'].push(project_id);
+ this.chart['data'].push(this.getData(this.samplesList[project_id]))
+ }
+
+ /**
+ * Load the samples and format data
+ */
+
this.showSamples = () => {
this.loader = true;
- Ceilometer.getSamples(this.name, this.tenant)
+ // Ceilometer.getSamples(this.name, this.tenant) //fetch one
+ Ceilometer.getSamples(this.name) //fetch all
.then(res => {
- res = lodash.sortBy(res, 'timestamp');
+ this.samplesList = lodash.groupBy(res, 'project_id');
+ res = lodash.sortBy(this.samplesList[this.tenant], 'timestamp');
this.chart = {
- series: [this.name],
+ series: [this.tenant],
labels: this.getLabels(res),
data: [this.getData(res)]
}
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/meters_mock.json b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/meters_mock.json
new file mode 100644
index 0000000..e6203ed
--- /dev/null
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/meters_mock.json
@@ -0,0 +1,145 @@
+[
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "subnet",
+ "resource_id": "6ebbcbdb-a172-41bf-8014-686c017c3d5a",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "NmViYmNiZGItYTE3Mi00MWJmLTgwMTQtNjg2YzAxN2MzZDVhK3N1Ym5ldA==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "subnet",
+ "description": "Existence of subnet"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "network",
+ "resource_id": "2ccafd0d-630f-45db-9b0e-b58a9d1de494",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MmNjYWZkMGQtNjMwZi00NWRiLTliMGUtYjU4YTlkMWRlNDk0K25ldHdvcms=\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "network",
+ "description": "Existence of network"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "instance",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK2luc3RhbmNl\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "instance",
+ "description": "Existence of instance"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "network.incoming.bytes.rate",
+ "resource_id": "instance-0000000c-03663f84-adb2-40cf-ac22-b48dd18909da-tapb62de4c8-a8",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "aW5zdGFuY2UtMDAwMDAwMGMtMDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhLXRh\ncGI2MmRlNGM4LWE4K25ldHdvcmsuaW5jb21pbmcuYnl0ZXMucmF0ZQ==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "B/s",
+ "description": "Average rate per sec of incoming bytes on a VM network interface"
+ },
+ {
+ "project_name": "mysite_vcpe",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "port",
+ "resource_id": "a14625cf-4184-460c-bef2-a2f8ff2054de",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "YTE0NjI1Y2YtNDE4NC00NjBjLWJlZjItYTJmOGZmMjA1NGRlK3BvcnQ=\n",
+ "project_id": "1e948b44facc4efd81567d94b7c4d7a8",
+ "type": "gauge",
+ "unit": "port",
+ "description": "Existence of port"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "cpu_util",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK2NwdV91dGls\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "%",
+ "description": "Average CPU utilization"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "vcpus",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK3ZjcHVz\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "vcpu",
+ "description": "Number of VCPUs"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "network.outgoing.bytes.rate",
+ "resource_id": "instance-0000000c-03663f84-adb2-40cf-ac22-b48dd18909da-tapb62de4c8-a8",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "aW5zdGFuY2UtMDAwMDAwMGMtMDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhLXRh\ncGI2MmRlNGM4LWE4K25ldHdvcmsub3V0Z29pbmcuYnl0ZXMucmF0ZQ==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "B/s",
+ "description": "Average rate per sec of outgoing bytes on a VM network interface"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "memory",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK21lbW9yeQ==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "MB",
+ "description": "Volume of RAM"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "cpu",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK2NwdQ==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "cumulative",
+ "unit": "ns",
+ "description": "CPU time used"
+ },
+ {
+ "project_name": "mysite_onos_vbng",
+ "user_id": "bcb8c1f07ab94a948b0ea491f2ba43f1",
+ "name": "memory.usage",
+ "resource_id": "03663f84-adb2-40cf-ac22-b48dd18909da",
+ "label": "",
+ "source": "openstack",
+ "meter_id": "MDM2NjNmODQtYWRiMi00MGNmLWFjMjItYjQ4ZGQxODkwOWRhK21lbW9yeS51c2FnZQ==\n",
+ "project_id": "75bf7d7deee744749ac76dc6d2e22c28",
+ "type": "gauge",
+ "unit": "MB",
+ "description": "Volume of RAM used"
+ }
+]
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
index 3eee429..5f8fb1a 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
@@ -1,6 +1,6 @@
<div class="row">
<div class="col-sm-12">
- <h1>Ceilometer Dashboard</h1>
+ <h1>XOS Monitoring Statistics</h1>
</div>
</div>
@@ -10,52 +10,44 @@
</div>
</div>
-<section ng-hide="vm.loader">
+<section ng-hide="vm.loader" ng-class="{animate: !vm.loader}">
<div class="row">
- <div class="col-xs-12">
- <h2>Projects</h2>
- </div>
- </div>
- <div class="well" ng-repeat="(project, resources) in vm.projects">
- <div class="row">
- <div class="col-xs-11">
- <h3>{{project}}</h3>
- </div>
- <div class="col-xs-1">
- <a ng-click="expandProject = !expandProject" class="btn btn-primary">
- <i class="glyphicon glyphicon-plus"></i>
+ <div class="col-sm-4">
+ <div class="list-group">
+ <div class="list-group-item">
+ <h2>Service Name</h2>
+ </div>
+ <a href="#" ng-click="vm.selectResources(resources, slice)" class="list-group-item" ng-repeat="(slice, resources) in vm.projects" ng-class="{active: slice === vm.selectedSlice}">
+ {{slice}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>
</a>
</div>
</div>
-
- <div class="row">
- <div class="panel panel-default" ng-show="expandProject">
- <div class="panel-heading">
- <h4>Resources</h4>
+ <div class="col-sm-4 animate-slide-left" ng-hide="!vm.selectedResources">
+ <div class="list-group">
+ <div class="list-group-item">
+ <h2>Resources</h2>
</div>
- <div class="panel-body" ng-repeat="(resource, meters) in resources">
+ <a href="#" ng-click="vm.selectMeters(meters, resource)" class="list-group-item" ng-repeat="(resource, meters) in vm.selectedResources" ng-class="{active: resource === vm.selectedResource}">
+ {{resource}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>
+ </a>
+ </div>
+ </div>
+ <div class="col-sm-4 animate-slide-left" ng-hide="!vm.selectedMeters">
+ <div class="list-group">
+ <div class="list-group-item">
+ <h2>Meters</h2>
+ </div>
+ <div class="list-group-item">
<div class="row">
- <div class="col-xs-11">
- <b>{{resource}}</b>
+ <div class="col-xs-4">
+ <label>Name:</label>
</div>
- <div class="col-xs-1">
- <a ng-click="expandResource = !expandResource" class="btn btn-primary">
- <i class="glyphicon glyphicon-plus"></i>
- </a>
+ <div class="col-xs-4">
+ <label>Unit:</label>
</div>
+ <div class="col-xs-4"></div>
</div>
- <div class="row" ng-show="expandResource">
- <div class="col-xs-4">
- <b>Meter:</b>
- </div>
- <div class="col-xs-4">
- <b>Unit:</b>
- </div>
- <div class="col-xs-4">
- <b>Actions:</b>
- </div>
- </div>
- <div class="row" ng-repeat="meter in meters" ng-show="expandResource">
+ <div class="row" ng-click="vm.selectMeters(meters)" ng-repeat="meter in vm.selectedMeters" style="margin-bottom: 10px;">
<div class="col-xs-4">
{{meter.name}}
</div>
@@ -63,21 +55,13 @@
{{meter.unit}}
</div>
<div class="col-xs-4">
- <!-- <a ng-click="showMeter = !showMeter" class="btn btn-primary">
- <i class="glyphicon glyphicon-search"></i> Details
- </a> -->
- <a ng-click="showChart = !showChart" class="btn btn-primary">
- <i class="glyphicon glyphicon-search"></i> View chart
+ <a ui-sref="samples({name: meter.name, tenant: meter.project_id})" class="btn btn-primary">
+ <i class="glyphicon glyphicon-search"></i>
</a>
</div>
- <!-- -->
- <div class="col-xs-12" ng-show="showChart">
- <ceilometer-samples name="meter.name" tenant="meter.project_id" ng-if="showChart"></ceilometer-samples>
- </div>
</div>
</div>
</div>
</div>
-
</div>
-</section>
\ No newline at end of file
+</section>
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
index d935e27..b8c5f39 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
+++ b/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
@@ -1,13 +1,40 @@
+<!-- <pre>{{ vm | json}}</pre> -->
+
+<div class="row">
+ <div class="col-xs-10">
+ <h1>{{vm.name | uppercase}}</h1>
+ </div>
+ <div class="col-xs-2">
+ <a ui-sref="ceilometerDashboard" class="btn btn-primary pull-right">
+ <i class="glyphicon glyphicon-arrow-left"></i> Back to list
+ </a>
+ </div>
+</div>
+
+<div class="row">
+ <form class="form-inline col-xs-8" ng-submit="vm.addMeterToChart(vm.addMeterValue)">
+ <select ng-model="vm.addMeterValue" class="form-control" ng-options="project as project for (project, meter) in vm.samplesList"></select>
+ <button class="btn btn-success">
+ <i class="glyphicon glyphicon-plus"></i> Add
+ </button>
+ </form>
+ <div class="col-xs-4 text-right">
+ <a ng-click="vm.chartType = 'line'" class="btn" ng-class="{'btn-default': vm.chartType != 'bar', 'btn-primary': vm.chartType == 'line'}">Lines</a>
+ <a ng-click="vm.chartType = 'bar'" class="btn" ng-class="{'btn-default': vm.chartType != 'line', 'btn-primary': vm.chartType == 'bar'}">Bars</a>
+ </div>
+</div>
+
<div class="row">
<div class="col-xs-12" ng-show="vm.loader">
<div class="loader">Loading</div>
</div>
<div class="col-xs-12" ng-if="!vm.loader">
- <!-- <div ac-chart="'line'" ac-data="vm.sampleChartData" ac-config="vm.sampleChartConfig" class="chart"></div> -->
- <canvas id="line" class="chart chart-line" chart-data="vm.chart.data"
+ <canvas ng-if="vm.chartType === 'line'" id="line" class="chart chart-line" chart-data="vm.chart.data"
+ chart-labels="vm.chart.labels" chart-legend="true" chart-series="vm.chart.series">
+ </canvas>
+ <canvas ng-if="vm.chartType === 'bar'" id="bar" class="chart chart-bar" chart-data="vm.chart.data"
chart-labels="vm.chart.labels" chart-legend="true" chart-series="vm.chart.series">
</canvas>
- <!-- <pre> {{ vm.chart | json }} </pre> -->
</div>
</div>
\ No newline at end of file