211 lines
5.1 KiB
JavaScript

'use strict';
angular.module('etcdControlPanel')
.controller('StatsCtrl', function ($scope, $rootScope, $interval, EtcdV2, statsVega, vg) {
$scope.graphContainer = '#latency';
$scope.graphVisibility = 'etcd-graph-show';
$scope.tableVisibility = 'etcd-table-hide';
//make requests
function readStats() {
EtcdV2.getStat('leader').get().success(function(data) {
$scope.leaderStats = data;
$scope.leaderName = data.leader;
$scope.peers = [];
//hardcode leader stats
$scope.peers.push({
latency: {
average: 0,
current: 0,
minimum: 0,
maximum: 0,
standardDeviation: 0
},
name: data.leader
});
$.each(data.followers, function(index, value) {
value.name = index;
$scope.peers.push(value);
});
//sort array so peers don't jump when output
$scope.peers.sort(function(a, b){
if(a.name < b.name) {
return -1;
}
if(a.name > b.name) {
return 1;
}
return 0;
});
drawGraph();
});
}
function drawGraph () {
//hardcoded padding from chart json
var vertPadding = 30;
var horzPadding = 15;
//fetch width and height of graph area
var width = $($scope.graphContainer).width() - horzPadding;
var height = $($scope.graphContainer).height() - vertPadding;
// parse a spec and create a visualization view
function parse(spec) {
vg.parse.spec(spec, function(chart) {
chart({
el: $scope.graphContainer,
data: {
'stats': $scope.peers
}
}).width(width).height(height).update();
});
}
parse(statsVega);
}
$scope.showTable = function() {
$scope.tableVisibility = 'etcd-table-reveal';
};
$scope.showGraph = function() {
$scope.tableVisibility = 'etcd-table-hide';
};
$scope.getHeight = function() {
return $(window).height();
};
$scope.getWidth = function() {
return $(window).width();
};
//$scope.$watch($scope.getHeight, function() {
////$('.etcd-container.etcd-stats .etcd-body').css('height', $scope.getHeight()-5);
//readStats();
//});
$scope.$watch($scope.getWidth, function() {
readStats();
});
window.onresize = function(){
$scope.$apply();
};
$scope.pollPromise = null;
$scope.startPolling = function() {
// Update the graphs live
if ($scope.pollPromise) {
return;
}
$scope.pollPromise = $interval(function() {
readStats();
}, 500);
};
$scope.stopPolling = function() {
$interval.cancel($scope.pollPromise);
$scope.pollPromise = null;
};
// Stop polling when navigating away from a view with this controller.
$rootScope.$on('$routeChangeStart', function () {
$scope.stopPolling();
});
$scope.startPolling();
})
/* statsVega returns the vega configuration for the stats dashboard */
.factory('statsVega', function () {
return {
'padding': {'top': 10, 'left': 5, 'bottom': 40, 'right': 10},
'data': [
{
'name': 'stats'
},
{
'name': 'thresholds',
'values': [50, 100]
}
],
'scales': [
{
'name': 'y',
'type': 'ordinal',
'range': 'height',
'domain': {'data': 'stats', 'field': 'index'}
},
{
'name': 'x',
'range': 'width',
'domainMin': 0,
'domainMax': 100,
'nice': true,
'zero': true,
'domain': {'data': 'stats', 'field': 'data.latency.current'}
},
{
'name': 'color',
'type': 'linear',
'domain': [10, 50, 100, 1000000000],
'range': ['#00DB24', '#FFC000', '#c40022', '#c40022']
}
],
'axes': [
{
'type': 'x',
'scale': 'x',
'ticks': 6,
'name': 'Latency (ms)'
},
{
'type': 'y',
'scale': 'y',
'properties': {
'ticks': {
'stroke': {'value': 'transparent'}
},
'majorTicks': {
'stroke': {'value': 'transparent'}
},
'labels': {
'fill': {'value': 'transparent'}
},
'axis': {
'stroke': {'value': '#333'},
'strokeWidth': {'value': 1}
}
}
}
],
'marks': [
{
'type': 'rect',
'from': {'data': 'stats'},
'properties': {
'enter': {
'x': {'scale': 'x', 'value': 0},
'x2': {'scale': 'x', 'field': 'data.latency.current'},
'y': {'scale': 'y', 'field': 'index', 'offset': -1},
'height': {'value': 3},
'fill': {'scale':'color', 'field':'data.latency.current'}
}
}
},
{
'type': 'symbol',
'from': {'data': 'stats'},
'properties': {
'enter': {
'x': {'scale': 'x', 'field': 'data.latency.current'},
'y': {'scale': 'y', 'field': 'index'},
'size': {'value': 50},
'fill': {'value': '#000'}
}
}
}
]
};
});