mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ExtractFields: properly detect value types from extracted fields (#41995)
This commit is contained in:
parent
cf995ea420
commit
82cf49143d
@ -11,6 +11,7 @@ import { DataFrameDTO, FieldType, TableData, TimeSeries } from '../types/index';
|
||||
import { dateTime } from '../datetime/moment_wrapper';
|
||||
import { MutableDataFrame } from './MutableDataFrame';
|
||||
import { ArrayDataFrame } from './ArrayDataFrame';
|
||||
import { getFieldTypeFromValue } from '.';
|
||||
|
||||
describe('toDataFrame', () => {
|
||||
it('converts timeseries to series', () => {
|
||||
@ -118,15 +119,13 @@ describe('toDataFrame', () => {
|
||||
expect(guessFieldTypeFromValue('xxxx')).toBe(FieldType.string);
|
||||
});
|
||||
|
||||
it('Guess Column Types from strings', () => {
|
||||
expect(guessFieldTypeFromValue('1')).toBe(FieldType.number);
|
||||
expect(guessFieldTypeFromValue('1.234')).toBe(FieldType.number);
|
||||
expect(guessFieldTypeFromValue('NaN')).toBe(FieldType.number);
|
||||
expect(guessFieldTypeFromValue('3.125e7')).toBe(FieldType.number);
|
||||
expect(guessFieldTypeFromValue('True')).toBe(FieldType.boolean);
|
||||
expect(guessFieldTypeFromValue('FALSE')).toBe(FieldType.boolean);
|
||||
expect(guessFieldTypeFromValue('true')).toBe(FieldType.boolean);
|
||||
expect(guessFieldTypeFromValue('xxxx')).toBe(FieldType.string);
|
||||
it('Get column types from values', () => {
|
||||
expect(getFieldTypeFromValue(1)).toBe(FieldType.number);
|
||||
expect(getFieldTypeFromValue(1.234)).toBe(FieldType.number);
|
||||
expect(getFieldTypeFromValue(NaN)).toBe(FieldType.number);
|
||||
expect(getFieldTypeFromValue(3.125e7)).toBe(FieldType.number);
|
||||
expect(getFieldTypeFromValue(true)).toBe(FieldType.boolean);
|
||||
expect(getFieldTypeFromValue('xxxx')).toBe(FieldType.string);
|
||||
});
|
||||
|
||||
it('Guess Column Types from series', () => {
|
||||
|
@ -189,10 +189,33 @@ export function guessFieldTypeFromNameAndValue(name: string, v: any): FieldType
|
||||
return guessFieldTypeFromValue(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the field type to see what the contents are
|
||||
*/
|
||||
export function getFieldTypeFromValue(v: any): FieldType {
|
||||
if (v instanceof Date || isDateTime(v)) {
|
||||
return FieldType.time;
|
||||
}
|
||||
|
||||
if (isNumber(v)) {
|
||||
return FieldType.number;
|
||||
}
|
||||
|
||||
if (isString(v)) {
|
||||
return FieldType.string;
|
||||
}
|
||||
|
||||
if (isBoolean(v)) {
|
||||
return FieldType.boolean;
|
||||
}
|
||||
|
||||
return FieldType.other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value this will guess the best column type
|
||||
*
|
||||
* TODO: better Date/Time support! Look for standard date strings?
|
||||
* NOTE: this is will try to see if string values can be mapped to other types (like number)
|
||||
*/
|
||||
export function guessFieldTypeFromValue(v: any): FieldType {
|
||||
if (v instanceof Date || isDateTime(v)) {
|
||||
@ -237,7 +260,7 @@ export function guessFieldTypeForField(field: Field): FieldType | undefined {
|
||||
// 2. Check the first non-null value
|
||||
for (let i = 0; i < field.values.length; i++) {
|
||||
const v = field.values.get(i);
|
||||
if (v !== null) {
|
||||
if (v != null) {
|
||||
return guessFieldTypeFromValue(v);
|
||||
}
|
||||
}
|
||||
|
@ -14,23 +14,28 @@ describe('Fields from JSON', () => {
|
||||
|
||||
const frames = extractFieldsTransformer.transformer(cfg)([data]);
|
||||
expect(frames.length).toEqual(1);
|
||||
expect(frames[0].fields.map((v) => v.name)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"a",
|
||||
"av",
|
||||
"c",
|
||||
"e",
|
||||
"ev",
|
||||
"h",
|
||||
"l",
|
||||
"o",
|
||||
"op",
|
||||
"s",
|
||||
"sym",
|
||||
"v",
|
||||
"vw",
|
||||
"z",
|
||||
]
|
||||
expect(
|
||||
frames[0].fields.reduce((acc, v) => {
|
||||
acc[v.name] = v.type;
|
||||
return acc;
|
||||
}, {} as any)
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"a": "string",
|
||||
"av": "number",
|
||||
"c": "string",
|
||||
"e": "number",
|
||||
"ev": "string",
|
||||
"h": "string",
|
||||
"l": "string",
|
||||
"o": "string",
|
||||
"op": "string",
|
||||
"s": "number",
|
||||
"sym": "string",
|
||||
"v": "number",
|
||||
"vw": "string",
|
||||
"z": "number",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
DataTransformerID,
|
||||
Field,
|
||||
FieldType,
|
||||
guessFieldTypeForField,
|
||||
getFieldTypeFromValue,
|
||||
SynchronousDataTransformerInfo,
|
||||
} from '@grafana/data';
|
||||
import { findField } from 'app/features/dimensions';
|
||||
@ -72,14 +72,13 @@ function addExtractedFields(frame: DataFrame, options: ExtractFieldsOptions): Da
|
||||
}
|
||||
|
||||
const fields = names.map((name) => {
|
||||
const f: Field = {
|
||||
const buffer = values.get(name);
|
||||
return {
|
||||
name,
|
||||
values: new ArrayVector(values.get(name)),
|
||||
type: FieldType.boolean,
|
||||
values: new ArrayVector(buffer),
|
||||
type: buffer ? getFieldTypeFromValue(buffer.find((v) => v != null)) : FieldType.other,
|
||||
config: {},
|
||||
};
|
||||
f.type = guessFieldTypeForField(f) ?? FieldType.other;
|
||||
return f;
|
||||
} as Field;
|
||||
});
|
||||
|
||||
if (!options.replace) {
|
||||
|
Loading…
Reference in New Issue
Block a user