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

This commit is contained in:
Torkel Ödegaard
2016-08-10 15:27:33 +02:00
parent 4fd8b2ace4
commit 0f8c8517e3
4 changed files with 194 additions and 113 deletions

View File

@@ -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;

View File

@@ -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});
}
}

View File

@@ -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}

View File

@@ -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 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="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 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>
<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" 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">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 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>
<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="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 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 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 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 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>
<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
</li>
</ul>
<div class="clearfix"></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>
<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.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" ng-click="ctrl.addThreshold()">
<i class="fa fa-plus"></i>&nbsp;Add Threshold
</button>
</div>
</div>