Просмотр исходного кода

SinglestatPanel: Added null point handling, and value to text mapping, Closes #1130, Fixes #1120, #951

Torkel Ödegaard 11 лет назад
Родитель
Сommit
a1d652d578
3 измененных файлов с 92 добавлено и 9 удалено
  1. 4 0
      CHANGELOG.md
  2. 41 2
      src/app/panels/singlestat/editor.html
  3. 47 7
      src/app/panels/singlestat/module.js

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 # 1.9.0 (unreleased)
 
+**Enhancements**
+- [Issue #1130](https://github.com/grafana/grafana/issues/1130). SinglestatPanel: Added null point handling, and value to text mapping
+
+
 **Fixes**
 - [Issue #1087](https://github.com/grafana/grafana/issues/1087). Panel: Fixed IE9 crash due to angular drag drop
 - [Issue #1093](https://github.com/grafana/grafana/issues/1093). SingleStatPanel: Fixed position for drilldown link tooltip when dashboard requires scrolling

+ 41 - 2
src/app/panels/singlestat/editor.html

@@ -13,6 +13,10 @@
 			<label class="small">Postfix</label>
 			<input type="text" class="input-small" ng-model="panel.postfix" ng-blur="render()" ng-trim="false"></input>
 		</div>
+    <div class="editor-option">
+      <label class="small">Null point mode<tip>Define how null values should handled, connected = ignored</tip></label>
+      <select class="input-medium" ng-model="panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="get_data()"></select>
+    </div>
 	</div>
 
 	<div class="section">
@@ -38,6 +42,9 @@
 			<select class="input-small" ng-model="panel.format" ng-options="f for f in ['none','short','bytes', 'bits', 'bps', 's', 'ms', 'µs', 'ns', 'percent']" ng-change="render()"></select>
 		</div>
 	</div>
+</div>
+
+<div class="editor-row">
 	<div class="section">
     <h5>Coloring</h5>
 		<editor-opt-bool text="Background" model="panel.colorBackground" change="setColoring({background: true})"></editor-opt-bool>
@@ -54,9 +61,7 @@
 			<a class="pointer" ng-click="invertColorOrder()">invert order</a>
 		</div>
 	</div>
-</div>
 
-<div class="editor-row">
 	<div class="section">
 		<h5>Spark lines</h5>
 		<editor-opt-bool text="Spark line" model="panel.sparkline.show" change="render()"></editor-opt-bool>
@@ -72,5 +77,39 @@
 	</div>
 </div>
 
+<div class="editor-row">
+	<div class="section">
+		<h5>Value to text mapping</h5>
+		<div class="editor-option">
+			<label class="small">Specify mappings</label>
+			<div class="grafana-target">
+				<div class="grafana-target-inner">
+					<ul class="grafana-segment-list">
+						<li class="grafana-target-segment"  ng-repeat-start="map in panel.valueMaps">
+							<i class="icon-remove pointer" ng-click="removeValueMap(map)"></i>
+						</li>
+
+						<li>
+							<input type="text" ng-model="map.value" placeholder="value" class="input-mini grafana-target-segment-input" ng-blur="render()">
+						</li>
+						<li class="grafana-target-segment">
+							<i class="icon-arrow-right"></i>
+						</li>
+						<li ng-repeat-end>
+							<input type="text" placeholder="text" ng-model="map.text" class="input-mini grafana-target-segment-input" ng-blur="render()">
+						</li>
+
+						<li>
+							<a class="pointer grafana-target-segment" ng-click="addValueMap();">
+								<i class="icon-plus"></i>
+							</a>
+						</li>
+
+					</ul>
+					<div class="clearfix"></div>
+				</div>
+			</div>
+		</div>
+	</div>
 </div>
 

+ 47 - 7
src/app/panels/singlestat/module.js

@@ -34,9 +34,14 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       format: 'none',
       prefix: '',
       postfix: '',
+      nullText: null,
+      valueMaps: [
+        { value: 'null', op: '=', text: 'N/A' }
+      ],
+      nullPointMode: 'connected',
       valueName: 'avg',
       prefixFontSize: '50%',
-      valueFontSize: '100%',
+      valueFontSize: '80%',
       postfixFontSize: '50%',
       thresholds: '',
       colorBackground: false,
@@ -98,7 +103,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
         alias: seriesData.target,
       });
 
-      series.flotpairs = series.getFlotPairs('connected');
+      series.flotpairs = series.getFlotPairs($scope.panel.nullPointMode);
 
       return series;
     };
@@ -169,15 +174,12 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       if (!$scope.series || $scope.series.length === 0) {
         data.flotpairs = [];
         data.mainValue = Number.NaN;
-        data.mainValueFormated = 'NaN';
+        data.mainValueFormated = $scope.getFormatedValue(null);
       }
       else {
         var series = $scope.series[0];
         data.mainValue = series.stats[$scope.panel.valueName];
-        var decimalInfo = $scope.getDecimalsForValue(data.mainValue);
-        var formatFunc = kbn.valueFormats[$scope.panel.format];
-
-        data.mainValueFormated = formatFunc(data.mainValue, decimalInfo.decimals, decimalInfo.scaledDecimals);
+        data.mainValueFormated = $scope.getFormatedValue(data.mainValue);
         data.flotpairs = series.flotpairs;
       }
 
@@ -191,6 +193,44 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
       $scope.$emit('render');
     };
 
+    $scope.getFormatedValue = function(mainValue) {
+
+      // 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;
+          }
+          continue;
+        }
+        // value/number to text mapping
+        var value = parseFloat(map.value);
+        if (value === mainValue) {
+          return map.text;
+        }
+      }
+
+      if (mainValue === null || mainValue === void 0) {
+        return "no value";
+      }
+
+      var decimalInfo = $scope.getDecimalsForValue(mainValue);
+      var formatFunc = kbn.valueFormats[$scope.panel.format];
+      return formatFunc(mainValue, decimalInfo.decimals, decimalInfo.scaledDecimals);
+    };
+
+    $scope.removeValueMap = function(map) {
+      var index = _.indexOf($scope.panel.valueMaps, map);
+      $scope.panel.valueMaps.splice(index, 1);
+      $scope.render();
+    };
+
+    $scope.addValueMap = function() {
+      $scope.panel.valueMaps.push({value: '', op: '=', text: '' });
+    };
+
     $scope.init();
   });
 });