stats.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. 'use strict';
  2. angular.module('etcdStats', ['ngRoute', 'etcd'])
  3. .config(['$routeProvider', function ($routeProvider) {
  4. $routeProvider
  5. .when('/', {
  6. templateUrl: 'views/stats.html',
  7. controller: 'StatsCtrl'
  8. })
  9. .otherwise({
  10. templateUrl: 'views/stats.html',
  11. controller: 'StatsCtrl'
  12. });
  13. }])
  14. .controller('StatsCtrl', ['$scope', 'EtcdV1', 'statsVega', function ($scope, EtcdV1, statsVega) {
  15. $scope.graphContainer = '#latency';
  16. $scope.graphVisibility = 'etcd-graph-show';
  17. $scope.tableVisibility = 'etcd-table-hide';
  18. //make requests
  19. function readStats() {
  20. EtcdV1.getStat('leader').get().success(function(data) {
  21. $scope.leaderStats = data;
  22. $scope.followers = [];
  23. $.each(data.followers, function(index, value) {
  24. value.name = index;
  25. $scope.followers.push(value);
  26. });
  27. drawGraph();
  28. });
  29. }
  30. function drawGraph () {
  31. //hardcoded padding from chart json
  32. var vertPadding = 30;
  33. var horzPadding = 15;
  34. //fetch width and height of graph area
  35. var width = $($scope.graphContainer).width() - horzPadding;
  36. var height = $($scope.graphContainer).height() - vertPadding;
  37. // parse a spec and create a visualization view
  38. function parse(spec) {
  39. vg.parse.spec(spec, function(chart) {
  40. chart({
  41. el: $scope.graphContainer,
  42. data: {
  43. 'stats': $scope.followers
  44. }
  45. }).width(width).height(height).update();
  46. });
  47. }
  48. parse(statsVega);
  49. }
  50. $scope.showTable = function() {
  51. $scope.tableVisibility = 'etcd-table-reveal';
  52. };
  53. $scope.showGraph = function() {
  54. $scope.tableVisibility = 'etcd-table-hide';
  55. };
  56. $scope.getHeight = function() {
  57. return $(window).height();
  58. };
  59. $scope.getWidth = function() {
  60. return $(window).width();
  61. };
  62. $scope.$watch($scope.getHeight, function() {
  63. $('.etcd-body').css('height', $scope.getHeight()-5);
  64. readStats();
  65. });
  66. $scope.$watch($scope.getWidth, function() {
  67. readStats();
  68. });
  69. window.onresize = function(){
  70. $scope.$apply();
  71. };
  72. // Update the graphs live
  73. setInterval(function() {
  74. readStats();
  75. $scope.$apply();
  76. }, 500);
  77. }])
  78. /* statsVega returns the vega configuration for the stats dashboard */
  79. .factory('statsVega', function () {
  80. return {
  81. 'padding': {'top': 10, 'left': 5, 'bottom': 40, 'right': 10},
  82. 'data': [
  83. {
  84. 'name': 'stats'
  85. },
  86. {
  87. 'name': 'thresholds',
  88. 'values': [50, 100]
  89. }
  90. ],
  91. 'scales': [
  92. {
  93. 'name': 'y',
  94. 'type': 'ordinal',
  95. 'range': 'height',
  96. 'domain': {'data': 'stats', 'field': 'index'}
  97. },
  98. {
  99. 'name': 'x',
  100. 'range': 'width',
  101. 'domainMin': 0,
  102. 'domainMax': 100,
  103. 'nice': true,
  104. 'zero': true,
  105. 'domain': {'data': 'stats', 'field': 'data.latency.current'}
  106. },
  107. {
  108. 'name': 'color',
  109. 'type': 'linear',
  110. 'domain': [10, 50, 100, 1000000000],
  111. 'range': ['#00DB24', '#FFC000', '#c40022', '#c40022']
  112. }
  113. ],
  114. 'axes': [
  115. {
  116. 'type': 'x',
  117. 'scale': 'x',
  118. 'ticks': 6,
  119. 'name': 'Latency (ms)'
  120. },
  121. {
  122. 'type': 'y',
  123. 'scale': 'y',
  124. 'properties': {
  125. 'ticks': {
  126. 'stroke': {'value': 'transparent'}
  127. },
  128. 'majorTicks': {
  129. 'stroke': {'value': 'transparent'}
  130. },
  131. 'labels': {
  132. 'fill': {'value': 'transparent'}
  133. },
  134. 'axis': {
  135. 'stroke': {'value': '#333'},
  136. 'strokeWidth': {'value': 1}
  137. }
  138. }
  139. }
  140. ],
  141. 'marks': [
  142. {
  143. 'type': 'rect',
  144. 'from': {'data': 'stats'},
  145. 'properties': {
  146. 'enter': {
  147. 'x': {'scale': 'x', 'value': 0},
  148. 'x2': {'scale': 'x', 'field': 'data.latency.current'},
  149. 'y': {'scale': 'y', 'field': 'index', 'offset': -1},
  150. 'height': {'value': 3},
  151. 'fill': {'scale':'color', 'field':'data.latency.current'}
  152. }
  153. }
  154. },
  155. {
  156. 'type': 'symbol',
  157. 'from': {'data': 'stats'},
  158. 'properties': {
  159. 'enter': {
  160. 'x': {'scale': 'x', 'field': 'data.latency.current'},
  161. 'y': {'scale': 'y', 'field': 'index'},
  162. 'size': {'value': 50},
  163. 'fill': {'value': '#000'}
  164. }
  165. }
  166. }
  167. ]
  168. };
  169. });