diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts index 4563a09cbca..e5d6c342fd0 100644 --- a/public/app/core/time_series2.ts +++ b/public/app/core/time_series2.ts @@ -100,6 +100,7 @@ export default class TimeSeries { this.stats.total = 0; this.stats.max = -Number.MAX_VALUE; this.stats.min = Number.MAX_VALUE; + this.stats.logmin = Number.MAX_VALUE; this.stats.avg = null; this.stats.current = null; this.stats.first = null; @@ -172,6 +173,11 @@ export default class TimeSeries { } } previousValue = currentValue; + + if (currentValue < this.stats.logmin && currentValue > 0) { + this.stats.logmin = currentValue; + } + } if (currentValue !== 0) { diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 3b120edcd4a..69028a9e407 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -485,42 +485,59 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv) { if (axis.logBase === 1) { return; } + if (axis.min < Number.MIN_VALUE) { + axis.min = null; + } + if (axis.max < Number.MIN_VALUE) { + axis.max = null; + } var series, i; - var max = axis.max; + var max = axis.max, min = axis.min; - 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; - } + for (i = 0; i < data.length; i++) { + series = data[i]; + if (series.yaxis === axis.index) { + if (max === null || max < series.stats.max) { + max = series.stats.max; + } + if (min === null || min > series.stats.logmin) { + min = series.stats.logmin; } } - if (max === void 0) { - max = Number.MAX_VALUE; - } } - axis.min = axis.min !== null ? axis.min : 0; - axis.ticks = [0, 1]; - var nextTick = 1; + axis.transform = function(v) { return (v < Number.MIN_VALUE) ? null : Math.log(v) / Math.log(axis.logBase); }; + axis.inverseTransform = function (v) { return Math.pow(axis.logBase,v); }; - while (true) { - nextTick = nextTick * axis.logBase; - axis.ticks.push(nextTick); - if (nextTick > max) { - break; - } + if (max === null && min === null) { + max = axis.inverseTransform(+2); + min = axis.inverseTransform(-2); + } else if (max === null) { + max = min*axis.inverseTransform(+4); + } else if (min === null) { + min = max*axis.inverseTransform(-4); } - if (axis.logBase === 10) { - axis.transform = function(v) { return Math.log(v+0.1); }; - axis.inverseTransform = function (v) { return Math.pow(10,v); }; + if (axis.min !== null) { + min = axis.inverseTransform(Math.ceil(axis.transform(axis.min))); } else { - axis.transform = function(v) { return Math.log(v+0.1) / Math.log(axis.logBase); }; - axis.inverseTransform = function (v) { return Math.pow(axis.logBase,v); }; + min = axis.min = axis.inverseTransform(Math.floor(axis.transform(min))); + } + if (axis.max !== null) { + max = axis.inverseTransform(Math.floor(axis.transform(axis.max))); + } else { + max = axis.max = axis.inverseTransform(Math.ceil(axis.transform(max))); + } + + if (min < Number.MIN_VALUE || max < Number.MIN_VALUE) { + return; + } + + axis.ticks = []; + var nextTick; + for (nextTick = min; nextTick <= max; nextTick *= axis.logBase) { + axis.ticks.push(nextTick); } } diff --git a/public/app/plugins/panel/graph/specs/graph_specs.ts b/public/app/plugins/panel/graph/specs/graph_specs.ts index 5578b3a361e..fd958a7fe23 100644 --- a/public/app/plugins/panel/graph/specs/graph_specs.ts +++ b/public/app/plugins/panel/graph/specs/graph_specs.ts @@ -113,15 +113,38 @@ describe('grafanaGraph', function() { }); graphScenario('when logBase is log 10', function(ctx) { - ctx.setup(function(ctrl) { + ctx.setup(function(ctrl, data) { ctrl.panel.yaxes[0].logBase = 10; + data[0] = new TimeSeries({ + datapoints: [[2000,1],[0.002,2],[0,3],[-1,4]], + alias: 'seriesAutoscale', + }); + data[0].yaxis = 1; + ctrl.panel.yaxes[1].logBase = 10; + ctrl.panel.yaxes[1].min = 0.05; + ctrl.panel.yaxes[1].max = 1500; + data[1] = new TimeSeries({ + datapoints: [[2000,1],[0.002,2],[0,3],[-1,4]], + alias: 'seriesFixedscale', + }); + data[1].yaxis = 2; }); - it('should apply axis transform and ticks', function() { - var axis = ctx.plotOptions.yaxes[0]; - expect(axis.transform(100)).to.be(Math.log(100+0.1)); - expect(axis.ticks[0]).to.be(0); - expect(axis.ticks[1]).to.be(1); + it('should apply axis transform, autoscaling (if necessary) and ticks', function() { + var axisAutoscale = ctx.plotOptions.yaxes[0]; + expect(axisAutoscale.transform(100)).to.be(2); + expect(axisAutoscale.inverseTransform(-3)).to.be(0.001); + expect(axisAutoscale.min).to.be(0.001); + expect(axisAutoscale.max).to.be(10000); + expect(axisAutoscale.ticks.length).to.be(8); + expect(axisAutoscale.ticks[0]).to.be(0.001); + expect(axisAutoscale.ticks[7]).to.be(10000); + var axisFixedscale = ctx.plotOptions.yaxes[1]; + expect(axisFixedscale.min).to.be(0.05); + expect(axisFixedscale.max).to.be(1500); + expect(axisFixedscale.ticks.length).to.be(5); + expect(axisFixedscale.ticks[0]).to.be(0.1); + expect(axisFixedscale.ticks[4]).to.be(1000); }); });