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

feat(thresholds): adding a new form of thresholds options

Torkel Ödegaard 9 лет назад
Родитель
Сommit
0f8c8517e3

+ 0 - 3
public/app/features/alerting/alert_tab_ctrl.ts

@@ -33,9 +33,6 @@ export class AlertTabCtrl {
   handlers = [{text: 'Grafana', value: 1}, {text: 'External', value: 0}];
   conditionTypes = [
     {text: 'Query', value: 'query'},
-    {text: 'Other alert', value: 'other_alert'},
-    {text: 'Time of day', value: 'time_of_day'},
-    {text: 'Day of week', value: 'day_of_week'},
   ];
   alert: any;
   conditionModels: any;

+ 39 - 11
public/app/plugins/panel/graph/graph.js

@@ -331,23 +331,51 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholds) {
             return;
           }
 
+          var gtLimit = Infinity;
+          var ltLimit = -Infinity;
+
           for (var i = 0; i < panel.thresholds.length; i++) {
             var threshold = panel.thresholds[i];
-            if (!_.isNumber(threshold.from)) {
+            if (!_.isNumber(threshold.value)) {
               continue;
             }
 
-            // fill
-            options.grid.markings.push({
-              yaxis: {from: threshold.from, to: threshold.to},
-              color: 'rgba(234, 112, 112, 0.10)',
-            });
+            var limit;
+            switch(threshold.op) {
+              case '>': {
+                limit = gtLimit;
+                gtLimit = threshold.value;
+                break;
+              }
+              case '<': {
+                limit = ltLimit;
+                ltLimit = threshold.value;
+                break;
+              }
+            }
 
-            // line
-            options.grid.markings.push({
-              yaxis: {from: threshold.from, to: threshold.from},
-              color: '#ed2e18'
-            });
+            var fillColor, lineColor;
+            switch(threshold.severity) {
+              case 'critical': {
+                fillColor = 'rgba(234, 112, 112, 0.12)';
+                lineColor = 'rgba(237, 46, 24, 0.60)';
+                break;
+              }
+              case 'warning': {
+                fillColor = 'rgba(235, 138, 14, 0.12)';
+                lineColor = 'rgba(247, 149, 32, 0.60)';
+                break;
+              }
+              case 'ok': {
+                fillColor = 'rgba(11, 237, 50, 0.090)';
+                lineColor = 'rgba(6,163,69, 0.60)';
+                break;
+              }
+            }
+
+            // fill
+            options.grid.markings.push({yaxis: {from: threshold.value, to: limit}, color: fillColor});
+            options.grid.markings.push({yaxis: {from: threshold.value, to: threshold.value}, color: lineColor});
           }
         }
 

+ 12 - 0
public/app/plugins/panel/graph/module.ts

