Refactor: move more files to @grafana/data (#17972)

This commit is contained in:
Ryan McKinley
2019-07-06 09:18:23 -07:00
committed by GitHub
parent fcdc29746f
commit bdaf0aa81a
34 changed files with 84 additions and 88 deletions

View File

@@ -0,0 +1,5 @@
export interface DataLink {
url: string;
title: string;
targetBlank?: boolean;
}

View File

@@ -1,5 +1,8 @@
export * from './data';
export * from './dataLink';
export * from './logs';
export * from './navModel';
export * from './time';
export * from './threshold';
export * from './utils';
export * from './valueMapping';

View File

@@ -0,0 +1,5 @@
export interface Threshold {
index: number;
value: number;
color: string;
}

View File

@@ -0,0 +1,22 @@
export enum MappingType {
ValueToText = 1,
RangeToText = 2,
}
interface BaseMap {
id: number;
operator: string;
text: string;
type: MappingType;
}
export type ValueMapping = ValueMap | RangeMap;
export interface ValueMap extends BaseMap {
value: string;
}
export interface RangeMap extends BaseMap {
from: string;
to: string;
}

View File

@@ -9,6 +9,9 @@ export * from './labels';
export * from './object';
export * from './fieldCache';
export * from './moment_wrapper';
export * from './thresholds';
export { getMappedValue } from './valueMappings';
// Names are too general to export globally
import * as dateMath from './datemath';

View File

@@ -0,0 +1,23 @@
import { Threshold } from '../types';
export function getThresholdForValue(
thresholds: Threshold[],
value: number | null | string | undefined
): Threshold | null {
if (thresholds.length === 1) {
return thresholds[0];
}
const atThreshold = thresholds.filter(threshold => (value as number) === threshold.value)[0];
if (atThreshold) {
return atThreshold;
}
const belowThreshold = thresholds.filter(threshold => (value as number) > threshold.value);
if (belowThreshold.length > 0) {
const nearestThreshold = belowThreshold.sort((t1: Threshold, t2: Threshold) => t2.value - t1.value)[0];
return nearestThreshold;
}
return null;
}

View File

@@ -0,0 +1,81 @@
import { getMappedValue } from './valueMappings';
import { ValueMapping, MappingType } from '../types';
describe('Format value with value mappings', () => {
it('should return undefined with no valuemappings', () => {
const valueMappings: ValueMapping[] = [];
const value = '10';
expect(getMappedValue(valueMappings, value)).toBeUndefined();
});
it('should return undefined with no matching valuemappings', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: 'elva', type: MappingType.ValueToText, value: '11' },
{ id: 1, operator: '', text: '1-9', type: MappingType.RangeToText, from: '1', to: '9' },
];
const value = '10';
expect(getMappedValue(valueMappings, value)).toBeUndefined();
});
it('should return first matching mapping with lowest id', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '1-20', type: MappingType.RangeToText, from: '1', to: '20' },
{ id: 1, operator: '', text: 'tio', type: MappingType.ValueToText, value: '10' },
];
const value = '10';
expect(getMappedValue(valueMappings, value).text).toEqual('1-20');
});
it('should return if value is null and value to text mapping value is null', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '1-20', type: MappingType.RangeToText, from: '1', to: '20' },
{ id: 1, operator: '', text: '<NULL>', type: MappingType.ValueToText, value: 'null' },
];
const value = null;
expect(getMappedValue(valueMappings, value).text).toEqual('<NULL>');
});
it('should return if value is null and range to text mapping from and to is null', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '<NULL>', type: MappingType.RangeToText, from: 'null', to: 'null' },
{ id: 1, operator: '', text: 'elva', type: MappingType.ValueToText, value: '11' },
];
const value = null;
expect(getMappedValue(valueMappings, value).text).toEqual('<NULL>');
});
it('should return rangeToText mapping where value equals to', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '1-10', type: MappingType.RangeToText, from: '1', to: '10' },
{ id: 1, operator: '', text: 'elva', type: MappingType.ValueToText, value: '11' },
];
const value = '10';
expect(getMappedValue(valueMappings, value).text).toEqual('1-10');
});
it('should return rangeToText mapping where value equals from', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '10-20', type: MappingType.RangeToText, from: '10', to: '20' },
{ id: 1, operator: '', text: 'elva', type: MappingType.ValueToText, value: '11' },
];
const value = '10';
expect(getMappedValue(valueMappings, value).text).toEqual('10-20');
});
it('should return rangeToText mapping where value is between from and to', () => {
const valueMappings: ValueMapping[] = [
{ id: 0, operator: '', text: '1-20', type: MappingType.RangeToText, from: '1', to: '20' },
{ id: 1, operator: '', text: 'elva', type: MappingType.ValueToText, value: '11' },
];
const value = '10';
expect(getMappedValue(valueMappings, value).text).toEqual('1-20');
});
});

