|
|
|
@ -1,3 +1,5 @@ |
|
|
|
|
import {getDataMinMax} from 'app/core/time_series2'; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Calculate tick step. |
|
|
|
|
* Implementation from d3-array (ticks.js) |
|
|
|
@ -32,6 +34,7 @@ export function getScaledDecimals(decimals, tick_size) { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Calculate tick size based on min and max values, number of ticks and precision. |
|
|
|
|
* Implementation from Flot. |
|
|
|
|
* @param min Axis minimum |
|
|
|
|
* @param max Axis maximum |
|
|
|
|
* @param noTicks Number of ticks |
|
|
|
@ -65,3 +68,107 @@ export function getFlotTickSize(min: number, max: number, noTicks: number, tickD |
|
|
|
|
|
|
|
|
|
return size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Calculate axis range (min and max). |
|
|
|
|
* Implementation from Flot. |
|
|
|
|
*/ |
|
|
|
|
export function getFlotRange(panelMin, panelMax, datamin, datamax) { |
|
|
|
|
const autoscaleMargin = 0.02; |
|
|
|
|
|
|
|
|
|
let min = +(panelMin != null ? panelMin : datamin); |
|
|
|
|
let max = +(panelMax != null ? panelMax : datamax); |
|
|
|
|
let delta = max - min; |
|
|
|
|
|
|
|
|
|
if (delta === 0.0) { |
|
|
|
|
// Grafana fix: wide Y min and max using increased wideFactor
|
|
|
|
|
// when all series values are the same
|
|
|
|
|
var wideFactor = 0.25; |
|
|
|
|
var widen = Math.abs(max === 0 ? 1 : max * wideFactor); |
|
|
|
|
|
|
|
|
|
if (panelMin === null) { |
|
|
|
|
min -= widen; |
|
|
|
|
} |
|
|
|
|
// always widen max if we couldn't widen min to ensure we
|
|
|
|
|
// don't fall into min == max which doesn't work
|
|
|
|
|
if (panelMax == null || panelMin != null) { |
|
|
|
|
max += widen; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// consider autoscaling
|
|
|
|
|
var margin = autoscaleMargin; |
|
|
|
|
if (margin != null) { |
|
|
|
|
if (panelMin == null) { |
|
|
|
|
min -= delta * margin; |
|
|
|
|
// make sure we don't go below zero if all values
|
|
|
|
|
// are positive
|
|
|
|
|
if (min < 0 && datamin != null && datamin >= 0) { |
|
|
|
|
min = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (panelMax == null) { |
|
|
|
|
max += delta * margin; |
|
|
|
|
if (max > 0 && datamax != null && datamax <= 0) { |
|
|
|
|
max = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return {min, max}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Estimate number of ticks for Y axis. |
|
|
|
|
* Implementation from Flot. |
|
|
|
|
*/ |
|
|
|
|
export function getFlotNumberOfTicks(height, ticks?) { |
|
|
|
|
let noTicks; |
|
|
|
|
if (typeof ticks === "number" && ticks > 0) { |
|
|
|
|
noTicks = ticks; |
|
|
|
|
} else { |
|
|
|
|
// heuristic based on the model a*sqrt(x) fitted to
|
|
|
|
|
// some data points that seemed reasonable
|
|
|
|
|
noTicks = 0.3 * Math.sqrt(height); |
|
|
|
|
} |
|
|
|
|
return noTicks; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Calculate tick decimals. |
|
|
|
|
* Implementation from Flot. |
|
|
|
|
*/ |
|
|
|
|
export function getFlotTickDecimals(data, axis, height) { |
|
|
|
|
let {datamin, datamax} = getDataMinMax(data); |
|
|
|
|
let {min, max} = getFlotRange(axis.min, axis.max, datamin, datamax); |
|
|
|
|
let noTicks = getFlotNumberOfTicks(height); |
|
|
|
|
let tickDecimals, maxDec; |
|
|
|
|
let delta = (max - min) / noTicks; |
|
|
|
|
let dec = -Math.floor(Math.log(delta) / Math.LN10); |
|
|
|
|
|
|
|
|
|
let magn = Math.pow(10, -dec); |
|
|
|
|
// norm is between 1.0 and 10.0
|
|
|
|
|
let norm = delta / magn; |
|
|
|
|
let size; |
|
|
|
|
|
|
|
|
|
if (norm < 1.5) { |
|
|
|
|
size = 1; |
|
|
|
|
} else if (norm < 3) { |
|
|
|
|
size = 2; |
|
|
|
|
// special case for 2.5, requires an extra decimal
|
|
|
|
|
if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { |
|
|
|
|
size = 2.5; |
|
|
|
|
++dec; |
|
|
|
|
} |
|
|
|
|
} else if (norm < 7.5) { |
|
|
|
|
size = 5; |
|
|
|
|
} else { |
|
|
|
|
size = 10; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size *= magn; |
|
|
|
|
|
|
|
|
|
tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); |
|
|
|
|
// grafana addition
|
|
|
|
|
const scaledDecimals = tickDecimals - Math.floor(Math.log(size) / Math.LN10); |
|
|
|
|
return {tickDecimals, scaledDecimals}; |
|
|
|
|
} |
|
|
|
|