mirror of https://github.com/grafana/grafana
DataLinks: allow using values from other fields in the same row (#21478)
parent
3f957a3735
commit
76ba2db4e7
@ -0,0 +1,66 @@ |
||||
import { toDataFrame, applyFieldOverrides, GrafanaTheme } from '@grafana/data'; |
||||
import { getFieldDisplayValuesProxy } from './fieldDisplayValuesProxy'; |
||||
|
||||
describe('getFieldDisplayValuesProxy', () => { |
||||
const data = applyFieldOverrides({ |
||||
data: [ |
||||
toDataFrame({ |
||||
fields: [ |
||||
{ name: 'Time', values: [1, 2, 3] }, |
||||
{ |
||||
name: 'power', |
||||
values: [100, 200, 300], |
||||
config: { |
||||
title: 'The Power', |
||||
}, |
||||
}, |
||||
{ |
||||
name: 'Last', |
||||
values: ['a', 'b', 'c'], |
||||
}, |
||||
], |
||||
}), |
||||
], |
||||
fieldOptions: { |
||||
defaults: {}, |
||||
overrides: [], |
||||
}, |
||||
replaceVariables: (val: string) => val, |
||||
timeZone: 'utc', |
||||
theme: {} as GrafanaTheme, |
||||
autoMinMax: true, |
||||
})[0]; |
||||
|
||||
it('should define all display functions', () => { |
||||
// Field display should be set
|
||||
for (const field of data.fields) { |
||||
expect(field.display).toBeDefined(); |
||||
} |
||||
}); |
||||
|
||||
it('should format the time values in UTC', () => { |
||||
// Test Proxies in general
|
||||
const p = getFieldDisplayValuesProxy(data, 0); |
||||
const time = p.Time; |
||||
expect(time.numeric).toEqual(1); |
||||
expect(time.text).toEqual('1970-01-01 00:00:00'); |
||||
|
||||
// Should get to the same values by name or index
|
||||
const time2 = p[0]; |
||||
expect(time2.toString()).toEqual(time.toString()); |
||||
}); |
||||
|
||||
it('Lookup by name, index, or title', () => { |
||||
const p = getFieldDisplayValuesProxy(data, 2); |
||||
expect(p.power.numeric).toEqual(300); |
||||
expect(p['power'].numeric).toEqual(300); |
||||
expect(p['The Power'].numeric).toEqual(300); |
||||
expect(p[1].numeric).toEqual(300); |
||||
}); |
||||
|
||||
it('should return undefined when missing', () => { |
||||
const p = getFieldDisplayValuesProxy(data, 0); |
||||
expect(p.xyz).toBeUndefined(); |
||||
expect(p[100]).toBeUndefined(); |
||||
}); |
||||
}); |
@ -0,0 +1,35 @@ |
||||
import { DisplayValue, DataFrame, formattedValueToString, getDisplayProcessor } from '@grafana/data'; |
||||
import { config } from '@grafana/runtime'; |
||||
import toNumber from 'lodash/toNumber'; |
||||
|
||||
export function getFieldDisplayValuesProxy(frame: DataFrame, rowIndex: number): Record<string, DisplayValue> { |
||||
return new Proxy({} as Record<string, DisplayValue>, { |
||||
get: (obj: any, key: string) => { |
||||
// 1. Match the name
|
||||
let field = frame.fields.find(f => key === f.name); |
||||
if (!field) { |
||||
// 2. Match the array index
|
||||
const k = toNumber(key); |
||||
field = frame.fields[k]; |
||||
} |
||||
if (!field) { |
||||
// 3. Match the title
|
||||
field = frame.fields.find(f => key === f.config.title); |
||||
} |
||||
if (!field) { |
||||
return undefined; |
||||
} |
||||
if (!field.display) { |
||||
// Lazy load the display processor
|
||||
field.display = getDisplayProcessor({ |
||||
field, |
||||
theme: config.theme, |
||||
}); |
||||
} |
||||
const raw = field.values.get(rowIndex); |
||||
const disp = field.display(raw); |
||||
disp.toString = () => formattedValueToString(disp); |
||||
return disp; |
||||
}, |
||||
}); |
||||
} |
Loading…
Reference in new issue