@@ -26,6 +26,7 @@ class GraphCtrl extends MetricsPanelCtrl {
   datapointsOutside: boolean;
   datapointsWarning: boolean;
   colors: any = [];
+  subTabIndex: number;
 
   panelDefaults = {
     // datasource name, null = default datasource
@@ -142,7 +143,9 @@ class GraphCtrl extends MetricsPanelCtrl {
       'log (base 32)': 32,
       'log (base 1024)': 1024
     };
+
     this.unitFormats = kbn.getUnitFormats();
+    this.subTabIndex = 0;
   }
 
   onInitPanelActions(actions) {
@@ -323,6 +326,15 @@ class GraphCtrl extends MetricsPanelCtrl {
   exportCsvColumns() {
     fileExport.exportSeriesListToCsvColumns(this.seriesList);
   }
+
+  addThreshold() {
+    this.panel.thresholds.push({value: undefined, color: "rgba(255,0,0,0.2)"});
+  }
+
+  removeThreshold(index) {
+    this.panel.thresholds.splice(index, 1);
+    this.render();
+  }
 }
 
 export {GraphCtrl, GraphCtrl as PanelCtrl}

+ 138 - 94
public/app/plugins/panel/graph/tab_display.html

@@ -1,103 +1,103 @@
-<div class="editor-row">
-  <div class="section gf-form-group">
-    <h5 class="section-heading">Draw Modes</h5>
-		<gf-form-switch class="gf-form"
-			label="Bars" label-class="width-5"
-			checked="ctrl.panel.bars" on-change="ctrl.render()">
-		</gf-form-switch>
-		<gf-form-switch class="gf-form"
-			label="Lines" label-class="width-5"
-			checked="ctrl.panel.lines" on-change="ctrl.render()">
-		</gf-form-switch>
-		<gf-form-switch class="gf-form"
-			label="Points" label-class="width-5"
-			checked="ctrl.panel.points" on-change="ctrl.render()">
-		</gf-form-switch>
-	</div>
-	<div class="section gf-form-group">
-		<h5 class="section-heading">Mode Options</h5>
-		<div class="gf-form" ng-show="ctrl.panel.lines">
-			<label class="gf-form-label width-8">Fill</label>
-			<div class="gf-form-select-wrapper max-width-5">
-				<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
-			</div>
+<div class="edit-tab-with-sidemenu">
+	<aside class="edit-sidemenu-aside">
+		<ul class="edit-sidemenu">
+			<li ng-class="{active: ctrl.subTabIndex === 0}">
+				<a ng-click="ctrl.subTabIndex = 0">Draw options</a>
+			</li>
+			<li ng-class="{active: ctrl.subTabIndex === 1}">
+				<a ng-click="ctrl.subTabIndex = 1">
+					Series overrides <span class="muted">({{ctrl.panel.seriesOverrides.length}})</span>
+				</a>
+			</li>
+			<li ng-class="{active: ctrl.subTabIndex === 2}">
+				<a ng-click="ctrl.subTabIndex = 2">Thresholds</a>
+			</li>
+		</ul>
+	</aside>
+
+	<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 0">
+		<div class="section gf-form-group">
+			<h5 class="section-heading">Draw Modes</h5>
+			<gf-form-switch class="gf-form" label="Bars" label-class="width-5" checked="ctrl.panel.bars" on-change="ctrl.render()"></gf-form-switch>
+			<gf-form-switch class="gf-form" label="Lines" label-class="width-5" checked="ctrl.panel.lines" on-change="ctrl.render()"></gf-form-switch>
+			<gf-form-switch class="gf-form" label="Points" label-class="width-5" checked="ctrl.panel.points" on-change="ctrl.render()"></gf-form-switch>
 		</div>
-		<div class="gf-form" ng-show="ctrl.panel.lines">
-			<label class="gf-form-label width-8">Line Width</label>
-			<div class="gf-form-select-wrapper max-width-5">
-				<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
+		<div class="section gf-form-group">
+			<h5 class="section-heading">Mode Options</h5>
+			<div class="gf-form" ng-show="ctrl.panel.lines">
+				<label class="gf-form-label width-8">Fill</label>
+				<div class="gf-form-select-wrapper max-width-5">
+					<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
-		</div>
-		<gf-form-switch ng-show="ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
-		</gf-form-switch>
-		<div class="gf-form" ng-show="ctrl.panel.points">
-			<label class="gf-form-label width-8">Point Radius</label>
-			<div class="gf-form-select-wrapper max-width-5">
-				<select class="gf-form-input" ng-model="ctrl.panel.pointradius" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
+			<div class="gf-form" ng-show="ctrl.panel.lines">
+				<label class="gf-form-label width-8">Line Width</label>
+				<div class="gf-form-select-wrapper max-width-5">
+					<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
-		</div>
-	</div>
-	<div class="section gf-form-group">
-		<h5 class="section-heading">Hover info</h5>
-		<div class="gf-form">
-			<label class="gf-form-label width-9">Mode</label>
-			<div class="gf-form-select-wrapper max-width-8">
-				<select class="gf-form-input" ng-model="ctrl.panel.tooltip.shared" ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]" ng-change="ctrl.render()"></select>
+			<gf-form-switch ng-show="ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
+			</gf-form-switch>
+			<div class="gf-form" ng-show="ctrl.panel.points">
+				<label class="gf-form-label width-8">Point Radius</label>
+				<div class="gf-form-select-wrapper max-width-5">
+					<select class="gf-form-input" ng-model="ctrl.panel.pointradius" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
 		</div>
-		<div class="gf-form">
-			<label class="gf-form-label width-9">Sort order</label>
-			<div class="gf-form-select-wrapper max-width-8">
-				<select class="gf-form-input" ng-model="ctrl.panel.tooltip.sort" ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]" ng-change="ctrl.render()"></select>
+		<div class="section gf-form-group">
+			<h5 class="section-heading">Hover info</h5>
+			<div class="gf-form">
+				<label class="gf-form-label width-9">Mode</label>
+				<div class="gf-form-select-wrapper max-width-8">
+					<select class="gf-form-input" ng-model="ctrl.panel.tooltip.shared" ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
-		</div>
-		<div class="gf-form" ng-show="ctrl.panel.stack">
-			<label class="gf-form-label width-9">Stacked value</label>
-			<div class="gf-form-select-wrapper max-width-8">
-				<select class="gf-form-input" ng-model="ctrl.panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="ctrl.render()"></select>
+			<div class="gf-form">
+				<label class="gf-form-label width-9">Sort order</label>
+				<div class="gf-form-select-wrapper max-width-8">
+					<select class="gf-form-input" ng-model="ctrl.panel.tooltip.sort" ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]" ng-change="ctrl.render()"></select>
+				</div>
+			</div>
+			<div class="gf-form" ng-show="ctrl.panel.stack">
+				<label class="gf-form-label width-9">Stacked value</label>
+				<div class="gf-form-select-wrapper max-width-8">
+					<select class="gf-form-input" ng-model="ctrl.panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
 		</div>
-	</div>
 