View File

@@ -0,0 +1,89 @@
import { ValueMapping, MappingType, ValueMap, RangeMap } from '../types';
type TimeSeriesValue = string | number | null;
const addValueToTextMappingText = (
allValueMappings: ValueMapping[],
valueToTextMapping: ValueMap,
value: TimeSeriesValue
) => {
if (valueToTextMapping.value === undefined) {
return allValueMappings;
}
if (value === null && valueToTextMapping.value && valueToTextMapping.value.toLowerCase() === 'null') {
return allValueMappings.concat(valueToTextMapping);
}
const valueAsNumber = parseFloat(value as string);
const valueToTextMappingAsNumber = parseFloat(valueToTextMapping.value as string);
if (isNaN(valueAsNumber) || isNaN(valueToTextMappingAsNumber)) {
return allValueMappings;
}
if (valueAsNumber !== valueToTextMappingAsNumber) {
return allValueMappings;
}
return allValueMappings.concat(valueToTextMapping);
};
const addRangeToTextMappingText = (
allValueMappings: ValueMapping[],
rangeToTextMapping: RangeMap,
value: TimeSeriesValue
) => {
if (rangeToTextMapping.from === undefined || rangeToTextMapping.to === undefined || value === undefined) {
return allValueMappings;
}
if (
value === null &&
rangeToTextMapping.from &&
rangeToTextMapping.to &&
rangeToTextMapping.from.toLowerCase() === 'null' &&
rangeToTextMapping.to.toLowerCase() === 'null'
) {
return allValueMappings.concat(rangeToTextMapping);
}
const valueAsNumber = parseFloat(value as string);
const fromAsNumber = parseFloat(rangeToTextMapping.from as string);
const toAsNumber = parseFloat(rangeToTextMapping.to as string);
if (isNaN(valueAsNumber) || isNaN(fromAsNumber) || isNaN(toAsNumber)) {
return allValueMappings;
}
if (valueAsNumber >= fromAsNumber && valueAsNumber <= toAsNumber) {
return allValueMappings.concat(rangeToTextMapping);
}
return allValueMappings;
};
const getAllFormattedValueMappings = (valueMappings: ValueMapping[], value: TimeSeriesValue) => {
const allFormattedValueMappings = valueMappings.reduce(
(allValueMappings, valueMapping) => {
if (valueMapping.type === MappingType.ValueToText) {
allValueMappings = addValueToTextMappingText(allValueMappings, valueMapping as ValueMap, value);
} else if (valueMapping.type === MappingType.RangeToText) {
allValueMappings = addRangeToTextMappingText(allValueMappings, valueMapping as RangeMap, value);
}
return allValueMappings;
},
[] as ValueMapping[]
);
allFormattedValueMappings.sort((t1, t2) => {
return t1.id - t2.id;
});
return allFormattedValueMappings;
};
export const getMappedValue = (valueMappings: ValueMapping[], value: TimeSeriesValue): ValueMapping => {
return getAllFormattedValueMappings(valueMappings, value)[0];
};