mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Graph: Adds logarithmic scale option (log base 10), Closes #452
This commit is contained in:
parent
eb8b9c4ac3
commit
d81d0c8c44
@ -7,6 +7,7 @@
|
|||||||
- [Issue #171](https://github.com/grafana/grafana/issues/171). Panel: Different time periods, panels can override dashboard relative time and/or add a time shift
|
- [Issue #171](https://github.com/grafana/grafana/issues/171). Panel: Different time periods, panels can override dashboard relative time and/or add a time shift
|
||||||
- [Issue #1488](https://github.com/grafana/grafana/issues/1488). Dashboard: Clone dashboard / Save as
|
- [Issue #1488](https://github.com/grafana/grafana/issues/1488). Dashboard: Clone dashboard / Save as
|
||||||
- [Issue #1458](https://github.com/grafana/grafana/issues/1458). User: persisted user option for dark or light theme (no longer an option on a dashboard)
|
- [Issue #1458](https://github.com/grafana/grafana/issues/1458). User: persisted user option for dark or light theme (no longer an option on a dashboard)
|
||||||
|
- [Issue #452](https://github.com/grafana/grafana/issues/452). Graph: Adds logarithmic scale option (log base 10)
|
||||||
|
|
||||||
**Enhancements**
|
**Enhancements**
|
||||||
- [Issue #1366](https://github.com/grafana/grafana/issues/1366). Graph & Singlestat: Support for additional units, Fahrenheit (°F) and Celsius (°C), Humidity (%H), kW, watt-hour (Wh), kilowatt-hour (kWh), velocities (m/s, km/h, mpg, knot)
|
- [Issue #1366](https://github.com/grafana/grafana/issues/1366). Graph & Singlestat: Support for additional units, Fahrenheit (°F) and Celsius (°C), Humidity (%H), kW, watt-hour (Wh), kilowatt-hour (kWh), velocities (m/s, km/h, mpg, knot)
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
empty-to-null ng-model="panel.grid.leftMin"
|
empty-to-null ng-model="panel.grid.leftMin"
|
||||||
ng-change="render()" ng-model-onblur>
|
ng-change="render()" ng-model-onblur>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="tight-form-item">
|
||||||
|
Scale type
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<select class="input-small tight-form-input" style="width: 113px" ng-model="panel.grid.leftScale" ng-options="v as k for (k, v) in scaleTypes" ng-change="render()"></select>
|
||||||
|
</li>
|
||||||
<li class="tight-form-item">
|
<li class="tight-form-item">
|
||||||
Label
|
Label
|
||||||
</li>
|
</li>
|
||||||
@ -69,6 +75,12 @@
|
|||||||
empty-to-null ng-model="panel.grid.rightMin"
|
empty-to-null ng-model="panel.grid.rightMin"
|
||||||
ng-change="render()" ng-model-onblur>
|
ng-change="render()" ng-model-onblur>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="tight-form-item">
|
||||||
|
Scale type
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<select class="input-small tight-form-input" style="width: 113px" ng-model="panel.grid.rightScale" ng-options="v as k for (k, v) in scaleTypes" ng-change="render()"></select>
|
||||||
|
</li>
|
||||||
<li class="tight-form-item">
|
<li class="tight-form-item">
|
||||||
Label
|
Label
|
||||||
</li>
|
</li>
|
||||||
|
@ -27,6 +27,7 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
|||||||
var dashboard = scope.dashboard;
|
var dashboard = scope.dashboard;
|
||||||
var data, annotations;
|
var data, annotations;
|
||||||
var sortedSeries;
|
var sortedSeries;
|
||||||
|
var graphHeight;
|
||||||
var legendSideLastValue = null;
|
var legendSideLastValue = null;
|
||||||
scope.crosshairEmiter = false;
|
scope.crosshairEmiter = false;
|
||||||
|
|
||||||
@ -64,19 +65,19 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
|||||||
|
|
||||||
function setElementHeight() {
|
function setElementHeight() {
|
||||||
try {
|
try {
|
||||||
var height = scope.height || scope.panel.height || scope.row.height;
|
graphHeight = scope.height || scope.panel.height || scope.row.height;
|
||||||
if (_.isString(height)) {
|
if (_.isString(graphHeight)) {
|
||||||
height = parseInt(height.replace('px', ''), 10);
|
graphHeight = parseInt(graphHeight.replace('px', ''), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
height -= 5; // padding
|
graphHeight -= 5; // padding
|
||||||
height -= scope.panel.title ? 24 : 9; // subtract panel title bar
|
graphHeight -= scope.panel.title ? 24 : 9; // subtract panel title bar
|
||||||
|
|
||||||
if (scope.panel.legend.show && !scope.panel.legend.rightSide) {
|
if (scope.panel.legend.show && !scope.panel.legend.rightSide) {
|
||||||
height = height - 26; // subtract one line legend
|
graphHeight = graphHeight - 26; // subtract one line legend
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.css('height', height + 'px');
|
elem.css('height', graphHeight + 'px');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch(e) { // IE throws errors sometimes
|
} catch(e) { // IE throws errors sometimes
|
||||||
@ -349,6 +350,8 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
|||||||
position: 'left',
|
position: 'left',
|
||||||
show: scope.panel['y-axis'],
|
show: scope.panel['y-axis'],
|
||||||
min: scope.panel.grid.leftMin,
|
min: scope.panel.grid.leftMin,
|
||||||
|
index: 1,
|
||||||
|
scale: scope.panel.grid.leftScale,
|
||||||
max: scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.leftMax,
|
max: scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.leftMax,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -356,16 +359,59 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
|||||||
|
|
||||||
if (_.findWhere(data, {yaxis: 2})) {
|
if (_.findWhere(data, {yaxis: 2})) {
|
||||||
var secondY = _.clone(defaults);
|
var secondY = _.clone(defaults);
|
||||||
|
secondY.index = 2,
|
||||||
|
secondY.scale = scope.panel.grid.rightScale;
|
||||||
secondY.position = 'right';
|
secondY.position = 'right';
|
||||||
secondY.min = scope.panel.grid.rightMin;
|
secondY.min = scope.panel.grid.rightMin;
|
||||||
secondY.max = scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.rightMax;
|
secondY.max = scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.rightMax;
|
||||||
options.yaxes.push(secondY);
|
options.yaxes.push(secondY);
|
||||||
|
|
||||||
|
applyLogScale(options.yaxes[1], data);
|
||||||
configureAxisMode(options.yaxes[1], scope.panel.y_formats[1]);
|
configureAxisMode(options.yaxes[1], scope.panel.y_formats[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyLogScale(options.yaxes[0], data);
|
||||||
configureAxisMode(options.yaxes[0], scope.panel.y_formats[0]);
|
configureAxisMode(options.yaxes[0], scope.panel.y_formats[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyLogScale(axis, data) {
|
||||||
|
if (axis.scale !== 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var series, i;
|
||||||
|
var max = axis.max;
|
||||||
|
|
||||||
|
if (max === null) {
|
||||||
|
for (i = 0; i < data.length; i++) {
|
||||||
|
series = data[i];
|
||||||
|
if (series.yaxis === axis.index) {
|
||||||
|
if (max < series.stats.max) {
|
||||||
|
max = series.stats.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max === null) {
|
||||||
|
max = 10000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
axis.ticks = [0, 1];
|
||||||
|
var tick = 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
tick = tick*10;
|
||||||
|
axis.ticks.push(tick);
|
||||||
|
if (tick > max) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
axis.transform = function(v) { return Math.log(v+0.1); };
|
||||||
|
axis.inverseTransform = function (v) { return Math.pow(10,v); };
|
||||||
|
}
|
||||||
|
|
||||||
function configureAxisMode(axis, format) {
|
function configureAxisMode(axis, format) {
|
||||||
axis.tickFormatter = function(val, axis) {
|
axis.tickFormatter = function(val, axis) {
|
||||||
return kbn.valueFormats[format](val, axis.tickDecimals, axis.scaledDecimals);
|
return kbn.valueFormats[format](val, axis.tickDecimals, axis.scaledDecimals);
|
||||||
@ -411,44 +457,44 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
|||||||
url += scope.panel['y-axis'] ? '' : '&hideYAxis=true';
|
url += scope.panel['y-axis'] ? '' : '&hideYAxis=true';
|
||||||
|
|
||||||
switch(scope.panel.y_formats[0]) {
|
switch(scope.panel.y_formats[0]) {
|
||||||
case 'bytes':
|
case 'bytes':
|
||||||
url += '&yUnitSystem=binary';
|
url += '&yUnitSystem=binary';
|
||||||
break;
|
break;
|
||||||
case 'bits':
|
case 'bits':
|
||||||
url += '&yUnitSystem=binary';
|
url += '&yUnitSystem=binary';
|
||||||
break;
|
break;
|
||||||
case 'bps':
|
case 'bps':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'Bps':
|
case 'Bps':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'short':
|
case 'short':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'joule':
|
case 'joule':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'watt':
|
case 'watt':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'ev':
|
case 'ev':
|
||||||
url += '&yUnitSystem=si';
|
url += '&yUnitSystem=si';
|
||||||
break;
|
break;
|
||||||
case 'none':
|
case 'none':
|
||||||
url += '&yUnitSystem=none';
|
url += '&yUnitSystem=none';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(scope.panel.nullPointMode) {
|
switch(scope.panel.nullPointMode) {
|
||||||
case 'connected':
|
case 'connected':
|
||||||
url += '&lineMode=connected';
|
url += '&lineMode=connected';
|
||||||
break;
|
break;
|
||||||
case 'null':
|
case 'null':
|
||||||
break; // graphite default lineMode
|
break; // graphite default lineMode
|
||||||
case 'null as zero':
|
case 'null as zero':
|
||||||
url += "&drawNullAsZero=true";
|
url += "&drawNullAsZero=true";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
url += scope.panel.steppedLine ? '&lineMode=staircase' : '';
|
url += scope.panel.steppedLine ? '&lineMode=staircase' : '';
|
||||||
|
@ -99,7 +99,7 @@ function ($) {
|
|||||||
var group, value, timestamp, hoverInfo, i, series, seriesHtml;
|
var group, value, timestamp, hoverInfo, i, series, seriesHtml;
|
||||||
|
|
||||||
if(dashboard.sharedCrosshair){
|
if(dashboard.sharedCrosshair){
|
||||||
scope.appEvent('setCrosshair', { pos: pos, scope: scope });
|
scope.appEvent('setCrosshair', { pos: pos, scope: scope });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seriesList.length === 0) {
|
if (seriesList.length === 0) {
|
||||||
|
@ -53,10 +53,12 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
|||||||
y_formats : ['short', 'short'],
|
y_formats : ['short', 'short'],
|
||||||
// grid options
|
// grid options
|
||||||
grid : {
|
grid : {
|
||||||
|
leftScale: 1,
|
||||||
leftMax: null,
|
leftMax: null,
|
||||||
rightMax: null,
|
rightMax: null,
|
||||||
leftMin: null,
|
leftMin: null,
|
||||||
rightMin: null,
|
rightMin: null,
|
||||||
|
rightScale: 1,
|
||||||
threshold1: null,
|
threshold1: null,
|
||||||
threshold2: null,
|
threshold2: null,
|
||||||
threshold1Color: 'rgba(216, 200, 27, 0.27)',
|
threshold1Color: 'rgba(216, 200, 27, 0.27)',
|
||||||
@ -114,6 +116,8 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
|||||||
_.defaults($scope.panel.grid, _d.grid);
|
_.defaults($scope.panel.grid, _d.grid);
|
||||||
_.defaults($scope.panel.legend, _d.legend);
|
_.defaults($scope.panel.legend, _d.legend);
|
||||||
|
|
||||||
|
$scope.scaleTypes = {'linear': 1, 'log (base 10)': 2};
|
||||||
|
|
||||||
$scope.hiddenSeries = {};
|
$scope.hiddenSeries = {};
|
||||||
$scope.seriesList = [];
|
$scope.seriesList = [];
|
||||||
$scope.unitFormats = kbn.getUnitFormats();
|
$scope.unitFormats = kbn.getUnitFormats();
|
||||||
|
Loading…
Reference in New Issue
Block a user