mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TimeSeries: Implement auto decimals for y axes (#52912)
This commit is contained in:
@@ -1971,11 +1971,10 @@ exports[`better eslint`] = {
|
|||||||
],
|
],
|
||||||
"packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts:5381": [
|
"packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
|
|
||||||
],
|
],
|
||||||
"packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts:5381": [
|
"packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
@@ -4592,12 +4591,13 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "10"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
|
[0, 0, 0, "Do not use any type assertions.", "11"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "15"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "16"]
|
||||||
],
|
],
|
||||||
"public/app/features/dashboard/utils/panelMerge.test.ts:5381": [
|
"public/app/features/dashboard/utils/panelMerge.test.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { toUtc, dateTimeParse } from '../datetime';
|
|||||||
import { GrafanaTheme2 } from '../themes/types';
|
import { GrafanaTheme2 } from '../themes/types';
|
||||||
import { KeyValue, TimeZone } from '../types';
|
import { KeyValue, TimeZone } from '../types';
|
||||||
import { Field, FieldType } from '../types/dataFrame';
|
import { Field, FieldType } from '../types/dataFrame';
|
||||||
import { DisplayProcessor, DisplayValue } from '../types/displayValue';
|
import { DecimalCount, DisplayProcessor, DisplayValue } from '../types/displayValue';
|
||||||
import { anyToNumber } from '../utils/anyToNumber';
|
import { anyToNumber } from '../utils/anyToNumber';
|
||||||
import { getValueMappingResult } from '../utils/valueMappings';
|
import { getValueMappingResult } from '../utils/valueMappings';
|
||||||
import { getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats';
|
import { getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats';
|
||||||
@@ -75,7 +75,7 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
|
|||||||
const formatFunc = getValueFormat(unit || 'none');
|
const formatFunc = getValueFormat(unit || 'none');
|
||||||
const scaleFunc = getScaleCalculator(field, options.theme);
|
const scaleFunc = getScaleCalculator(field, options.theme);
|
||||||
|
|
||||||
return (value: any) => {
|
return (value: any, decimals?: DecimalCount) => {
|
||||||
const { mappings } = config;
|
const { mappings } = config;
|
||||||
const isStringUnit = unit === 'string';
|
const isStringUnit = unit === 'string';
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
|
|||||||
|
|
||||||
if (!isNaN(numeric)) {
|
if (!isNaN(numeric)) {
|
||||||
if (text == null && !isBoolean(value)) {
|
if (text == null && !isBoolean(value)) {
|
||||||
const v = formatFunc(numeric, config.decimals, null, options.timeZone, showMs);
|
const v = formatFunc(numeric, decimals ?? config.decimals, null, options.timeZone, showMs);
|
||||||
text = v.text;
|
text = v.text;
|
||||||
suffix = v.suffix;
|
suffix = v.suffix;
|
||||||
prefix = v.prefix;
|
prefix = v.prefix;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
ApplyFieldOverrideOptions,
|
ApplyFieldOverrideOptions,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataLink,
|
DataLink,
|
||||||
|
DecimalCount,
|
||||||
DisplayProcessor,
|
DisplayProcessor,
|
||||||
DisplayValue,
|
DisplayValue,
|
||||||
DynamicConfigValue,
|
DynamicConfigValue,
|
||||||
@@ -213,9 +214,18 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra
|
|||||||
// 2. have the ability to selectively get display color or text (but not always both, which are each quite expensive)
|
// 2. have the ability to selectively get display color or text (but not always both, which are each quite expensive)
|
||||||
// 3. sufficently optimize text formatting and threshold color determinitation
|
// 3. sufficently optimize text formatting and threshold color determinitation
|
||||||
function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): DisplayProcessor {
|
function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): DisplayProcessor {
|
||||||
const cache = new Map<any, DisplayValue>();
|
type dispCache = Map<any, DisplayValue>;
|
||||||
|
// decimals -> cache mapping, -1 is unspecified decimals
|
||||||
|
const caches = new Map<number, dispCache>();
|
||||||
|
|
||||||
|
// pre-init caches for up to 15 decimals
|
||||||
|
for (let i = -1; i <= 15; i++) {
|
||||||
|
caches.set(i, new Map());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (value: any, decimals?: DecimalCount) => {
|
||||||
|
let cache = caches.get(decimals ?? -1)!;
|
||||||
|
|
||||||
return (value: any) => {
|
|
||||||
let v = cache.get(value);
|
let v = cache.get(value);
|
||||||
|
|
||||||
if (!v) {
|
if (!v) {
|
||||||
@@ -224,7 +234,7 @@ function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): D
|
|||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
v = disp(value);
|
v = disp(value, decimals);
|
||||||
|
|
||||||
// convert to hex6 or hex8 so downstream we can cheaply test for alpha (and set new alpha)
|
// convert to hex6 or hex8 so downstream we can cheaply test for alpha (and set new alpha)
|
||||||
// via a simple length check (in colorManipulator) rather using slow parsing via tinycolor
|
// via a simple length check (in colorManipulator) rather using slow parsing via tinycolor
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ScopedVars } from './ScopedVars';
|
import { ScopedVars } from './ScopedVars';
|
||||||
import { QueryResultBase, Labels, NullValueMode } from './data';
|
import { QueryResultBase, Labels, NullValueMode } from './data';
|
||||||
import { DataLink, LinkModel } from './dataLink';
|
import { DataLink, LinkModel } from './dataLink';
|
||||||
import { DisplayProcessor, DisplayValue } from './displayValue';
|
import { DecimalCount, DisplayProcessor, DisplayValue } from './displayValue';
|
||||||
import { FieldColor } from './fieldColor';
|
import { FieldColor } from './fieldColor';
|
||||||
import { ThresholdsConfig } from './thresholds';
|
import { ThresholdsConfig } from './thresholds';
|
||||||
import { ValueMapping } from './valueMapping';
|
import { ValueMapping } from './valueMapping';
|
||||||
@@ -63,7 +63,7 @@ export interface FieldConfig<TOptions = any> {
|
|||||||
|
|
||||||
// Numeric Options
|
// Numeric Options
|
||||||
unit?: string;
|
unit?: string;
|
||||||
decimals?: number | null; // Significant digits (for display)
|
decimals?: DecimalCount; // Significant digits (for display)
|
||||||
min?: number | null;
|
min?: number | null;
|
||||||
max?: number | null;
|
max?: number | null;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { FormattedValue } from '../valueFormats';
|
import { FormattedValue } from '../valueFormats';
|
||||||
|
|
||||||
export type DisplayProcessor = (value: any) => DisplayValue;
|
export type DisplayProcessor = (value: any, decimals?: DecimalCount) => DisplayValue;
|
||||||
|
|
||||||
export interface DisplayValue extends FormattedValue {
|
export interface DisplayValue extends FormattedValue {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export * from './deprecationWarning';
|
|||||||
export * from './csv';
|
export * from './csv';
|
||||||
export * from './logs';
|
export * from './logs';
|
||||||
export * from './labels';
|
export * from './labels';
|
||||||
export * from './labels';
|
export * from './numbers';
|
||||||
export * from './object';
|
export * from './object';
|
||||||
export * from './namedColorsPalette';
|
export * from './namedColorsPalette';
|
||||||
export * from './series';
|
export * from './series';
|
||||||
|
|||||||
29
packages/grafana-data/src/utils/numbers.ts
Normal file
29
packages/grafana-data/src/utils/numbers.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Round half away from zero ('commercial' rounding)
|
||||||
|
* Uses correction to offset floating-point inaccuracies.
|
||||||
|
* Works symmetrically for positive and negative numbers.
|
||||||
|
*
|
||||||
|
* ref: https://stackoverflow.com/a/48764436
|
||||||
|
*/
|
||||||
|
export function roundDecimals(val: number, dec = 0) {
|
||||||
|
if (Number.isInteger(val)) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = 10 ** dec;
|
||||||
|
let n = val * p * (1 + Number.EPSILON);
|
||||||
|
return Math.round(n) / p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to guess number of decimals needed to format a number
|
||||||
|
*
|
||||||
|
* used for determining minimum decimals required to uniformly
|
||||||
|
* format a numric sequence, e.g. 10, 10.125, 10.25, 10.5
|
||||||
|
*
|
||||||
|
* good for precisce increments: 0.125 -> 3
|
||||||
|
* bad for arbitrary floats: 371.499999999999 -> 12
|
||||||
|
*/
|
||||||
|
export function guessDecimals(num: number) {
|
||||||
|
return (('' + num).split('.')[1] || '').length;
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
getFieldDisplayName,
|
getFieldDisplayName,
|
||||||
getDisplayProcessor,
|
getDisplayProcessor,
|
||||||
FieldColorModeId,
|
FieldColorModeId,
|
||||||
|
DecimalCount,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import {
|
import {
|
||||||
AxisPlacement,
|
AxisPlacement,
|
||||||
@@ -35,7 +36,7 @@ import { UPlotConfigBuilder, UPlotConfigPrepFn } from '../uPlot/config/UPlotConf
|
|||||||
import { getScaleGradientFn } from '../uPlot/config/gradientFills';
|
import { getScaleGradientFn } from '../uPlot/config/gradientFills';
|
||||||
import { getStackingGroups, preparePlotData2 } from '../uPlot/utils';
|
import { getStackingGroups, preparePlotData2 } from '../uPlot/utils';
|
||||||
|
|
||||||
const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1));
|
const defaultFormatter = (v: any, decimals: DecimalCount = 1) => (v == null ? '-' : v.toFixed(decimals));
|
||||||
|
|
||||||
const defaultConfig: GraphFieldConfig = {
|
const defaultConfig: GraphFieldConfig = {
|
||||||
drawStyle: GraphDrawStyle.Line,
|
drawStyle: GraphDrawStyle.Line,
|
||||||
@@ -268,7 +269,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
|
|||||||
label: customConfig.axisLabel,
|
label: customConfig.axisLabel,
|
||||||
size: customConfig.axisWidth,
|
size: customConfig.axisWidth,
|
||||||
placement: customConfig.axisPlacement ?? AxisPlacement.Auto,
|
placement: customConfig.axisPlacement ?? AxisPlacement.Auto,
|
||||||
formatValue: (v) => formattedValueToString(fmt(v)),
|
formatValue: (v, decimals) => formattedValueToString(fmt(v, config.decimals ?? decimals)),
|
||||||
theme,
|
theme,
|
||||||
grid: { show: customConfig.axisGridShow },
|
grid: { show: customConfig.axisGridShow },
|
||||||
show: customConfig.hideFrom?.viz === false,
|
show: customConfig.hideFrom?.viz === false,
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
import uPlot, { Axis } from 'uplot';
|
import uPlot, { Axis } from 'uplot';
|
||||||
|
|
||||||
import { dateTimeFormat, GrafanaTheme2, isBooleanUnit, systemDateFormats, TimeZone } from '@grafana/data';
|
import {
|
||||||
|
dateTimeFormat,
|
||||||
|
DecimalCount,
|
||||||
|
GrafanaTheme2,
|
||||||
|
guessDecimals,
|
||||||
|
isBooleanUnit,
|
||||||
|
roundDecimals,
|
||||||
|
systemDateFormats,
|
||||||
|
TimeZone,
|
||||||
|
} from '@grafana/data';
|
||||||
import { AxisPlacement } from '@grafana/schema';
|
import { AxisPlacement } from '@grafana/schema';
|
||||||
|
|
||||||
import { measureText } from '../../../utils/measureText';
|
import { measureText } from '../../../utils/measureText';
|
||||||
@@ -21,7 +30,7 @@ export interface AxisProps {
|
|||||||
ticks?: Axis.Ticks;
|
ticks?: Axis.Ticks;
|
||||||
filter?: Axis.Filter;
|
filter?: Axis.Filter;
|
||||||
space?: Axis.Space;
|
space?: Axis.Space;
|
||||||
formatValue?: (v: any) => string;
|
formatValue?: (v: any, decimals?: DecimalCount) => string;
|
||||||
incrs?: Axis.Incrs;
|
incrs?: Axis.Incrs;
|
||||||
splits?: Axis.Splits;
|
splits?: Axis.Splits;
|
||||||
values?: Axis.Values;
|
values?: Axis.Values;
|
||||||
@@ -176,7 +185,10 @@ export class UPlotAxisBuilder extends PlotConfigBuilder<AxisProps, Axis> {
|
|||||||
} else if (isTime) {
|
} else if (isTime) {
|
||||||
config.values = formatTime;
|
config.values = formatTime;
|
||||||
} else if (formatValue) {
|
} else if (formatValue) {
|
||||||
config.values = (u: uPlot, vals: any[]) => vals.map(formatValue!);
|
config.values = (u: uPlot, splits, axisIdx, tickSpace, tickIncr) => {
|
||||||
|
let decimals = guessDecimals(roundDecimals(tickIncr, 6));
|
||||||
|
return splits.map((v) => formatValue!(v, decimals > 0 ? decimals : undefined));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// store timezone
|
// store timezone
|
||||||
|
|||||||
@@ -1,28 +1,22 @@
|
|||||||
const { abs, round, pow } = Math;
|
import { guessDecimals, roundDecimals } from '@grafana/data';
|
||||||
|
|
||||||
export function roundDec(val: number, dec: number) {
|
const { abs, pow } = Math;
|
||||||
return round(val * (dec = 10 ** dec)) / dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fixedDec = new Map();
|
export const fixedDec = new Map();
|
||||||
|
|
||||||
export function guessDec(num: number) {
|
|
||||||
return (('' + num).split('.')[1] || '').length;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function genIncrs(base: number, minExp: number, maxExp: number, mults: number[]) {
|
export function genIncrs(base: number, minExp: number, maxExp: number, mults: number[]) {
|
||||||
let incrs = [];
|
let incrs = [];
|
||||||
|
|
||||||
let multDec = mults.map(guessDec);
|
let multDec = mults.map(guessDecimals);
|
||||||
|
|
||||||
for (let exp = minExp; exp < maxExp; exp++) {
|
for (let exp = minExp; exp < maxExp; exp++) {
|
||||||
let expa = abs(exp);
|
let expa = abs(exp);
|
||||||
let mag = roundDec(pow(base, exp), expa);
|
let mag = roundDecimals(pow(base, exp), expa);
|
||||||
|
|
||||||
for (let i = 0; i < mults.length; i++) {
|
for (let i = 0; i < mults.length; i++) {
|
||||||
let _incr = mults[i] * mag;
|
let _incr = mults[i] * mag;
|
||||||
let dec = (_incr >= 0 && exp >= 0 ? 0 : expa) + (exp >= multDec[i] ? 0 : multDec[i]);
|
let dec = (_incr >= 0 && exp >= 0 ? 0 : expa) + (exp >= multDec[i] ? 0 : multDec[i]);
|
||||||
let incr = roundDec(_incr, dec);
|
let incr = roundDecimals(_incr, dec);
|
||||||
incrs.push(incr);
|
incrs.push(incr);
|
||||||
fixedDec.set(incr, dec);
|
fixedDec.set(incr, dec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
function roundDec(val: number, dec: number) {
|
import { roundDecimals } from '@grafana/data';
|
||||||
return Math.round(val * (dec = 10 ** dec)) / dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SPACE_BETWEEN = 1;
|
export const SPACE_BETWEEN = 1;
|
||||||
export const SPACE_AROUND = 2;
|
export const SPACE_AROUND = 2;
|
||||||
export const SPACE_EVENLY = 3;
|
export const SPACE_EVENLY = 3;
|
||||||
|
|
||||||
const coord = (i: number, offs: number, iwid: number, gap: number) => roundDec(offs + i * (iwid + gap), 6);
|
const coord = (i: number, offs: number, iwid: number, gap: number) => roundDecimals(offs + i * (iwid + gap), 6);
|
||||||
|
|
||||||
export type Each = (idx: number, offPct: number, dimPct: number) => void;
|
export type Each = (idx: number, offPct: number, dimPct: number) => void;
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ export function distribute(numItems: number, sizeFactor: number, justify: number
|
|||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
let iwid = sizeFactor / numItems;
|
let iwid = sizeFactor / numItems;
|
||||||
let _iwid = roundDec(iwid, 6);
|
let _iwid = roundDecimals(iwid, 6);
|
||||||
|
|
||||||
if (onlyIdx == null) {
|
if (onlyIdx == null) {
|
||||||
for (let i = 0; i < numItems; i++) {
|
for (let i = 0; i < numItems; i++) {
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
label: customConfig.axisLabel,
|
label: customConfig.axisLabel,
|
||||||
size: customConfig.axisWidth,
|
size: customConfig.axisWidth,
|
||||||
placement,
|
placement,
|
||||||
formatValue: (v) => formattedValueToString(field.display!(v)),
|
formatValue: (v, decimals) => formattedValueToString(field.display!(v, field.config.decimals ?? decimals)),
|
||||||
theme,
|
theme,
|
||||||
grid: { show: customConfig.axisGridShow },
|
grid: { show: customConfig.axisGridShow },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
DataHoverClearEvent,
|
DataHoverClearEvent,
|
||||||
DataHoverEvent,
|
DataHoverEvent,
|
||||||
DataHoverPayload,
|
DataHoverPayload,
|
||||||
|
DecimalCount,
|
||||||
FieldDisplay,
|
FieldDisplay,
|
||||||
FieldType,
|
FieldType,
|
||||||
formattedValueToString,
|
formattedValueToString,
|
||||||
@@ -945,11 +946,7 @@ class GraphElement {
|
|||||||
return ticks;
|
return ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
configureAxisMode(
|
configureAxisMode(axis: { tickFormatter: (val: any, axis: any) => string }, format: string, decimals?: DecimalCount) {
|
||||||
axis: { tickFormatter: (val: any, axis: any) => string },
|
|
||||||
format: string,
|
|
||||||
decimals?: number | null
|
|
||||||
) {
|
|
||||||
axis.tickFormatter = (val, axis) => {
|
axis.tickFormatter = (val, axis) => {
|
||||||
const formatter = getValueFormat(format);
|
const formatter = getValueFormat(format);
|
||||||
|
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ export function prepConfig(opts: PrepConfigOpts) {
|
|||||||
size: yAxisConfig.axisWidth || null,
|
size: yAxisConfig.axisWidth || null,
|
||||||
label: yAxisConfig.axisLabel,
|
label: yAxisConfig.axisLabel,
|
||||||
theme: theme,
|
theme: theme,
|
||||||
formatValue: (v: number) => formattedValueToString(dispY(v)),
|
formatValue: (v, decimals) => formattedValueToString(dispY(v, yField.config.decimals ?? decimals)),
|
||||||
splits: isOrdianalY
|
splits: isOrdianalY
|
||||||
? (self: uPlot) => {
|
? (self: uPlot) => {
|
||||||
const meta = readHeatmapRowsCustomMeta(dataRef.current?.heatmap);
|
const meta = readHeatmapRowsCustomMeta(dataRef.current?.heatmap);
|
||||||
|
|||||||
@@ -144,10 +144,15 @@ const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
|
|||||||
theme,
|
theme,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// assumes BucketMax is [1]
|
||||||
|
let countField = frame.fields[2];
|
||||||
|
let dispY = countField.display;
|
||||||
|
|
||||||
builder.addAxis({
|
builder.addAxis({
|
||||||
scaleKey: 'y',
|
scaleKey: 'y',
|
||||||
isTime: false,
|
isTime: false,
|
||||||
placement: AxisPlacement.Left,
|
placement: AxisPlacement.Left,
|
||||||
|
formatValue: (v, decimals) => formattedValueToString(dispY!(v, countField.config.decimals ?? decimals)),
|
||||||
//splits: config.xSplits,
|
//splits: config.xSplits,
|
||||||
//values: config.xValues,
|
//values: config.xValues,
|
||||||
//grid: false,
|
//grid: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user