Major reworking of the graph axis editor tab
This commit is contained in:
@@ -485,5 +485,33 @@ function($, _, moment) {
|
|||||||
return new RegExp(match[1], match[2]);
|
return new RegExp(match[1], match[2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kbn.getUnitFormats = function() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
text: 'none',
|
||||||
|
submenu: [
|
||||||
|
{text: 'none' , value: 'none'},
|
||||||
|
{text: 'short', value: 'short'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'duration',
|
||||||
|
submenu: [
|
||||||
|
{text: 'nanoseconds (ns)' , value: 'ns'},
|
||||||
|
{text: 'microseconds (µs)', value: 'µs'},
|
||||||
|
{text: 'milliseconds (ms)', value: 'ms'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'data',
|
||||||
|
submenu: [
|
||||||
|
{text: 'bit', value: 'bit'},
|
||||||
|
{text: 'bytes', value: 'bytes'},
|
||||||
|
{text: 'kilobytes', value: 'kbytes'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
return kbn;
|
return kbn;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,35 +17,47 @@ function (angular, app, _, $) {
|
|||||||
|
|
||||||
var buttonTemplate = '<a class="grafana-target-segment grafana-target-function dropdown-toggle"' +
|
var buttonTemplate = '<a class="grafana-target-segment grafana-target-function dropdown-toggle"' +
|
||||||
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
||||||
' data-placement="top"><i class="icon-plus"></i></a>';
|
' data-placement="top"><i class="fa fa-plus"></i></a>';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scope: {
|
scope: {
|
||||||
"menuItems": "=dropdownTypeahead",
|
menuItems: "=dropdownTypeahead",
|
||||||
"dropdownTypeaheadOnSelect": "&dropdownTypeaheadOnSelect"
|
dropdownTypeaheadOnSelect: "&dropdownTypeaheadOnSelect",
|
||||||
|
model: '=ngModel'
|
||||||
},
|
},
|
||||||
link: function($scope, elem) {
|
link: function($scope, elem, attrs) {
|
||||||
var $input = $(inputTemplate);
|
var $input = $(inputTemplate);
|
||||||
var $button = $(buttonTemplate);
|
var $button = $(buttonTemplate);
|
||||||
$input.appendTo(elem);
|
$input.appendTo(elem);
|
||||||
$button.appendTo(elem);
|
$button.appendTo(elem);
|
||||||
|
|
||||||
var typeaheadValues = _.reduce($scope.menuItems, function(memo, value) {
|
if (attrs.linkText) {
|
||||||
_.each(value.submenu, function(item) {
|
$button.html(attrs.linkText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.ngModel) {
|
||||||
|
$scope.$watch('model', function(newValue) {
|
||||||
|
_.each($scope.menuItems, function(item){
|
||||||
|
_.each(item.submenu, function(subItem) {
|
||||||
|
if (subItem.value === newValue) {
|
||||||
|
$button.html(subItem.text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeaheadValues = _.reduce($scope.menuItems, function(memo, value, index) {
|
||||||
|
_.each(value.submenu, function(item, subIndex) {
|
||||||
|
item.click = 'menuItemSelected(' + index + ',' + subIndex + ')';
|
||||||
memo.push(value.text + ' ' + item.text);
|
memo.push(value.text + ' ' + item.text);
|
||||||
});
|
});
|
||||||
return memo;
|
return memo;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
$scope.menuItemSelected = function(optionIndex, valueIndex) {
|
$scope.menuItemSelected = function(index, subIndex) {
|
||||||
var option = $scope.menuItems[optionIndex];
|
var item = $scope.menuItems[index];
|
||||||
var result = {
|
$scope.dropdownTypeaheadOnSelect({$item: item, $subItem: item.submenu[subIndex]});
|
||||||
$item: option.submenu[valueIndex],
|
|
||||||
$optionIndex: optionIndex,
|
|
||||||
$valueIndex: valueIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.dropdownTypeaheadOnSelect(result);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$input.attr('data-provide', 'typeahead');
|
$input.attr('data-provide', 'typeahead');
|
||||||
@@ -55,12 +67,11 @@ function (angular, app, _, $) {
|
|||||||
items: 10,
|
items: 10,
|
||||||
updater: function (value) {
|
updater: function (value) {
|
||||||
var result = {};
|
var result = {};
|
||||||
_.each($scope.menuItems, function(menuItem, optionIndex) {
|
_.each($scope.menuItems, function(menuItem) {
|
||||||
_.each(menuItem.submenu, function(submenuItem, valueIndex) {
|
_.each(menuItem.submenu, function(submenuItem) {
|
||||||
if (value === (menuItem.text + ' ' + submenuItem.text)) {
|
if (value === (menuItem.text + ' ' + submenuItem.text)) {
|
||||||
result.$item = submenuItem;
|
result.$item = menuItem;
|
||||||
result.$optionIndex = optionIndex;
|
result.$subItem = submenuItem;
|
||||||
result.$valueIndex = valueIndex;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,90 +1,160 @@
|
|||||||
|
|
||||||
<div class="editor-row">
|
<div class="editor-row">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h5>Left Y Axis</h5>
|
<div class="grafana-target">
|
||||||
<div class="editor-option">
|
<div class="grafana-target-inner">
|
||||||
<label class="small">Format <tip>Y-axis formatting</tip></label>
|
<ul class="grafana-segment-list">
|
||||||
<select class="input-small" ng-model="panel.y_formats[0]" ng-options="f for f in ['none','short','bytes', 'kbytes', 'mbytes', 'bits', 'bps', 'Bps', 's', 'ms', 'µs', 'ns', 'percent', 'joule', 'watt', 'ev']" ng-change="render()"></select>
|
<li class="grafana-target-segment" style="width: 90px">
|
||||||
</div>
|
<strong>Left Y Axis</strong>
|
||||||
<div class="editor-option">
|
</li>
|
||||||
<label class="small">Min / <a ng-click="toggleGridMinMax('leftMin')">Auto <i class="fa fa-star" ng-show="_.isNull(panel.grid.leftMin)"></i></a></label>
|
<li class="grafana-target-segment">
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.leftMin" ng-change="render()" ng-model-onblur />
|
Unit
|
||||||
</div>
|
</li>
|
||||||
<div class="editor-option">
|
<li class="dropdown" style="width: 150px;"
|
||||||
<label class="small">Max / <a ng-click="toggleGridMinMax('leftMax')">Auto <i class="fa fa-star" ng-show="_.isNull(panel.grid.leftMax)"></i></a></label>
|
ng-model="panel.y_formats[0]"
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.leftMax" ng-change="render()" ng-model-onblur />
|
dropdown-typeahead="unitFormats"
|
||||||
</div>
|
dropdown-typeahead-on-select="setUnitFormat(0, $subItem)">
|
||||||
<div class="editor-option">
|
</li>
|
||||||
<label class="small">Label</label>
|
<li class="grafana-target-segment">
|
||||||
<input ng-change="render()" ng-model-onblur placeholder="" type="text" class="input-medium" ng-model="panel.leftYAxisLabel">
|
Grid Max
|
||||||
</div>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
<div class="section">
|
<input type="text" class="input-small grafana-target-segment-input" placeholder="auto">
|
||||||
<h5>Right Y Axis</h5>
|
</li>
|
||||||
<div class="editor-option">
|
<li class="grafana-target-segment">
|
||||||
<label class="small">Format <tip>Y-axis formatting</tip></label>
|
Min
|
||||||
<select class="input-small" ng-model="panel.y_formats[0]" ng-options="f for f in ['none','short','bytes', 'kbytes', 'mbytes', 'bits', 'bps', 'Bps', 's', 'ms', 'µs', 'ns', 'percent', 'joule', 'watt', 'ev']" ng-change="render()"></select>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
<div class="editor-option">
|
<input type="text" class="input-small grafana-target-segment-input" placeholder="auto">
|
||||||
<label class="small">Min / <a ng-click="toggleGridMinMax('rightMin')">Auto <i class="fa fa-star" ng-show="_.isNull(panel.grid.rightMin)"></i></a></label>
|
</li>
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.rightMin" ng-change="render()" ng-model-onblur />
|
<li class="grafana-target-segment">
|
||||||
</div>
|
Label
|
||||||
<div class="editor-option">
|
</li>
|
||||||
<label class="small">Max / <a ng-click="toggleGridMinMax('rightMax')">Auto <i class="fa fa-star" ng-show="_.isNull(panel.grid.rightMax)"></i></a></label>
|
<li>
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.rightMax" ng-change="render()" ng-model-onblur />
|
<input type="text" class="input-small grafana-target-segment-input" value="">
|
||||||
</div>
|
</li>
|
||||||
<div class="editor-option">
|
<li class="grafana-target-segment">
|
||||||
<label class="small">Label</label>
|
Show
|
||||||
<input ng-change="render()" ng-model-onblur placeholder="" type="text" class="input-medium" ng-model="panel.rightYAxisLabel">
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="grafana-target-inner">
|
||||||
|
<ul class="grafana-segment-list">
|
||||||
<div class="editor-row">
|
<li class="grafana-target-segment" style="width: 90px">
|
||||||
<div class="section">
|
<strong>Right Y Axis</strong>
|
||||||
<h5>Legend styles</h5>
|
</li>
|
||||||
<editor-opt-bool text="Show" model="panel.legend.show" change="get_data();"></editor-opt-bool>
|
<li class="grafana-target-segment">
|
||||||
<editor-opt-bool text="Values" model="panel.legend.values" change="render()"></editor-opt-bool>
|
Unit
|
||||||
<editor-opt-bool text="Table" model="panel.legend.alignAsTable" change="render()"></editor-opt-bool>
|
</li>
|
||||||
<editor-opt-bool text="Right side" model="panel.legend.rightSide" change="render()"></editor-opt-bool>
|
<li class="dropdown" style="width: 150px"
|
||||||
<editor-opt-bool text="Hide empty" model="panel.legend.hideEmpty" tip="Hides series with only null values" change="render()"></editor-opt-bool>
|
ng-model="panel.y_formats[1]"
|
||||||
|
dropdown-typeahead="unitFormats"
|
||||||
|
dropdown-typeahead-on-select="setUnitFormat(1, $subItem)">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Grid Max
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" class="input-small grafana-target-segment-input" placeholder="auto">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Min
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" class="input-small grafana-target-segment-input" placeholder="auto">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Label
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" class="input-small grafana-target-segment-input" value="">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Show
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section" ng-if="panel.legend.values">
|
|
||||||
<h5>Legend values</h5>
|
|
||||||
<editor-opt-bool text="Min" model="panel.legend.min" change="render()"></editor-opt-bool>
|
|
||||||
<editor-opt-bool text="Max" model="panel.legend.max" change="render()"></editor-opt-bool>
|
|
||||||
<editor-opt-bool text="Current" model="panel.legend.current" change="render()"></editor-opt-bool>
|
|
||||||
<editor-opt-bool text="Total" model="panel.legend.total" change="render()"></editor-opt-bool>
|
|
||||||
<editor-opt-bool text="Avg" model="panel.legend.avg" change="render()"></editor-opt-bool>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<h5>Grid thresholds</h5>
|
|
||||||
<div class="editor-option">
|
|
||||||
<label class="small">Level1</label>
|
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.threshold1" ng-change="render()" ng-model-onblur />
|
|
||||||
</div>
|
|
||||||
<div class="editor-option">
|
|
||||||
<label class="small">Color</label>
|
|
||||||
<spectrum-picker ng-model="panel.grid.threshold1Color" ng-change="render()" ></spectrum-picker>
|
|
||||||
</div>
|
|
||||||
<div class="editor-option">
|
|
||||||
<label class="small">Level2</label>
|
|
||||||
<input type="number" class="input-small" ng-model="panel.grid.threshold2" ng-change="render()" ng-model-onblur />
|
|
||||||
</div>
|
|
||||||
<div class="editor-option">
|
|
||||||
<label class="small">Color</label>
|
|
||||||
<spectrum-picker ng-model="panel.grid.threshold2Color" ng-change="render()" ></spectrum-picker>
|
|
||||||
</div>
|
|
||||||
<editor-opt-bool text="Line mode" model="panel.grid.thresholdLine" change="render()"></editor-opt-bool>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<h5>Show Axes</h5>
|
|
||||||
<editor-opt-bool text="X-Axis" model="panel['x-axis']" change="render()"></editor-opt-bool>
|
|
||||||
<editor-opt-bool text="Y-axis" model="panel['y-axis']" change="render()"></editor-opt-bool>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="editor-row" style="margin-top: 20px">
|
||||||
|
<div class="section">
|
||||||
|
<div class="grafana-target">
|
||||||
|
<div class="grafana-target-inner">
|
||||||
|
<ul class="grafana-segment-list">
|
||||||
|
<li class="grafana-target-segment" style="width: 90px">
|
||||||
|
<strong>Thresholds</strong>
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Level 1
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" class="input-small grafana-target-segment-input">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
<spectrum-picker ng-model="panel.grid.threshold1Color" ng-change="render()" ></spectrum-picker>
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Level 2
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" class="input-small grafana-target-segment-input">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
<spectrum-picker ng-model="panel.grid.threshold1Color" ng-change="render()" ></spectrum-picker>
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Line mode
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="editor-row" style="margin-top: 20px">
|
||||||
|
<div class="section">
|
||||||
|
<div class="grafana-target">
|
||||||
|
<div class="grafana-target-inner">
|
||||||
|
<ul class="grafana-segment-list">
|
||||||
|
<li class="grafana-target-segment" style="width: 90px">
|
||||||
|
<strong>Legend</strong>
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Show: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Table: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Right side: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Hide empty: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Min: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Max: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Avg: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Total: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
<li class="grafana-target-segment">
|
||||||
|
Current: <input type="checkbox">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,12 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
|||||||
|
|
||||||
$scope.hiddenSeries = {};
|
$scope.hiddenSeries = {};
|
||||||
$scope.seriesList = [];
|
$scope.seriesList = [];
|
||||||
|
$scope.unitFormats = kbn.getUnitFormats();
|
||||||
|
|
||||||
|
$scope.setUnitFormat = function(axis, subItem) {
|
||||||
|
$scope.panel.y_formats[axis] = subItem.value;
|
||||||
|
$scope.render();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.updateTimeRange = function () {
|
$scope.updateTimeRange = function () {
|
||||||
$scope.range = timeSrv.timeRange();
|
$scope.range = timeSrv.timeRange();
|
||||||
|
|||||||
@@ -20,26 +20,21 @@ define([
|
|||||||
option.index = $scope.overrideMenu.length;
|
option.index = $scope.overrideMenu.length;
|
||||||
option.values = values;
|
option.values = values;
|
||||||
|
|
||||||
option.submenu = _.map(values, function(value, index) {
|
option.submenu = _.map(values, function(value) {
|
||||||
return {
|
return { text: String(value), value: value };
|
||||||
text: String(value),
|
|
||||||
click: 'menuItemSelected(' + option.index + ',' + index + ')'
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.overrideMenu.push(option);
|
$scope.overrideMenu.push(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.setOverride = function(optionIndex, valueIndex) {
|
$scope.setOverride = function(item, subItem) {
|
||||||
var option = $scope.overrideMenu[optionIndex];
|
$scope.override[item.propertyName] = subItem.value;
|
||||||
var value = option.values[valueIndex];
|
|
||||||
$scope.override[option.propertyName] = value;
|
|
||||||
|
|
||||||
// automatically disable lines for this series and the fill bellow to series
|
// automatically disable lines for this series and the fill bellow to series
|
||||||
// can be removed by the user if they still want lines
|
// can be removed by the user if they still want lines
|
||||||
if (option.propertyName === 'fillBelowTo') {
|
if (item.propertyName === 'fillBelowTo') {
|
||||||
$scope.override['lines'] = false;
|
$scope.override['lines'] = false;
|
||||||
$scope.addSeriesOverride({ alias: value, lines: false });
|
$scope.addSeriesOverride({ alias: subItem.value, lines: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.updateCurrentOverrides();
|
$scope.updateCurrentOverrides();
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
{{option.name}}: {{option.value}}
|
{{option.name}}: {{option.value}}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($optionIndex, $valueIndex)">
|
<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -39,13 +39,7 @@
|
|||||||
<h5>Formats</h5>
|
<h5>Formats</h5>
|
||||||
<div class="editor-option">
|
<div class="editor-option">
|
||||||
<label class="small">Unit format</label>
|
<label class="small">Unit format</label>
|
||||||
<<<<<<< HEAD
|
<select class="input-small" ng-model="panel.format" ng-options="f for f in ['none','short','bytes', 'bits', 'Bps', bps', 's', 'ms', 'µs', 'ns', 'percent', 'joule', 'watt', 'ev']" ng-change="render()"></select>
|
||||||
<select class="input-small" ng-model="panel.format" ng-options="f for f in ['none','short','bytes', 'bits', 'bps', 's', 'ms', 'µs', 'ns', 'percent', 'joule', 'watt', 'ev']" ng-change="render()"></select>
|
|
||||||
||||||| merged common ancestors
|
|
||||||
<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>
|
|
||||||
=======
|
|
||||||
<select class="input-small" ng-model="panel.format" ng-options="f for f in ['none','short','bytes', 'bits', 'Bps', bps', 's', 'ms', 'µs', 'ns', 'percent']" ng-change="render()"></select>
|
|
||||||
>>>>>>> 09a0ef2013eecb12864b71ea324e645576049a56
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user