Commit 296a8416 by Marcus Efraimsson Committed by GitHub

Merge pull request #12123 from alexanderzobnin/fix-11792

graph: fix legend decimals precision calculation
parents ae07fc29 24f6d34a
import * as ticks from '../utils/ticks';
describe('ticks', () => {
describe('getFlotTickDecimals()', () => {
let ctx: any = {};
beforeEach(() => {
ctx.axis = {};
});
it('should calculate decimals precision based on graph height', () => {
let dec = ticks.getFlotTickDecimals(0, 10, ctx.axis, 200);
expect(dec.tickDecimals).toBe(1);
expect(dec.scaledDecimals).toBe(1);
dec = ticks.getFlotTickDecimals(0, 100, ctx.axis, 200);
expect(dec.tickDecimals).toBe(0);
expect(dec.scaledDecimals).toBe(-1);
dec = ticks.getFlotTickDecimals(0, 1, ctx.axis, 200);
expect(dec.tickDecimals).toBe(2);
expect(dec.scaledDecimals).toBe(3);
});
});
});
import TimeSeries from 'app/core/time_series2';
import { updateLegendValues } from 'app/core/time_series2';
describe('TimeSeries', function() {
var points, series;
......@@ -311,4 +312,55 @@ describe('TimeSeries', function() {
expect(series.formatValue(-Infinity)).toBe('');
});
});
describe('legend decimals', function() {
let series, panel;
let height = 200;
beforeEach(function() {
testData = {
alias: 'test',
datapoints: [[1, 2], [0, 3], [10, 4], [8, 5]],
};
series = new TimeSeries(testData);
series.getFlotPairs();
panel = {
decimals: null,
yaxes: [
{
decimals: null,
},
],
};
});
it('should set decimals based on Y axis (expect calculated decimals = 1)', function() {
let data = [series];
// Expect ticks with this data will have decimals = 1
updateLegendValues(data, panel, height);
expect(data[0].decimals).toBe(2);
});
it('should set decimals based on Y axis to 0 if calculated decimals = 0)', function() {
testData.datapoints = [[10, 2], [0, 3], [100, 4], [80, 5]];
series = new TimeSeries(testData);
series.getFlotPairs();
let data = [series];
updateLegendValues(data, panel, height);
expect(data[0].decimals).toBe(0);
});
it('should set decimals to Y axis decimals + 1', function() {
panel.yaxes[0].decimals = 2;
let data = [series];
updateLegendValues(data, panel, height);
expect(data[0].decimals).toBe(3);
});
it('should set decimals to legend decimals value if it was set explicitly', function() {
panel.decimals = 3;
let data = [series];
updateLegendValues(data, panel, height);
expect(data[0].decimals).toBe(3);
});
});
});
......@@ -23,23 +23,27 @@ function translateFillOption(fill) {
* Calculate decimals for legend and update values for each series.
* @param data series data
* @param panel
* @param height
*/
export function updateLegendValues(data: TimeSeries[], panel) {
export function updateLegendValues(data: TimeSeries[], panel, height) {
for (let i = 0; i < data.length; i++) {
let series = data[i];
let yaxes = panel.yaxes;
const yaxes = panel.yaxes;
const seriesYAxis = series.yaxis || 1;
let axis = yaxes[seriesYAxis - 1];
let { tickDecimals, scaledDecimals } = getFlotTickDecimals(data, axis);
let formater = kbn.valueFormats[panel.yaxes[seriesYAxis - 1].format];
const axis = yaxes[seriesYAxis - 1];
let formater = kbn.valueFormats[axis.format];
// decimal override
if (_.isNumber(panel.decimals)) {
series.updateLegendValues(formater, panel.decimals, null);
} else if (_.isNumber(axis.decimals)) {
series.updateLegendValues(formater, axis.decimals + 1, null);
} else {
// auto decimals
// legend and tooltip gets one more decimal precision
// than graph legend ticks
const { datamin, datamax } = getDataMinMax(data);
let { tickDecimals, scaledDecimals } = getFlotTickDecimals(datamin, datamax, axis, height);
tickDecimals = (tickDecimals || -1) + 1;
series.updateLegendValues(formater, tickDecimals, scaledDecimals + 2);
}
......
import { getDataMinMax } from 'app/core/time_series2';
/**
* Calculate tick step.
* Implementation from d3-array (ticks.js)
......@@ -121,12 +119,10 @@ export function getFlotRange(panelMin, panelMax, datamin, datamax) {
* Calculate tick decimals.
* Implementation from Flot.
*/
export function getFlotTickDecimals(data, axis) {
let { datamin, datamax } = getDataMinMax(data);
let { min, max } = getFlotRange(axis.min, axis.max, datamin, datamax);
let noTicks = 3;
let tickDecimals, maxDec;
let delta = (max - min) / noTicks;
export function getFlotTickDecimals(datamin, datamax, axis, height) {
const { min, max } = getFlotRange(axis.min, axis.max, datamin, datamax);
const noTicks = 0.3 * Math.sqrt(height);
const delta = (max - min) / noTicks;
let dec = -Math.floor(Math.log(delta) / Math.LN10);
let magn = Math.pow(10, -dec);
......@@ -139,19 +135,17 @@ export function getFlotTickDecimals(data, axis) {
} else if (norm < 3) {
size = 2;
// special case for 2.5, requires an extra decimal
if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
if (norm > 2.25) {
size = 2.5;
++dec;
}
} else if (norm < 7.5) {
size = 5;
} else {
size = 10;
}
size *= magn;
tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
const tickDecimals = Math.max(0, -Math.floor(Math.log(delta) / Math.LN10) + 1);
// grafana addition
const scaledDecimals = tickDecimals - Math.floor(Math.log(size) / Math.LN10);
return { tickDecimals, scaledDecimals };
......
......@@ -64,7 +64,8 @@ function graphDirective(timeSrv, popoverSrv, contextSrv) {
}
annotations = ctrl.annotations || [];
buildFlotPairs(data);
updateLegendValues(data, panel);
const graphHeight = elem.height();
updateLegendValues(data, panel, graphHeight);
ctrl.events.emit('render-legend');
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment