This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository mum. See http://git.chorem.org/mum.git commit f5637be14655522df9b84671f345586779cd0242 Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Wed May 13 15:27:26 2015 +0200 statistics by module on hostpage --- static/js/controllers/hostPageCtrl.js | 154 ++++++++++++++++++++++++++++++++++ static/js/controllers/statsCtrl.js | 53 ++++++++---- views/hostpage.html | 50 +++++++++++ 3 files changed, 241 insertions(+), 16 deletions(-) diff --git a/static/js/controllers/hostPageCtrl.js b/static/js/controllers/hostPageCtrl.js index 14ee7f4..294faea 100644 --- a/static/js/controllers/hostPageCtrl.js +++ b/static/js/controllers/hostPageCtrl.js @@ -271,6 +271,21 @@ mumApp.controller('hostPageCtrl', function ($scope, $rootScope, $route, $routePa } }); }; + + $scope.open_modal_stats = function (addr_host, modname, subpart) { + var modalInstance = $modal.open({ + templateUrl: 'modal_stats.html', + controller: 'ModalStatsCtrl', + size: 'lg', + resolve: { + stats_args: function () { + return {'addr_host' : addr_host, + 'mod': modname, + 'subpart': subpart}; + } + } + }); + }; }); // modals controllers @@ -733,4 +748,143 @@ mumApp.controller('ModalPortConfigInstanceCtrl', function ($scope, $rootScope, $ $modalInstance.close(); $route.reload(); }; +}); + +mumApp.controller('ModalStatsCtrl', function ($scope, $rootScope, $modalInstance, $route, $timeout, stats_args) { + $scope.selected_host = stats_args.addr_host; + $scope.selected_mod = stats_args.mod; + $scope.selected_subpart = stats_args.subpart; + $scope.selected_period = 'min'; + + //data + $scope.stats = {}; + $scope.archive = {}; + + //calculated statistics + $scope.mean_value = 0; + $scope.standard_derivation = 0; + $scope.slope_lr = 0; + + $scope.get_stats = function() { + if ($scope.selected_host != null && $scope.selected_host != '') { + var args = {}; + args['addr_host'] = $scope.selected_host; + $rootScope.$broadcast("sendViaWs", JSON.stringify({"CALL_FUNC_DB": {'func': 'get_stats', 'args': args}})); + } + }; + + $scope.get_stats(); + + $scope.$on("resCall", function (event, args) { + if (args.func == 'get_stats') { + $timeout(function () { + $scope.stats = args.res.stats; + $scope.archive = args.res.archive; + $scope.update_stats(); + $scope.refresh_chart_data(); + }, 0); + } + }); + + $scope.update_stats = function() { + update_mean(); + update_standard_derivation(); + update_slope_of_linear_regression(); + }; + + $scope.refresh_chart_data = function() { + $scope.config.title = $scope.selected_host; + $scope.data.data = []; + var archive_list = $scope.archive[$scope.selected_mod][$scope.selected_period]; + // need to test if this achive have a subpart (= if its value is an object) + var first_entry = archive_list[0]; + if (typeof(first_entry.value) == "object") { + // if this archive have subparts + // will get the archives for the selected subpart + $scope.data.series = [$scope.selected_mod + ' on ' + $scope.selected_subpart]; + for (var i = 0; i<archive_list.length; i++) { + var current_arch = archive_list[i]; + if (current_arch.value.hasOwnProperty($scope.selected_subpart)) { + $scope.data.data.push({'x': i, + 'y': [current_arch.value[$scope.selected_subpart]], + 'tooltip': current_arch.value[$scope.selected_subpart] + " @ " + + current_arch.date.split('.')[0] + } + ) + } + } + } + else { + // there is no subpart + $scope.data.series = [$scope.selected_mod]; + var archive_list = $scope.archive[$scope.selected_mod][$scope.selected_period] + for (var i = 0; i < archive_list.length; i++) { + var current_arch = archive_list[i]; + $scope.data.data.push({'x': i, + 'y': [current_arch.value], + 'tooltip': current_arch.value + " @ " + + current_arch.date.split('.')[0] + } + ) + } + } + }; + + $scope.value_is_NaN = function (value) { + return value !== value; + }; + + var update_mean = function () { + var total = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total; + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + + $scope.mean_value = total / nb_check; + }; + + var update_standard_derivation = function () { + var m2 = $scope.stats[$scope.selected_mod][$scope.selected_subpart].M2; + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var variance = m2 / Math.max(1, nb_check + 1); + + $scope.standard_derivation = Math.sqrt(variance); + }; + + var update_slope_of_linear_regression = function () { + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var total = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total; + var lin_reg = $scope.stats[$scope.selected_mod][$scope.selected_subpart].lin_reg; + + var mX = (nb_check + 1) / 2; + var mY = total / nb_check; + var mX2 = (nb_check + 1) * (2 * nb_check + 1) / 6; + var mXY = lin_reg / nb_check; + + $scope.slope_lr = (mXY - mX * mY) / (mX2 - mX * mX); + }; + + // angular_charts fields : + $scope.config = { + title: '', + tooltips: true, + labels: false, + mouseover: function () {}, + mouseout: function () {}, + click: function () {}, + legend: { + display: true, + //could be 'left, right' + position: 'right' + }, + waitForHeightAndWidth: true + }; + + $scope.data = { + series: [], + data: [] + }; + + $scope.close = function () { + $modalInstance.close(); + $route.reload(); + }; }); \ No newline at end of file diff --git a/static/js/controllers/statsCtrl.js b/static/js/controllers/statsCtrl.js index 10c49a1..fedad18 100644 --- a/static/js/controllers/statsCtrl.js +++ b/static/js/controllers/statsCtrl.js @@ -61,26 +61,35 @@ mumApp.controller('statsCtrl', function ($scope, $rootScope, $timeout, DataHosts $scope.refresh_chart_data = function() { $scope.config.title = $scope.selected_host; $scope.data.data = []; - if (typeof($scope.archive[$scope.selected_mod][$scope.selected_period][0].value) == "object") { + var archive_list = $scope.archive[$scope.selected_mod][$scope.selected_period]; + // need to test if this achive have a subpart (= if its value is an object) + var first_entry = archive_list[0]; + if (typeof(first_entry.value) == "object") { + // if this archive have subparts + // will get the archives for the selected subpart $scope.data.series = [$scope.selected_mod + ' on ' + $scope.selected_subpart]; - for (var i = 0; i<$scope.archive[$scope.selected_mod][$scope.selected_period].length; i++) { - if ($scope.archive[$scope.selected_mod][$scope.selected_period][i].value.hasOwnProperty($scope.selected_subpart)) { + for (var i = 0; i<archive_list.length; i++) { + var current_arch = archive_list[i]; + if (current_arch.value.hasOwnProperty($scope.selected_subpart)) { $scope.data.data.push({'x': i, - 'y': [$scope.archive[$scope.selected_mod][$scope.selected_period][i].value[$scope.selected_subpart]], - 'tooltip': $scope.archive[$scope.selected_mod][$scope.selected_period][i].value[$scope.selected_subpart] + " @ " + - $scope.archive[$scope.selected_mod][$scope.selected_period][i].date.split('.')[0] + 'y': [current_arch.value[$scope.selected_subpart]], + 'tooltip': current_arch.value[$scope.selected_subpart] + " @ " + + current_arch.date.split('.')[0] } ) } } } else { + // there is no subpart $scope.data.series = [$scope.selected_mod]; - for (var i = 0; i<$scope.archive[$scope.selected_mod][$scope.selected_period].length; i++) { + var archive_list = $scope.archive[$scope.selected_mod][$scope.selected_period] + for (var i = 0; i < archive_list.length; i++) { + var current_arch = archive_list[i]; $scope.data.data.push({'x': i, - 'y': [$scope.archive[$scope.selected_mod][$scope.selected_period][i].value], - 'tooltip': $scope.archive[$scope.selected_mod][$scope.selected_period][i].value + " @ " + - $scope.archive[$scope.selected_mod][$scope.selected_period][i].date.split('.')[0] + 'y': [current_arch.value], + 'tooltip': current_arch.value + " @ " + + current_arch.date.split('.')[0] } ) } @@ -92,22 +101,34 @@ mumApp.controller('statsCtrl', function ($scope, $rootScope, $timeout, DataHosts }; var update_mean = function () { - $scope.mean_value = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total / $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var total = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total; + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + + $scope.mean_value = total / nb_check; }; var update_standard_derivation = function () { - var variance = $scope.stats[$scope.selected_mod][$scope.selected_subpart].M2 / Math.max(1, $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check + 1); + var m2 = $scope.stats[$scope.selected_mod][$scope.selected_subpart].M2; + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var variance = m2 / Math.max(1, nb_check + 1); + $scope.standard_derivation = Math.sqrt(variance); }; var update_slope_of_linear_regression = function () { - var mX = ($scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check + 1) / 2; - var mY = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total / $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; - var mX2 = ($scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check + 1) * (2 * $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check + 1) / 6; - var mXY = $scope.stats[$scope.selected_mod][$scope.selected_subpart].lin_reg / $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var nb_check = $scope.stats[$scope.selected_mod][$scope.selected_subpart].nb_check; + var total = $scope.stats[$scope.selected_mod][$scope.selected_subpart].total; + var lin_reg = $scope.stats[$scope.selected_mod][$scope.selected_subpart].lin_reg; + + var mX = (nb_check + 1) / 2; + var mY = total / nb_check; + var mX2 = (nb_check + 1) * (2 * nb_check + 1) / 6; + var mXY = lin_reg / nb_check; + $scope.slope_lr = (mXY - mX * mY) / (mX2 - mX * mX); }; + // angular_charts fields : $scope.config = { title: '', tooltips: true, diff --git a/views/hostpage.html b/views/hostpage.html index c0cfc8b..91d55d5 100644 --- a/views/hostpage.html +++ b/views/hostpage.html @@ -57,6 +57,8 @@ <td>{{item.date.split('.')[0]}}</td> <td><button type="button" class="btn btn-primary btn-xs" ng-click="open_modal_conf(itemname)">Configure</button></td> + <td><button type="button" class="btn btn-primary btn-xs" + ng-click="open_modal_stats(addr_host, itemname, '')">Archives</button></td> <td><button type="button" class="btn btn-info btn-xs" ng-click="check(itemname)">Check now</button></td> </tr> @@ -65,6 +67,8 @@ collapse="collapsed[itemname]"> <td>{{valname}}</td> <td>{{val}} {{get_unit(itemname)}}</td> + <td><button type="button" class="btn btn-primary btn-xs" + ng-click="open_modal_stats(addr_host, itemname, valname)">Archives</button></td> </tr> </tbody> @@ -542,4 +546,50 @@ </script> + <script type="text/ng-template" id="modal_stats.html"> + <div class="modal-header"> + <h3 class="modal-title">Statistics for {{selected_host}} on {{selected_mod}}</h3> + </div> + <div class="modal-body"> + <select ng-model="selected_period" + ng-show="selected_mod != ''" + ng-change="refresh_chart_data()"> + <option value="min">By minute</option> + <option value="hour">By hour</option> + <option value="day">By day</option> + <option value="week">By week</option> + <option value="month">By month</option> + <option value="year">By year</option> + </select> + <div class="row" + ng-show="selected_mod != ''"> + <div class="col-xs-2" + ng-show="!value_is_NaN(mean_value)"> + Mean value : {{mean_value}} + </div> + <div class="col-xs-2" + ng-show="!value_is_NaN(standard_derivation)"> + Standard derivation : {{standard_derivation}} + </div> + <div class="col-xs-2" + ng-show="!value_is_NaN(slope_lr)"> + Slope of linear regression : {{slope_lr}} + </div> + </div> + <div + style="" + ng-show="selected_period != ''" + data-ac-chart="'line'" + data-ac-data="data" + data-ac-config="config" + class="chart"> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal" + ng-click="close()">Close</button> + </div> + + </script> + </div> \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.