Files
grafana/packages/grafana-ui/src/utils/valueProcessor.ts
2019-03-11 14:47:54 -07:00

98 lines
3.0 KiB
TypeScript

import { ValueMapping, Threshold } from '../types/panel';
import _ from 'lodash';
import { getValueFormat, DecimalCount } from './valueFormats/valueFormats';
import { getMappedValue } from './valueMappings';
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';
import { getColorFromHexRgbOrName } from './namedColorsPalette';
export interface DisplayValue {
text: string; // How the value should be displayed
numeric?: number; // the value as a number
color?: string; // suggested color
}
export interface DisplayValueOptions {
unit?: string;
decimals?: DecimalCount;
scaledDecimals?: DecimalCount;
isUtc?: boolean;
color?: string;
mappings?: ValueMapping[];
thresholds?: Threshold[];
prefix?: string;
suffix?: string;
noValue?: string;
theme?: GrafanaTheme; // Will pick 'dark' if not defined
}
export type ValueProcessor = (value: any) => DisplayValue;
export function getValueProcessor(options?: DisplayValueOptions): ValueProcessor {
if (options && !_.isEmpty(options)) {
const formatFunc = getValueFormat(options.unit || 'none');
return (value: any) => {
const { prefix, suffix, mappings, thresholds, theme } = options;
let color = options.color;
let text = _.toString(value);
const numeric = _.toNumber(value);
if (mappings && mappings.length > 0) {
const mappedValue = getMappedValue(mappings, value);
if (mappedValue) {
text = mappedValue.text;
// TODO? convert the mapped value back to a number?
}
}
if (_.isNumber(numeric)) {
text = formatFunc(numeric, options.decimals, options.scaledDecimals, options.isUtc);
if (thresholds && thresholds.length > 0) {
color = getColorFromThreshold(numeric, thresholds, theme);
}
}
if (!text) {
text = options.noValue ? options.noValue : '';
}
if (prefix) {
text = prefix + text;
}
if (suffix) {
text = text + suffix;
}
return { text, numeric, color };
};
}
return toStringProcessor;
}
function toStringProcessor(value: any): DisplayValue {
return { text: _.toString(value), numeric: _.toNumber(value) };
}
export function getColorFromThreshold(value: number, thresholds: Threshold[], theme?: GrafanaTheme): string {
const themeType = theme ? theme.type : GrafanaThemeType.Dark;
if (thresholds.length === 1) {
return getColorFromHexRgbOrName(thresholds[0].color, themeType);
}
const atThreshold = thresholds.filter(threshold => value === threshold.value)[0];
if (atThreshold) {
return getColorFromHexRgbOrName(atThreshold.color, themeType);
}
const belowThreshold = thresholds.filter(threshold => value > threshold.value);
if (belowThreshold.length > 0) {
const nearestThreshold = belowThreshold.sort((t1, t2) => t2.value - t1.value)[0];
return getColorFromHexRgbOrName(nearestThreshold.color, themeType);
}
// Use the first threshold as the default color
return getColorFromHexRgbOrName(thresholds[0].color, themeType);
}