-	<div class="section gf-form-group">
-		<h5 class="section-heading">Stacking & Null value</h5>
-		<gf-form-switch class="gf-form"
-			label="Stack" label-class="width-7"
-			checked="ctrl.panel.stack" on-change="ctrl.render()">
-		</gf-form-switch>
-		<gf-form-switch class="gf-form" ng-show="ctrl.panel.stack"
-			label="Percent" label-class="width-7"
-			checked="ctrl.panel.percentage" on-change="ctrl.render()">
-		</gf-form-switch>
-		<div class="gf-form">
-			<label class="gf-form-label width-7">Null value</label>
-			<div class="gf-form-select-wrapper">
-				<select class="gf-form-input max-width-8" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="ctrl.render()"></select>
+		<div class="section gf-form-group">
+			<h5 class="section-heading">Stacking & Null value</h5>
+			<gf-form-switch class="gf-form"
+									 label="Stack" label-class="width-7"
+												checked="ctrl.panel.stack" on-change="ctrl.render()">
+			</gf-form-switch>
+			<gf-form-switch class="gf-form" ng-show="ctrl.panel.stack"
+																	 label="Percent" label-class="width-7"
+																	checked="ctrl.panel.percentage" on-change="ctrl.render()">
+			</gf-form-switch>
+			<div class="gf-form">
+				<label class="gf-form-label width-7">Null value</label>
+				<div class="gf-form-select-wrapper">
+					<select class="gf-form-input max-width-8" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="ctrl.render()"></select>
+				</div>
 			</div>
 		</div>
 	</div>
 
-</div>
-
-<div class="editor-row">
-	<div class="section gf-form-group">
-		<h5>Series specific overrides <tip>Regex match example: /server[0-3]/i </tip></h5>
-		<div class="tight-form-container">
-			<div class="tight-form" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
-				<ul class="tight-form-list">
-					<li class="tight-form-item">
-						<i class="fa fa-remove pointer" ng-click="ctrl.removeSeriesOverride(override)"></i>
-					</li>
-
-					<li class="tight-form-item">
-						alias or regex
-					</li>
-
-					<li>
-						<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="ctrl.render()" data-min-length=0 data-items=100 class="input-medium tight-form-input" >
-					</li>
-
-					<li class="tight-form-item" ng-repeat="option in currentOverrides">
+	<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 1">
+		<div class="gf-form-group">
+			<h5>Series specific overrides <tip>Regex match example: /server[0-3]/i </tip></h5>
+			<div class="gf-form-inline" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
+				<div class="gf-form">
+					<label class="gf-form-label">alias or regex</label>
+				</div>
+				<div class="gf-form width-15">
+					<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="ctrl.render()" data-min-length=0 data-items=100 class="gf-form-input width-15">
+				</div>
+				<div class="gf-form" ng-repeat="option in currentOverrides">
+					<label class="gf-form-label">
 						<i class="pointer fa fa-remove" ng-click="removeOverride(option)"></i>
 						<span ng-show="option.propertyName === 'color'">
 							Color: <i class="fa fa-circle" ng-style="{color:option.value}"></i>
@@ -105,17 +105,61 @@
 						<span ng-show="option.propertyName !== 'color'">
 							{{option.name}}: {{option.value}}
 						</span>
-					</li>
+					</label>
+				</div>
+
+				<div class="gf-form">
+					<span class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
+					</span>
+				</div>
+
+				<div class="gf-form gf-form--grow">
+					<div class="gf-form-label gf-form-label--grow"></div>
+				</div>
+
+				<div class="gf-form">
+					<label class="gf-form-label">
+						<i class="fa fa-trash pointer" ng-click="ctrl.removeSeriesOverride(override)"></i>
+					</label>
+				</div>
+			</div>
+		</div>
 
-					<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
-					</li>
-				</ul>
-				<div class="clearfix"></div>
+		<button class="btn btn-inverse" ng-click="ctrl.addSeriesOverride()">
+			<i class="fa fa-plus"></i>&nbsp;Add override
+		</button>
+	</div>
+
+	<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 2">
+		<div class="gf-form-group">
+			<h5>Thresholds</h5>
+			<div class="gf-form-inline" ng-repeat="threshold in ctrl.panel.thresholds">
+				<div class="gf-form">
+					<label class="gf-form-label">T{{$index+1}}</label>
+				</div>
+
+				<div class="gf-form">
+					<div class="gf-form-select-wrapper">
+						<select class="gf-form-input" ng-model="threshold.op" ng-options="f for f in ['>', '<']" ng-change="ctrl.render()"></select>
+					</div>
+					<input type="number" ng-model="threshold.value" class="gf-form-input width-8" ng-change="ctrl.render()" placeholder="value">
+					<label class="gf-form-label">Color</label>
+					<div class="gf-form-select-wrapper">
+						<select class="gf-form-input" ng-model="threshold.severity" ng-options="f for f in ['critical', 'warning', 'ok']" ng-change="ctrl.render()"></select>
+					</div>
+				</div>
+
+				<div class="gf-form">
+					<label class="gf-form-label">
+						<i class="fa fa-trash pointer" ng-click="ctrl.removeThreshold($index)"></i>
+					</label>
+				</div>
 			</div>
 		</div>
 
-		<button class="btn btn-inverse" style="margin-top: 20px" ng-click="ctrl.addSeriesOverride()">
-			Add series specific option
+		<button class="btn btn-inverse" ng-click="ctrl.addThreshold()">
+			<i class="fa fa-plus"></i>&nbsp;Add Threshold
 		</button>
 	</div>
+
 </div>