Ver código fonte

Singlestat: threshold checks are now done on a rounded value, rounded to same number of decimals as is shown, Fixes #1983

Torkel Ödegaard 10 anos atrás
pai
commit
582e680b12

+ 5 - 0
public/app/components/kbn.js

@@ -404,6 +404,11 @@ function($, _, moment) {
   kbn.valueFormats.velocitymph = function(value, decimals) { return kbn.toFixed(value, decimals) + ' mph'; };
   kbn.valueFormats.velocityknot = function(value, decimals) { return kbn.toFixed(value, decimals) + ' kn'; };
 
+  kbn.roundValue = function (num, decimals) {
+    var n = Math.pow(10, decimals);
+    return Math.round((n * num).toFixed(decimals))  / n;
+  };
+
   kbn.toFixedScaled = function(value, decimals, scaledDecimals, additionalDecimals, ext) {
     if (scaledDecimals === null) {
       return kbn.toFixed(value, decimals) + ext;

+ 19 - 20
public/app/panels/singlestat/module.js

@@ -170,17 +170,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
     $scope.render = function() {
       var data = {};
 
-      if (!$scope.series || $scope.series.length === 0) {
-        data.flotpairs = [];
-        data.mainValue = Number.NaN;
-        data.mainValueFormated = $scope.getFormatedValue(null);
-      }
-      else {
-        var series = $scope.series[0];
-        data.mainValue = series.stats[$scope.panel.valueName];
-        data.mainValueFormated = $scope.getFormatedValue(data.mainValue);
-        data.flotpairs = series.flotpairs;
-      }
+      $scope.setValues(data);
 
       data.thresholds = $scope.panel.thresholds.split(',').map(function(strVale) {
         return Number(strVale.trim());
@@ -192,32 +182,41 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       $scope.$broadcast('render');
     };
 
-    $scope.getFormatedValue = function(mainValue) {
+    $scope.setValues = function(data) {
+      data.flotpairs = [];
+
+      if ($scope.series && $scope.series.length > 0) {
+        data.value = $scope.series[0].stats[$scope.panel.valueName];
+        data.flotpairs = $scope.series[0].flotpairs;
+      }
 
       // first check value to text mappings
       for(var i = 0; i < $scope.panel.valueMaps.length; i++) {
         var map = $scope.panel.valueMaps[i];
         // special null case
         if (map.value === 'null') {
-          if (mainValue === null || mainValue === void 0) {
-            return map.text;
+          if (data.value === null || data.value === void 0) {
+            data.valueFormated = map.text;
+            return;
           }
           continue;
         }
         // value/number to text mapping
         var value = parseFloat(map.value);
-        if (value === mainValue) {
-          return map.text;
+        if (value === data.value) {
+          data.valueFormated = map.text;
+          return;
         }
       }
 
-      if (mainValue === null || mainValue === void 0) {
-        return "no value";
+      if (data.value === null || data.value === void 0) {
+        data.valueFormated = "no value";
       }
 
-      var decimalInfo = $scope.getDecimalsForValue(mainValue);
+      var decimalInfo = $scope.getDecimalsForValue(data.value);
       var formatFunc = kbn.valueFormats[$scope.panel.format];
-      return formatFunc(mainValue, decimalInfo.decimals, decimalInfo.scaledDecimals);
+      data.valueFormated = formatFunc(data.value, decimalInfo.decimals, decimalInfo.scaledDecimals);
+      data.valueRounded = kbn.roundValue(data.value, decimalInfo.decimals);
     };
 
     $scope.removeValueMap = function(map) {

+ 3 - 3
public/app/panels/singlestat/singleStatPanel.js

@@ -73,7 +73,7 @@ function (angular, app, _, $) {
 
           if (panel.prefix) { body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, scope.panel.prefix); }
 
-          var value = applyColoringThresholds(data.mainValue, data.mainValueFormated);
+          var value = applyColoringThresholds(data.valueRounded, data.valueFormated);
           body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
 
           if (panel.postfix) { body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.postfix); }
@@ -147,8 +147,8 @@ function (angular, app, _, $) {
 
           var body = getBigValueHtml();
 
-          if (panel.colorBackground && !isNaN(data.mainValue)) {
-            var color = getColorForValue(data.mainValue);
+          if (panel.colorBackground && !isNaN(data.valueRounded)) {
+            var color = getColorForValue(data.valueRounded);
             if (color) {
               $panelContainer.css('background-color', color);
               if (scope.fullscreen) {

+ 85 - 0
public/test/specs/singlestat-specs.js

@@ -0,0 +1,85 @@
+define([
+  'helpers',
+  'features/panel/panelSrv',
+  'features/panel/panelHelper',
+  'panels/singlestat/module'
+], function(helpers) {
+  'use strict';
+
+  describe('SingleStatCtrl', function() {
+    var ctx = new helpers.ControllerTestContext();
+
+    function singleStatScenario(desc, func) {
+
+      describe(desc, function() {
+
+        ctx.setup = function (setupFunc) {
+
+          beforeEach(module('grafana.services'));
+          beforeEach(module('grafana.panels.singlestat'));
+
+          beforeEach(ctx.providePhase());
+          beforeEach(ctx.createControllerPhase('SingleStatCtrl'));
+
+          beforeEach(function() {
+            setupFunc();
+            ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
+              data: [ { target: 'test.cpu1', datapoints: ctx.datapoints } ]
+            }));
+
+            ctx.scope.refreshData(ctx.datasource);
+            ctx.scope.$digest();
+            ctx.data = ctx.scope.data;
+          });
+        };
+
+        func(ctx);
+      });
+    }
+
+    singleStatScenario('with defaults', function(ctx) {
+      ctx.setup(function() {
+        ctx.datapoints = [[10,1], [20,2]];
+      });
+
+      it('Should use series avg as default main value', function() {
+        expect(ctx.data.value).to.be(15);
+        expect(ctx.data.valueRounded).to.be(15);
+      });
+
+      it('should set formated falue', function() {
+        expect(ctx.data.valueFormated).to.be('15');
+      });
+    });
+
+    singleStatScenario('MainValue should use same number for decimals as displayed when checking thresholds', function(ctx) {
+      ctx.setup(function() {
+        ctx.datapoints = [[99.999,1], [99.99999,2]];
+      });
+
+      it('Should be rounded', function() {
+        expect(ctx.data.value).to.be(99.999495);
+        expect(ctx.data.valueRounded).to.be(100);
+      });
+
+      it('should set formated falue', function() {
+        expect(ctx.data.valueFormated).to.be('100');
+      });
+    });
+
+    singleStatScenario('When value to text mapping is specified', function(ctx) {
+      ctx.setup(function() {
+        ctx.datapoints = [[10,1]];
+        ctx.scope.panel.valueMaps = [{value: '10', text: 'OK'}];
+      });
+
+      it('Should replace value with text', function() {
+        expect(ctx.data.value).to.be(10);
+        expect(ctx.data.valueFormated).to.be('OK');
+      });
+
+    });
+
+  });
+});
+

+ 1 - 0
public/test/test-main.js

@@ -140,6 +140,7 @@ require([
     'specs/dashboardSrv-specs',
     'specs/dashboardViewStateSrv-specs',
     'specs/soloPanelCtrl-specs',
+    'specs/singlestat-specs',
     'specs/dynamicDashboardSrv-specs',
     'specs/unsavedChangesSrv-specs',
   ];