Field: UI & Code consistency Title -> Display name (#24507)

* Field: Change getFieldTitle to getFieldDisplayNamne and change the NAME of the title field config from Title to Display name

* Review feedback

* fixed unit tests

* Rename fieldConfig.title to displayName

* Fixed tests

* Added migration

* Renamed getFrameDisplayTitle to getFrameDisplayName
This commit is contained in:
Torkel Ödegaard 2020-05-12 13:52:53 +02:00 committed by GitHub
parent 125ba95686
commit 8de10a8b9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 254 additions and 224 deletions

View File

@ -14,14 +14,15 @@ import {
TimeSeriesValue, TimeSeriesValue,
FieldDTO, FieldDTO,
DataFrameDTO, DataFrameDTO,
TIME_SERIES_FIELD_NAME, TIME_SERIES_VALUE_FIELD_NAME,
TIME_SERIES_TIME_FIELD_NAME,
} from '../types/index'; } from '../types/index';
import { isDateTime } from '../datetime/moment_wrapper'; import { isDateTime } from '../datetime/moment_wrapper';
import { ArrayVector } from '../vector/ArrayVector'; import { ArrayVector } from '../vector/ArrayVector';
import { MutableDataFrame } from './MutableDataFrame'; import { MutableDataFrame } from './MutableDataFrame';
import { SortedVector } from '../vector/SortedVector'; import { SortedVector } from '../vector/SortedVector';
import { ArrayDataFrame } from './ArrayDataFrame'; import { ArrayDataFrame } from './ArrayDataFrame';
import { getFieldTitle } from '../field/fieldState'; import { getFieldDisplayName } from '../field/fieldState';
function convertTableToDataFrame(table: TableData): DataFrame { function convertTableToDataFrame(table: TableData): DataFrame {
const fields = table.columns.map(c => { const fields = table.columns.map(c => {
@ -71,13 +72,13 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
const fields = [ const fields = [
{ {
name: 'Time', name: TIME_SERIES_TIME_FIELD_NAME,
type: FieldType.time, type: FieldType.time,
config: {}, config: {},
values: new ArrayVector<number>(times), values: new ArrayVector<number>(times),
}, },
{ {
name: TIME_SERIES_FIELD_NAME, name: TIME_SERIES_VALUE_FIELD_NAME,
type: FieldType.number, type: FieldType.number,
config: { config: {
unit: timeSeries.unit, unit: timeSeries.unit,
@ -88,7 +89,7 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
]; ];
if (timeSeries.title) { if (timeSeries.title) {
(fields[1].config as FieldConfig).title = timeSeries.title; (fields[1].config as FieldConfig).displayName = timeSeries.title;
} }
return { return {
@ -118,13 +119,13 @@ function convertGraphSeriesToDataFrame(graphSeries: GraphSeriesXY): DataFrame {
name: graphSeries.label, name: graphSeries.label,
fields: [ fields: [
{ {
name: graphSeries.label || TIME_SERIES_FIELD_NAME, name: graphSeries.label || TIME_SERIES_VALUE_FIELD_NAME,
type: FieldType.number, type: FieldType.number,
config: {}, config: {},
values: x, values: x,
}, },
{ {
name: 'Time', name: TIME_SERIES_TIME_FIELD_NAME,
type: FieldType.time, type: FieldType.time,
config: { config: {
unit: 'dateTimeAsIso', unit: 'dateTimeAsIso',
@ -332,7 +333,7 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData =
return { return {
alias: frame.name, alias: frame.name,
target: getFieldTitle(valueField, frame), target: getFieldDisplayName(valueField, frame),
datapoints: rows, datapoints: rows,
unit: fields[0].config ? fields[0].config.unit : undefined, unit: fields[0].config ? fields[0].config.unit : undefined,
refId: frame.refId, refId: frame.refId,

View File

@ -32,7 +32,7 @@ describe('FieldDisplay', () => {
fieldConfig: { fieldConfig: {
overrides: [], overrides: [],
defaults: { defaults: {
title: '$__cell_0 * $__field_name * $__series_name', displayName: '$__cell_0 * $__field_name * $__series_name',
}, },
}, },
}); });

View File

@ -91,7 +91,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
let hitLimit = false; let hitLimit = false;
const limit = reduceOptions.limit ? reduceOptions.limit : DEFAULT_FIELD_DISPLAY_VALUES_LIMIT; const limit = reduceOptions.limit ? reduceOptions.limit : DEFAULT_FIELD_DISPLAY_VALUES_LIMIT;
const scopedVars: ScopedVars = {}; const scopedVars: ScopedVars = {};
const defaultTitle = getTitleTemplate(calcs); const defaultDisplayName = getTitleTemplate(calcs);
for (let s = 0; s < data.length && !hitLimit; s++) { for (let s = 0; s < data.length && !hitLimit; s++) {
const series = data[s]; // Name is already set const series = data[s]; // Name is already set
@ -109,7 +109,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
} }
const config = field.config; // already set by the prepare task const config = field.config; // already set by the prepare task
const title = field.config.title ?? defaultTitle; const displayName = field.config.displayName ?? defaultDisplayName;
const display = const display =
field.display ?? field.display ??
@ -121,7 +121,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
// Show all rows // Show all rows
if (reduceOptions.values) { if (reduceOptions.values) {
const usesCellValues = title.indexOf(VAR_CELL_PREFIX) >= 0; const usesCellValues = displayName.indexOf(VAR_CELL_PREFIX) >= 0;
for (let j = 0; j < field.values.length; j++) { for (let j = 0; j < field.values.length; j++) {
// Add all the row variables // Add all the row variables
@ -137,7 +137,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
} }
const displayValue = display(field.values.get(j)); const displayValue = display(field.values.get(j));
displayValue.title = replaceVariables(title, { displayValue.title = replaceVariables(displayName, {
...field.state?.scopedVars, // series and field scoped vars ...field.state?.scopedVars, // series and field scoped vars
...scopedVars, ...scopedVars,
}); });
@ -181,7 +181,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
for (const calc of calcs) { for (const calc of calcs) {
scopedVars[VAR_CALC] = { value: calc, text: calc }; scopedVars[VAR_CALC] = { value: calc, text: calc };
const displayValue = display(results[calc]); const displayValue = display(results[calc]);
displayValue.title = replaceVariables(title, { displayValue.title = replaceVariables(displayName, {
...field.state?.scopedVars, // series and field scoped vars ...field.state?.scopedVars, // series and field scoped vars
...scopedVars, ...scopedVars,
}); });
@ -209,7 +209,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
if (values.length === 0) { if (values.length === 0) {
values.push(createNoValuesFieldDisplay(options)); values.push(createNoValuesFieldDisplay(options));
} else if (values.length === 1 && !fieldConfig.defaults.title) { } else if (values.length === 1 && !fieldConfig.defaults.displayName) {
// Don't show title for single item // Don't show title for single item
values[0].display.title = undefined; values[0].display.title = undefined;
} }

View File

@ -19,7 +19,7 @@ import { Registry } from '../utils';
import { mockStandardProperties } from '../utils/tests/mockStandardProperties'; import { mockStandardProperties } from '../utils/tests/mockStandardProperties';
import { FieldMatcherID } from '../transformations'; import { FieldMatcherID } from '../transformations';
import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry';
import { getFieldTitle } from './fieldState'; import { getFieldDisplayName } from './fieldState';
const property1 = { const property1 = {
id: 'custom.property1', // Match field properties id: 'custom.property1', // Match field properties
@ -84,7 +84,7 @@ describe('applyFieldOverrides', () => {
matcher: { id: FieldMatcherID.numeric }, matcher: { id: FieldMatcherID.numeric },
properties: [ properties: [
{ id: 'decimals', value: 1 }, // Numeric { id: 'decimals', value: 1 }, // Numeric
{ id: 'title', value: 'Kittens' }, // Text { id: 'displayName', value: 'Kittens' }, // Text
], ],
}, },
], ],
@ -163,7 +163,7 @@ describe('applyFieldOverrides', () => {
dateFormat: '', // should be ignored dateFormat: '', // should be ignored
max: parseFloat('NOPE'), // should be ignored max: parseFloat('NOPE'), // should be ignored
min: null, // should alo be ignored! min: null, // should alo be ignored!
title: 'newTitle', displayName: 'newTitle',
}; };
const f: DataFrame = toDataFrame({ const f: DataFrame = toDataFrame({
@ -186,7 +186,7 @@ describe('applyFieldOverrides', () => {
expect(outField.config.min).toEqual(0); expect(outField.config.min).toEqual(0);
expect(outField.config.max).toEqual(100); expect(outField.config.max).toEqual(100);
expect(outField.config.unit).toEqual('ms'); expect(outField.config.unit).toEqual('ms');
expect(getFieldTitle(outField, f)).toEqual('newTitle'); expect(getFieldDisplayName(outField, f)).toEqual('newTitle');
}); });
it('will apply field overrides', () => { it('will apply field overrides', () => {
@ -210,7 +210,7 @@ describe('applyFieldOverrides', () => {
expect(config.unit).toEqual('xyz'); expect(config.unit).toEqual('xyz');
// The default value applied // The default value applied
expect(config.title).toEqual('Kittens'); expect(config.displayName).toEqual('Kittens');
// The override applied // The override applied
expect(config.decimals).toEqual(1); expect(config.decimals).toEqual(1);
@ -309,13 +309,13 @@ describe('setFieldConfigDefaults', () => {
describe('setDynamicConfigValue', () => { describe('setDynamicConfigValue', () => {
it('applies dynamic config values', () => { it('applies dynamic config values', () => {
const config = { const config = {
title: 'test', displayName: 'test',
}; };
setDynamicConfigValue( setDynamicConfigValue(
config, config,
{ {
id: 'title', id: 'displayName',
value: 'applied', value: 'applied',
}, },
{ {
@ -326,7 +326,7 @@ describe('setDynamicConfigValue', () => {
} }
); );
expect(config.title).toEqual('applied'); expect(config.displayName).toEqual('applied');
}); });
it('applies custom dynamic config values', () => { it('applies custom dynamic config values', () => {
@ -379,7 +379,7 @@ describe('setDynamicConfigValue', () => {
it('removes properties', () => { it('removes properties', () => {
const config = { const config = {
title: 'title', displayName: 'title',
custom: { custom: {
property3: { property3: {
nested: 1, nested: 1,
@ -403,7 +403,7 @@ describe('setDynamicConfigValue', () => {
setDynamicConfigValue( setDynamicConfigValue(
config, config,
{ {
id: 'title', id: 'displayName',
value: undefined, value: undefined,
}, },
{ {
@ -415,6 +415,6 @@ describe('setDynamicConfigValue', () => {
); );
expect(config.custom.property3).toEqual({}); expect(config.custom.property3).toEqual({});
expect(config.title).toBeUndefined(); expect(config.displayName).toBeUndefined();
}); });
}); });

View File

@ -31,7 +31,7 @@ import { DataLinkBuiltInVars, locationUtil } from '../utils';
import { formattedValueToString } from '../valueFormats'; import { formattedValueToString } from '../valueFormats';
import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy';
import { formatLabels } from '../utils/labels'; import { formatLabels } from '../utils/labels';
import { getFrameDisplayTitle, getFieldTitle } from './fieldState'; import { getFrameDisplayName, getFieldDisplayName } from './fieldState';
import { getTimeField } from '../dataframe/processDataFrame'; import { getTimeField } from '../dataframe/processDataFrame';
interface OverrideProps { interface OverrideProps {
@ -100,18 +100,18 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra
return options.data.map((frame, index) => { return options.data.map((frame, index) => {
const scopedVars: ScopedVars = { const scopedVars: ScopedVars = {
__series: { text: 'Series', value: { name: getFrameDisplayTitle(frame, index) } }, // might be missing __series: { text: 'Series', value: { name: getFrameDisplayName(frame, index) } }, // might be missing
}; };
const fields: Field[] = frame.fields.map(field => { const fields: Field[] = frame.fields.map(field => {
// Config is mutable within this scope // Config is mutable within this scope
const fieldScopedVars = { ...scopedVars }; const fieldScopedVars = { ...scopedVars };
const title = getFieldTitle(field, frame, options.data); const displayName = getFieldDisplayName(field, frame, options.data);
fieldScopedVars['__field'] = { fieldScopedVars['__field'] = {
text: 'Field', text: 'Field',
value: { value: {
name: title, // Generally appropriate (may include the series name if useful) name: displayName, // Generally appropriate (may include the series name if useful)
labels: formatLabels(field.labels!), labels: formatLabels(field.labels!),
label: field.labels, label: field.labels,
}, },
@ -119,8 +119,8 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra
field.state = { field.state = {
...field.state, ...field.state,
title: title,
scopedVars: fieldScopedVars, scopedVars: fieldScopedVars,
displayName,
}; };
const config: FieldConfig = { ...field.config }; const config: FieldConfig = { ...field.config };
@ -194,7 +194,7 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra
type, type,
state: { state: {
...field.state, ...field.state,
title: null, displayName: null,
}, },
}; };

View File

@ -1,5 +1,5 @@
import { DataFrame, TIME_SERIES_FIELD_NAME, FieldType } from '../types'; import { DataFrame, TIME_SERIES_VALUE_FIELD_NAME, FieldType } from '../types';
import { getFieldTitle } from './fieldState'; import { getFieldDisplayName } from './fieldState';
import { toDataFrame } from '../dataframe'; import { toDataFrame } from '../dataframe';
interface TitleScenario { interface TitleScenario {
@ -11,10 +11,10 @@ interface TitleScenario {
function checkScenario(scenario: TitleScenario): string { function checkScenario(scenario: TitleScenario): string {
const frame = scenario.frames[scenario.frameIndex ?? 0]; const frame = scenario.frames[scenario.frameIndex ?? 0];
const field = frame.fields[scenario.fieldIndex ?? 0]; const field = frame.fields[scenario.fieldIndex ?? 0];
return getFieldTitle(field, frame, scenario.frames); return getFieldDisplayName(field, frame, scenario.frames);
} }
describe('Check field state calculations (title and id)', () => { describe('Check field state calculations (displayName and id)', () => {
it('should use field name if no frame name', () => { it('should use field name if no frame name', () => {
const title = checkScenario({ const title = checkScenario({
frames: [ frames: [
@ -92,23 +92,23 @@ describe('Check field state calculations (title and id)', () => {
expect(title).toEqual('{mode="B", server="Server A"}'); expect(title).toEqual('{mode="B", server="Server A"}');
}); });
it('should use field name even when it is TIME_SERIES_FIELD_NAME if there are no labels', () => { it('should use field name even when it is TIME_SERIES_VALUE_FIELD_NAME if there are no labels', () => {
const title = checkScenario({ const title = checkScenario({
frames: [ frames: [
toDataFrame({ toDataFrame({
fields: [{ name: TIME_SERIES_FIELD_NAME, labels: {} }], fields: [{ name: TIME_SERIES_VALUE_FIELD_NAME, labels: {} }],
}), }),
], ],
}); });
expect(title).toEqual('Value'); expect(title).toEqual('Value');
}); });
it('should use series name when field name is TIME_SERIES_FIELD_NAME and there are no labels ', () => { it('should use series name when field name is TIME_SERIES_VALUE_FIELD_NAME and there are no labels ', () => {
const title = checkScenario({ const title = checkScenario({
frames: [ frames: [
toDataFrame({ toDataFrame({
name: 'Series A', name: 'Series A',
fields: [{ name: TIME_SERIES_FIELD_NAME, labels: {} }], fields: [{ name: TIME_SERIES_VALUE_FIELD_NAME, labels: {} }],
}), }),
], ],
}); });

View File

@ -1,10 +1,10 @@
import { DataFrame, Field, TIME_SERIES_FIELD_NAME, FieldType } from '../types'; import { DataFrame, Field, TIME_SERIES_VALUE_FIELD_NAME, FieldType, TIME_SERIES_TIME_FIELD_NAME } from '../types';
import { formatLabels } from '../utils/labels'; import { formatLabels } from '../utils/labels';
/** /**
* Get an appropriate display title * Get an appropriate display title
*/ */
export function getFrameDisplayTitle(frame: DataFrame, index?: number) { export function getFrameDisplayName(frame: DataFrame, index?: number) {
if (frame.name) { if (frame.name) {
return frame.name; return frame.name;
} }
@ -19,7 +19,7 @@ export function getFrameDisplayTitle(frame: DataFrame, index?: number) {
if (index === undefined) { if (index === undefined) {
return frame.fields return frame.fields
.filter(f => f.type !== FieldType.time) .filter(f => f.type !== FieldType.time)
.map(f => getFieldTitle(f, frame)) .map(f => getFieldDisplayName(f, frame))
.join(', '); .join(', ');
} }
@ -30,39 +30,39 @@ export function getFrameDisplayTitle(frame: DataFrame, index?: number) {
return `Series (${index})`; return `Series (${index})`;
} }
export function getFieldTitle(field: Field, frame?: DataFrame, allFrames?: DataFrame[]): string { export function getFieldDisplayName(field: Field, frame?: DataFrame, allFrames?: DataFrame[]): string {
const existingTitle = field.state?.title; const existingTitle = field.state?.displayName;
if (existingTitle) { if (existingTitle) {
return existingTitle; return existingTitle;
} }
const title = calculateFieldTitle(field, frame, allFrames); const displayName = calculateFieldDisplayName(field, frame, allFrames);
field.state = { field.state = {
...field.state, ...field.state,
title, displayName,
}; };
return title; return displayName;
} }
/** /**
* Get an appropriate display title. If the 'title' is set, use that * Get an appropriate display name. If the 'title' is set, use that
*/ */
function calculateFieldTitle(field: Field, frame?: DataFrame, allFrames?: DataFrame[]): string { function calculateFieldDisplayName(field: Field, frame?: DataFrame, allFrames?: DataFrame[]): string {
const hasConfigTitle = field.config?.title && field.config?.title.length; const hasConfigTitle = field.config?.displayName && field.config?.displayName.length;
let title = hasConfigTitle ? field.config!.title! : field.name; let displayName = hasConfigTitle ? field.config!.displayName! : field.name;
if (hasConfigTitle) { if (hasConfigTitle) {
return title; return displayName;
} }
// This is an ugly exception for time field // This is an ugly exception for time field
// For time series we should normally treat time field with same name // For time series we should normally treat time field with same name
// But in case it has a join source we should handle it as normal field // But in case it has a join source we should handle it as normal field
if (field.type === FieldType.time && !field.labels) { if (field.type === FieldType.time && !field.labels) {
return title ?? 'Time'; return displayName ?? TIME_SERIES_TIME_FIELD_NAME;
} }
let parts: string[] = []; let parts: string[] = [];
@ -86,7 +86,7 @@ function calculateFieldTitle(field: Field, frame?: DataFrame, allFrames?: DataFr
frameNameAdded = true; frameNameAdded = true;
} }
if (field.name && field.name !== TIME_SERIES_FIELD_NAME) { if (field.name && field.name !== TIME_SERIES_VALUE_FIELD_NAME) {
parts.push(field.name); parts.push(field.name);
} }
@ -106,7 +106,7 @@ function calculateFieldTitle(field: Field, frame?: DataFrame, allFrames?: DataFr
} }
// if we have not added frame name and no labels, and field name = Value, we should add frame name // if we have not added frame name and no labels, and field name = Value, we should add frame name
if (frame && !frameNameAdded && !labelsAdded && field.name === TIME_SERIES_FIELD_NAME) { if (frame && !frameNameAdded && !labelsAdded && field.name === TIME_SERIES_VALUE_FIELD_NAME) {
if (frame.name && frame.name.length > 0) { if (frame.name && frame.name.length > 0) {
parts.push(frame.name); parts.push(frame.name);
frameNameAdded = true; frameNameAdded = true;
@ -114,14 +114,14 @@ function calculateFieldTitle(field: Field, frame?: DataFrame, allFrames?: DataFr
} }
if (parts.length) { if (parts.length) {
title = parts.join(' '); displayName = parts.join(' ');
} else if (field.name) { } else if (field.name) {
title = field.name; displayName = field.name;
} else { } else {
title = TIME_SERIES_FIELD_NAME; displayName = TIME_SERIES_VALUE_FIELD_NAME;
} }
return title; return displayName;
} }
/** /**

View File

@ -13,7 +13,7 @@ describe('getFieldDisplayValuesProxy', () => {
name: 'power', name: 'power',
values: [100, 200, 300], values: [100, 200, 300],
config: { config: {
title: 'The Power', displayName: 'The Power',
}, },
}, },
{ {
@ -54,7 +54,7 @@ describe('getFieldDisplayValuesProxy', () => {
expect(time2.toString()).toEqual(time.toString()); expect(time2.toString()).toEqual(time.toString());
}); });
it('Lookup by name, index, or title', () => { it('Lookup by name, index, or displayName', () => {
const p = getFieldDisplayValuesProxy(data, 2, { const p = getFieldDisplayValuesProxy(data, 2, {
theme: {} as GrafanaTheme, theme: {} as GrafanaTheme,
}); });

View File

@ -29,7 +29,7 @@ export function getFieldDisplayValuesProxy(
} }
if (!field) { if (!field) {
// 3. Match the title // 3. Match the title
field = frame.fields.find(f => key === f.config.title); field = frame.fields.find(f => key === f.config.displayName);
} }
if (!field) { if (!field) {
return undefined; return undefined;

View File

@ -7,4 +7,4 @@ export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry';
export { applyFieldOverrides, validateFieldConfig } from './fieldOverrides'; export { applyFieldOverrides, validateFieldConfig } from './fieldOverrides';
export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy';
export { getFieldTitle, getFrameDisplayTitle } from './fieldState'; export { getFieldDisplayName, getFrameDisplayName } from './fieldState';

View File

@ -2,7 +2,7 @@ import { Field, DataFrame } from '../../types/dataFrame';
import { FieldMatcherID, FrameMatcherID } from './ids'; import { FieldMatcherID, FrameMatcherID } from './ids';
import { FieldMatcherInfo, FrameMatcherInfo } from '../../types/transformations'; import { FieldMatcherInfo, FrameMatcherInfo } from '../../types/transformations';
import { stringToJsRegex } from '../../text/string'; import { stringToJsRegex } from '../../text/string';
import { getFieldTitle } from '../../field/fieldState'; import { getFieldDisplayName } from '../../field/fieldState';
// General Field matcher // General Field matcher
const fieldNameMacher: FieldMatcherInfo<string> = { const fieldNameMacher: FieldMatcherInfo<string> = {
@ -19,7 +19,7 @@ const fieldNameMacher: FieldMatcherInfo<string> = {
console.error(e); console.error(e);
} }
return (field: Field) => { return (field: Field) => {
return regex.test(getFieldTitle(field) ?? ''); return regex.test(getFieldDisplayName(field) ?? '');
}; };
}, },

View File

@ -50,19 +50,19 @@ describe('OrganizeFields Transformer', () => {
labels: undefined, labels: undefined,
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature', displayName: 'temperature',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10.3, 10.4, 10.5, 10.6]), values: new ArrayVector([10.3, 10.4, 10.5, 10.6]),
}, },
{ {
config: { config: {
title: 'renamed_humidity', displayName: 'renamed_humidity',
}, },
labels: undefined, labels: undefined,
name: 'humidity', name: 'humidity',
state: { state: {
title: 'renamed_humidity', displayName: 'renamed_humidity',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]), values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]),
@ -105,11 +105,11 @@ describe('OrganizeFields Transformer', () => {
{ {
labels: undefined, labels: undefined,
config: { config: {
title: 'renamed_time', displayName: 'renamed_time',
}, },
name: 'time', name: 'time',
state: { state: {
title: 'renamed_time', displayName: 'renamed_time',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([3000, 4000, 5000, 6000]), values: new ArrayVector([3000, 4000, 5000, 6000]),
@ -119,7 +119,7 @@ describe('OrganizeFields Transformer', () => {
labels: undefined, labels: undefined,
name: 'pressure', name: 'pressure',
state: { state: {
title: 'pressure', displayName: 'pressure',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10.3, 10.4, 10.5, 10.6]), values: new ArrayVector([10.3, 10.4, 10.5, 10.6]),

View File

@ -65,25 +65,25 @@ describe('Reducer Transformer', () => {
name: 'first', name: 'first',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 10000.3, 1, 11000.1]), values: new ArrayVector([3, 10000.3, 1, 11000.1]),
config: { title: 'First' }, config: { displayName: 'First' },
}, },
{ {
name: 'min', name: 'min',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 10000.3, 1, 11000.1]), values: new ArrayVector([3, 10000.3, 1, 11000.1]),
config: { title: 'Min' }, config: { displayName: 'Min' },
}, },
{ {
name: 'max', name: 'max',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 10000.6, 7, 11000.7]), values: new ArrayVector([6, 10000.6, 7, 11000.7]),
config: { title: 'Max' }, config: { displayName: 'Max' },
}, },
{ {
name: 'last', name: 'last',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 10000.6, 7, 11000.7]), values: new ArrayVector([6, 10000.6, 7, 11000.7]),
config: { title: 'Last' }, config: { displayName: 'Last' },
}, },
]; ];
@ -111,25 +111,25 @@ describe('Reducer Transformer', () => {
name: 'first', name: 'first',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 1]), values: new ArrayVector([3, 1]),
config: { title: 'First' }, config: { displayName: 'First' },
}, },
{ {
name: 'min', name: 'min',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 1]), values: new ArrayVector([3, 1]),
config: { title: 'Min' }, config: { displayName: 'Min' },
}, },
{ {
name: 'max', name: 'max',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 7]), values: new ArrayVector([6, 7]),
config: { title: 'Max' }, config: { displayName: 'Max' },
}, },
{ {
name: 'last', name: 'last',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 7]), values: new ArrayVector([6, 7]),
config: { title: 'Last' }, config: { displayName: 'Last' },
}, },
]; ];
@ -157,25 +157,25 @@ describe('Reducer Transformer', () => {
name: 'first', name: 'first',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 10000.3]), values: new ArrayVector([3, 10000.3]),
config: { title: 'First' }, config: { displayName: 'First' },
}, },
{ {
name: 'min', name: 'min',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3, 10000.3]), values: new ArrayVector([3, 10000.3]),
config: { title: 'Min' }, config: { displayName: 'Min' },
}, },
{ {
name: 'max', name: 'max',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 10000.6]), values: new ArrayVector([6, 10000.6]),
config: { title: 'Max' }, config: { displayName: 'Max' },
}, },
{ {
name: 'last', name: 'last',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6, 10000.6]), values: new ArrayVector([6, 10000.6]),
config: { title: 'Last' }, config: { displayName: 'Last' },
}, },
]; ];
@ -203,25 +203,25 @@ describe('Reducer Transformer', () => {
name: 'first', name: 'first',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3]), values: new ArrayVector([3]),
config: { title: 'First' }, config: { displayName: 'First' },
}, },
{ {
name: 'min', name: 'min',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([3]), values: new ArrayVector([3]),
config: { title: 'Min' }, config: { displayName: 'Min' },
}, },
{ {
name: 'max', name: 'max',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6]), values: new ArrayVector([6]),
config: { title: 'Max' }, config: { displayName: 'Max' },
}, },
{ {
name: 'last', name: 'last',
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([6]), values: new ArrayVector([6]),
config: { title: 'Last' }, config: { displayName: 'Last' },
}, },
]; ];

View File

@ -59,7 +59,7 @@ export const reduceTransformer: DataTransformerInfo<ReduceTransformerOptions> =
type: FieldType.other, // UNKNOWN until after we call the functions type: FieldType.other, // UNKNOWN until after we call the functions
values: values[values.length - 1], values: values[values.length - 1],
config: { config: {
title: info.name, displayName: info.name,
// UNIT from original field? // UNIT from original field?
}, },
}); });

View File

@ -41,36 +41,36 @@ describe('Rename Transformer', () => {
expect(renamed.fields).toEqual([ expect(renamed.fields).toEqual([
{ {
config: { config: {
title: 'Total time', displayName: 'Total time',
}, },
labels: undefined, labels: undefined,
name: 'time', name: 'time',
state: { state: {
title: 'Total time', displayName: 'Total time',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([3000, 4000, 5000, 6000]), values: new ArrayVector([3000, 4000, 5000, 6000]),
}, },
{ {
config: { config: {
title: 'how cold is it?', displayName: 'how cold is it?',
}, },
labels: undefined, labels: undefined,
name: 'temperature', name: 'temperature',
state: { state: {
title: 'how cold is it?', displayName: 'how cold is it?',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10.3, 10.4, 10.5, 10.6]), values: new ArrayVector([10.3, 10.4, 10.5, 10.6]),
}, },
{ {
config: { config: {
title: 'Moistiness', displayName: 'Moistiness',
}, },
name: 'humidity', name: 'humidity',
labels: undefined, labels: undefined,
state: { state: {
title: 'Moistiness', displayName: 'Moistiness',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]), values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]),
@ -106,12 +106,12 @@ describe('Rename Transformer', () => {
expect(renamed.fields).toEqual([ expect(renamed.fields).toEqual([
{ {
config: { config: {
title: 'ttl', displayName: 'ttl',
}, },
name: 'time', name: 'time',
labels: undefined, labels: undefined,
state: { state: {
title: 'ttl', displayName: 'ttl',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([3000, 4000, 5000, 6000]), values: new ArrayVector([3000, 4000, 5000, 6000]),
@ -121,19 +121,19 @@ describe('Rename Transformer', () => {
labels: undefined, labels: undefined,
name: 'pressure', name: 'pressure',
state: { state: {
title: 'pressure', displayName: 'pressure',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10.3, 10.4, 10.5, 10.6]), values: new ArrayVector([10.3, 10.4, 10.5, 10.6]),
}, },
{ {
config: { config: {
title: 'hum', displayName: 'hum',
}, },
labels: undefined, labels: undefined,
name: 'humidity', name: 'humidity',
state: { state: {
title: 'hum', displayName: 'hum',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]), values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6]),

View File

@ -1,7 +1,7 @@
import { DataTransformerID } from './ids'; import { DataTransformerID } from './ids';
import { DataTransformerInfo } from '../../types/transformations'; import { DataTransformerInfo } from '../../types/transformations';
import { DataFrame, Field } from '../../types/dataFrame'; import { DataFrame, Field } from '../../types/dataFrame';
import { getFieldTitle } from '../../field/fieldState'; import { getFieldDisplayName } from '../../field/fieldState';
export interface RenameFieldsTransformerOptions { export interface RenameFieldsTransformerOptions {
renameByName: Record<string, string>; renameByName: Record<string, string>;
@ -41,8 +41,8 @@ const createRenamer = (renameByName: Record<string, string>) => (frame: DataFram
} }
return frame.fields.map(field => { return frame.fields.map(field => {
const title = getFieldTitle(field, frame); const displayName = getFieldDisplayName(field, frame);
const renameTo = renameByName[title]; const renameTo = renameByName[displayName];
if (typeof renameTo !== 'string' || renameTo.length === 0) { if (typeof renameTo !== 'string' || renameTo.length === 0) {
return field; return field;
@ -52,11 +52,11 @@ const createRenamer = (renameByName: Record<string, string>) => (frame: DataFram
...field, ...field,
config: { config: {
...field.config, ...field.config,
title: renameTo, displayName: renameTo,
}, },
state: { state: {
...field.state, ...field.state,
title: renameTo, displayName: renameTo,
}, },
}; };
}); });

View File

@ -46,7 +46,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'time', name: 'time',
state: { state: {
title: 'time', displayName: 'time',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([1000, 3000, 4000, 5000, 6000, 7000]), values: new ArrayVector([1000, 3000, 4000, 5000, 6000, 7000]),
@ -56,7 +56,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature even', displayName: 'temperature even',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([null, 10.3, 10.4, 10.5, 10.6, null]), values: new ArrayVector([null, 10.3, 10.4, 10.5, 10.6, null]),
@ -66,7 +66,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity even', displayName: 'humidity even',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([null, 10000.3, 10000.4, 10000.5, 10000.6, null]), values: new ArrayVector([null, 10000.3, 10000.4, 10000.5, 10000.6, null]),
@ -76,7 +76,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature odd', displayName: 'temperature odd',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([11.1, 11.3, null, 11.5, null, 11.7]), values: new ArrayVector([11.1, 11.3, null, 11.5, null, 11.7]),
@ -86,7 +86,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity odd', displayName: 'humidity odd',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([11000.1, 11000.3, null, 11000.5, null, 11000.7]), values: new ArrayVector([11000.1, 11000.3, null, 11000.5, null, 11000.7]),
@ -109,7 +109,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature', displayName: 'temperature',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10.3, 10.4, 10.5, 10.6, 11.1, 11.3, 11.5, 11.7]), values: new ArrayVector([10.3, 10.4, 10.5, 10.6, 11.1, 11.3, 11.5, 11.7]),
@ -119,7 +119,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'time', name: 'time',
state: { state: {
title: 'time even', displayName: 'time even',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([3000, 4000, 5000, 6000, null, null, null, null]), values: new ArrayVector([3000, 4000, 5000, 6000, null, null, null, null]),
@ -129,7 +129,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity even', displayName: 'humidity even',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6, null, null, null, null]), values: new ArrayVector([10000.3, 10000.4, 10000.5, 10000.6, null, null, null, null]),
@ -139,7 +139,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'time', name: 'time',
state: { state: {
title: 'time odd', displayName: 'time odd',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([null, null, null, null, 1000, 3000, 5000, 7000]), values: new ArrayVector([null, null, null, null, 1000, 3000, 5000, 7000]),
@ -149,7 +149,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity odd', displayName: 'humidity odd',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([null, null, null, null, 11000.1, 11000.3, 11000.5, 11000.7]), values: new ArrayVector([null, null, null, null, 11000.1, 11000.3, 11000.5, 11000.7]),
@ -176,7 +176,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'time', name: 'time',
state: { state: {
title: 'time', displayName: 'time',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([1000, 3000, 4000, 5000, 6000, 7000]), values: new ArrayVector([1000, 3000, 4000, 5000, 6000, 7000]),
@ -186,7 +186,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature even', displayName: 'temperature even',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([null, 10.3, 10.4, 10.5, 10.6, null]), values: new ArrayVector([null, 10.3, 10.4, 10.5, 10.6, null]),
@ -196,7 +196,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity even', displayName: 'humidity even',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([null, 10000.3, 10000.4, 10000.5, 10000.6, null]), values: new ArrayVector([null, 10000.3, 10000.4, 10000.5, 10000.6, null]),
@ -206,7 +206,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature odd', displayName: 'temperature odd',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([11.1, 11.3, null, 11.5, null, 11.7]), values: new ArrayVector([11.1, 11.3, null, 11.5, null, 11.7]),
@ -216,7 +216,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'humidity', name: 'humidity',
state: { state: {
title: 'humidity odd', displayName: 'humidity odd',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([11000.1, 11000.3, null, 11000.5, null, 11000.7]), values: new ArrayVector([11000.1, 11000.3, null, 11000.5, null, 11000.7]),
@ -256,7 +256,7 @@ describe('SeriesToColumns Transformer', () => {
{ {
name: 'time', name: 'time',
state: { state: {
title: 'time', displayName: 'time',
}, },
type: FieldType.time, type: FieldType.time,
values: new ArrayVector([1000, 2000, 3000, 4000]), values: new ArrayVector([1000, 2000, 3000, 4000]),
@ -269,14 +269,14 @@ describe('SeriesToColumns Transformer', () => {
values: new ArrayVector([1, 3, 5, 7]), values: new ArrayVector([1, 3, 5, 7]),
config: {}, config: {},
state: { state: {
title: 'temperature temperature', displayName: 'temperature temperature',
}, },
labels: { name: 'temperature' }, labels: { name: 'temperature' },
}, },
{ {
name: 'temperature', name: 'temperature',
state: { state: {
title: 'temperature B', displayName: 'temperature B',
}, },
type: FieldType.number, type: FieldType.number,
values: new ArrayVector([2, 4, 6, 8]), values: new ArrayVector([2, 4, 6, 8]),

View File

@ -2,7 +2,7 @@ import { DataFrame, DataTransformerInfo, Field } from '../../types';
import { DataTransformerID } from './ids'; import { DataTransformerID } from './ids';
import { MutableDataFrame } from '../../dataframe'; import { MutableDataFrame } from '../../dataframe';
import { ArrayVector } from '../../vector'; import { ArrayVector } from '../../vector';
import { getFieldTitle } from '../../field/fieldState'; import { getFieldDisplayName } from '../../field/fieldState';
export interface SeriesToColumnsOptions { export interface SeriesToColumnsOptions {
byField?: string; byField?: string;
@ -71,7 +71,7 @@ export const seriesToColumnsTransformer: DataTransformerInfo<SeriesToColumnsOpti
resultFrame.addField(item.newField); resultFrame.addField(item.newField);
} }
const keyFieldTitle = getFieldTitle(resultFrame.fields[0], resultFrame); const keyFieldTitle = getFieldDisplayName(resultFrame.fields[0], resultFrame);
const byKeyField: { [key: string]: { [key: string]: any } } = {}; const byKeyField: { [key: string]: { [key: string]: any } } = {};
/* /*
@ -92,7 +92,7 @@ export const seriesToColumnsTransformer: DataTransformerInfo<SeriesToColumnsOpti
for (let fieldIndex = 0; fieldIndex < allFields.length; fieldIndex++) { for (let fieldIndex = 0; fieldIndex < allFields.length; fieldIndex++) {
const { sourceField, keyField, newField } = allFields[fieldIndex]; const { sourceField, keyField, newField } = allFields[fieldIndex];
const newFieldTitle = getFieldTitle(newField, resultFrame); const newFieldTitle = getFieldDisplayName(newField, resultFrame);
for (let valueIndex = 0; valueIndex < sourceField.values.length; valueIndex++) { for (let valueIndex = 0; valueIndex < sourceField.values.length; valueIndex++) {
const value = sourceField.values.get(valueIndex); const value = sourceField.values.get(valueIndex);
@ -112,7 +112,7 @@ export const seriesToColumnsTransformer: DataTransformerInfo<SeriesToColumnsOpti
for (let fieldIndex = 0; fieldIndex < resultFrame.fields.length; fieldIndex++) { for (let fieldIndex = 0; fieldIndex < resultFrame.fields.length; fieldIndex++) {
const field = resultFrame.fields[fieldIndex]; const field = resultFrame.fields[fieldIndex];
const otherColumnName = getFieldTitle(field, resultFrame); const otherColumnName = getFieldDisplayName(field, resultFrame);
const value = byKeyField[keyValueAsString][otherColumnName] ?? null; const value = byKeyField[keyValueAsString][otherColumnName] ?? null;
field.values.add(value); field.values.add(value);
} }
@ -126,7 +126,7 @@ function findKeyField(frame: DataFrame, matchTitle: string): Field | null {
for (let fieldIndex = 0; fieldIndex < frame.fields.length; fieldIndex++) { for (let fieldIndex = 0; fieldIndex < frame.fields.length; fieldIndex++) {
const field = frame.fields[fieldIndex]; const field = frame.fields[fieldIndex];
if (matchTitle === getFieldTitle(field)) { if (matchTitle === getFieldDisplayName(field)) {
return field; return field;
} }
} }

View File

@ -46,7 +46,7 @@ export interface QueryResultMeta {
} }
export interface QueryResultMetaStat extends FieldConfig { export interface QueryResultMetaStat extends FieldConfig {
title: string; displayName: string;
value: number; value: number;
} }

View File

@ -23,7 +23,7 @@ export enum FieldType {
* Plugins may extend this with additional properties. Something like series overrides * Plugins may extend this with additional properties. Something like series overrides
*/ */
export interface FieldConfig<TOptions extends object = any> { export interface FieldConfig<TOptions extends object = any> {
title?: string; // The display value for this field. This supports template variables blank is auto displayName?: string; // The display value for this field. This supports template variables blank is auto
filterable?: boolean; filterable?: boolean;
// Numeric Options // Numeric Options
@ -106,7 +106,7 @@ export interface FieldState {
/** /**
* An appropriate name for the field (does not include frame info) * An appropriate name for the field (does not include frame info)
*/ */
title?: string | null; displayName?: string | null;
/** /**
* Cache of reduced values * Cache of reduced values
@ -148,4 +148,5 @@ export interface DataFrameDTO extends QueryResultBase {
export interface FieldCalcs extends Record<string, any> {} export interface FieldCalcs extends Record<string, any> {}
export const TIME_SERIES_FIELD_NAME = 'Value'; export const TIME_SERIES_VALUE_FIELD_NAME = 'Value';
export const TIME_SERIES_TIME_FIELD_NAME = 'Time';

View File

@ -3,10 +3,10 @@ import { ThresholdsMode } from '../../types';
export const mockStandardProperties = () => { export const mockStandardProperties = () => {
const title = { const title = {
id: 'title', id: 'displayName',
path: 'title', path: 'displayName',
name: 'Title', name: 'Display name',
description: "Field's title", description: "Field's display name",
editor: () => null, editor: () => null,
override: () => null, override: () => null,
process: identityOverrideProcessor, process: identityOverrideProcessor,

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types';
import { FieldMatcherID, fieldMatchers, getFieldTitle } from '@grafana/data'; import { FieldMatcherID, fieldMatchers, getFieldDisplayName } from '@grafana/data';
import { Select } from '../Select/Select'; import { Select } from '../Select/Select';
export class FieldNameMatcherEditor extends React.PureComponent<MatcherUIProps<string>> { export class FieldNameMatcherEditor extends React.PureComponent<MatcherUIProps<string>> {
@ -10,7 +10,7 @@ export class FieldNameMatcherEditor extends React.PureComponent<MatcherUIProps<s
for (const frame of data) { for (const frame of data) {
for (const field of frame.fields) { for (const field of frame.fields) {
names.add(getFieldTitle(field, frame, data)); names.add(getFieldDisplayName(field, frame, data));
} }
} }
if (options) { if (options) {

View File

@ -156,6 +156,29 @@ describe('sharedSingleStatMigrationHandler', () => {
`); `);
}); });
it('Rename title to displayName', () => {
const panel = {
options: {
fieldOptions: {
stat: 'last',
decimals: 5,
defaults: {
title: 'newTitle',
min: 0,
max: 100,
mappings: [],
},
override: {},
},
},
title: 'Usage',
type: 'bargauge',
};
sharedSingleStatMigrationHandler(panel as any);
expect((panel as any).fieldConfig.defaults.displayName).toBe('newTitle');
});
it('change from angular singlestat with no enabled gauge', () => { it('change from angular singlestat with no enabled gauge', () => {
const old: any = { const old: any = {
angular: { angular: {

View File

@ -202,6 +202,15 @@ export function sharedSingleStatMigrationHandler(panel: PanelModel<SingleStatBas
delete options.fieldOptions; delete options.fieldOptions;
} }
if (previousVersion < 7.1) {
// move title to displayName
const oldTitle = (panel.fieldConfig.defaults as any).title;
if (oldTitle !== undefined && oldTitle !== null) {
panel.fieldConfig.defaults.displayName = oldTitle;
delete (panel.fieldConfig.defaults as any).title;
}
}
return options as SingleStatBaseOptions; return options as SingleStatBaseOptions;
} }

View File

@ -1,5 +1,5 @@
import { TextAlignProperty } from 'csstype'; import { TextAlignProperty } from 'csstype';
import { DataFrame, Field, FieldType, getFieldTitle } from '@grafana/data'; import { DataFrame, Field, FieldType, getFieldDisplayName } from '@grafana/data';
import { Column } from 'react-table'; import { Column } from 'react-table';
import { DefaultCell } from './DefaultCell'; import { DefaultCell } from './DefaultCell';
import { BarGaugeCell } from './BarGaugeCell'; import { BarGaugeCell } from './BarGaugeCell';
@ -51,7 +51,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid
columns.push({ columns.push({
Cell, Cell,
id: fieldIndex.toString(), id: fieldIndex.toString(),
Header: getFieldTitle(field, data), Header: getFieldDisplayName(field, data),
accessor: (row: any, i: number) => { accessor: (row: any, i: number) => {
return field.values.get(i); return field.values.get(i);
}, },

View File

@ -33,11 +33,11 @@ import { StatsPickerEditor } from '../components/OptionsUI/stats';
*/ */
export const getStandardFieldConfigs = () => { export const getStandardFieldConfigs = () => {
const category = ['Standard options']; const category = ['Standard options'];
const title: FieldConfigPropertyItem<any, string, StringFieldConfigSettings> = { const displayName: FieldConfigPropertyItem<any, string, StringFieldConfigSettings> = {
id: 'title', id: 'displayName',
path: 'title', path: 'displayName',
name: 'Title', name: 'Display name',
description: "Field's title", description: 'Change the field or series name',
editor: standardEditorsRegistry.get('text').editor as any, editor: standardEditorsRegistry.get('text').editor as any,
override: standardEditorsRegistry.get('text').editor as any, override: standardEditorsRegistry.get('text').editor as any,
process: stringOverrideProcessor, process: stringOverrideProcessor,
@ -206,7 +206,7 @@ export const getStandardFieldConfigs = () => {
// category: ['Color & thresholds'], // category: ['Color & thresholds'],
// }; // };
return [unit, min, max, decimals, title, noValue, thresholds, mappings, links]; return [unit, min, max, decimals, displayName, noValue, thresholds, mappings, links];
}; };
/** /**

View File

@ -11,7 +11,7 @@ import {
BinaryOperationID, BinaryOperationID,
SelectableValue, SelectableValue,
binaryOperators, binaryOperators,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { Select, StatsPicker, LegacyForms, Input, FilterPill, HorizontalGroup } from '@grafana/ui'; import { Select, StatsPicker, LegacyForms, Input, FilterPill, HorizontalGroup } from '@grafana/ui';
import { import {
@ -75,11 +75,11 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
continue; continue;
} }
const title = getFieldTitle(field, frame, input); const displayName = getFieldDisplayName(field, frame, input);
if (!byName[title]) { if (!byName[displayName]) {
byName[title] = true; byName[displayName] = true;
allNames.push(title); allNames.push(displayName);
} }
} }
} }

View File

@ -5,7 +5,7 @@ import {
standardTransformers, standardTransformers,
TransformerRegistyItem, TransformerRegistyItem,
TransformerUIProps, TransformerUIProps,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { Field, Input, FilterPill, HorizontalGroup } from '@grafana/ui'; import { Field, Input, FilterPill, HorizontalGroup } from '@grafana/ui';
import { css } from 'emotion'; import { css } from 'emotion';
@ -58,15 +58,17 @@ export class FilterByNameTransformerEditor extends React.PureComponent<
for (const frame of input) { for (const frame of input) {
for (const field of frame.fields) { for (const field of frame.fields) {
const id = getFieldTitle(field, frame, input); const displayName = getFieldDisplayName(field, frame, input);
let v = byName[id]; let v = byName[displayName];
if (!v) { if (!v) {
v = byName[id] = { v = byName[displayName] = {
name: id, name: displayName,
count: 0, count: 0,
}; };
allNames.push(v); allNames.push(v);
} }
v.count++; v.count++;
} }
} }

View File

@ -8,7 +8,7 @@ import {
standardTransformers, standardTransformers,
TransformerRegistyItem, TransformerRegistyItem,
TransformerUIProps, TransformerUIProps,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { stylesFactory, useTheme, Input, IconButton } from '@grafana/ui'; import { stylesFactory, useTheme, Input, IconButton } from '@grafana/ui';
@ -215,7 +215,7 @@ export const getAllFieldNamesFromDataFrames = (input: DataFrame[]): string[] =>
} }
return frame.fields.reduce((names, field) => { return frame.fields.reduce((names, field) => {
const t = getFieldTitle(field, frame, input); const t = getFieldDisplayName(field, frame, input);
names[t] = true; names[t] = true;
return names; return names;
}, names); }, names);

View File

@ -387,7 +387,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel | undefi
for (const series of logSeries) { for (const series of logSeries) {
const totalBytesKey = series.meta?.custom?.lokiQueryStatKey; const totalBytesKey = series.meta?.custom?.lokiQueryStatKey;
if (totalBytesKey && series.meta.stats) { if (totalBytesKey && series.meta.stats) {
const byteStat = series.meta.stats.find(stat => stat.title === totalBytesKey); const byteStat = series.meta.stats.find(stat => stat.displayName === totalBytesKey);
if (byteStat) { if (byteStat) {
totalBytes += byteStat.value; totalBytes += byteStat.value;
} }

View File

@ -6,7 +6,7 @@ import {
SelectableValue, SelectableValue,
toCSV, toCSV,
transformDataFrame, transformDataFrame,
getFrameDisplayTitle, getFrameDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { Button, Field, Icon, Select, Table } from '@grafana/ui'; import { Button, Field, Icon, Select, Table } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -106,7 +106,7 @@ export class InspectDataTab extends PureComponent<Props, State> {
const choices = dataFrames.map((frame, index) => { const choices = dataFrames.map((frame, index) => {
return { return {
value: index, value: index,
label: `${getFrameDisplayTitle(frame)} (${index})`, label: `${getFrameDisplayName(frame)} (${index})`,
}; };
}); });

View File

@ -211,10 +211,10 @@ export class PanelInspectorUnconnected extends PureComponent<Props, State> {
dataRows += frame.length; dataRows += frame.length;
} }
stats.push({ title: 'Total request time', value: requestTime, unit: 'ms' }); stats.push({ displayName: 'Total request time', value: requestTime, unit: 'ms' });
stats.push({ title: 'Data processing time', value: processingTime, unit: 'ms' }); stats.push({ displayName: 'Data processing time', value: processingTime, unit: 'ms' });
stats.push({ title: 'Number of queries', value: request.targets.length }); stats.push({ displayName: 'Number of queries', value: request.targets.length });
stats.push({ title: 'Total number rows', value: dataRows }); stats.push({ displayName: 'Total number rows', value: dataRows });
let dataStats: QueryResultMetaStat[] = []; let dataStats: QueryResultMetaStat[] = [];
@ -245,8 +245,8 @@ export class PanelInspectorUnconnected extends PureComponent<Props, State> {
<tbody> <tbody>
{stats.map((stat, index) => { {stats.map((stat, index) => {
return ( return (
<tr key={`${stat.title}-${index}`}> <tr key={`${stat.displayName}-${index}`}>
<td>{stat.title}</td> <td>{stat.displayName}</td>
<td style={{ textAlign: 'right' }}>{formatStat(stat, dashboard.getTimezone())}</td> <td style={{ textAlign: 'right' }}>{formatStat(stat, dashboard.getTimezone())}</td>
</tr> </tr>
); );

View File

@ -3,7 +3,7 @@ import { supportsDataQuery } from './utils';
describe('standardFieldConfigEditorRegistry', () => { describe('standardFieldConfigEditorRegistry', () => {
const dummyConfig: FieldConfig = { const dummyConfig: FieldConfig = {
title: 'Hello', displayName: 'Hello',
min: 10, min: 10,
max: 10, max: 10,
decimals: 10, decimals: 10,

View File

@ -83,7 +83,7 @@ describe('getLinksFromLogsField', () => {
config: { config: {
unit: 'kW', unit: 'kW',
decimals: 3, decimals: 3,
title: 'TheTitle', displayName: 'TheTitle',
}, },
}, },
{ {

View File

@ -149,7 +149,7 @@ const getDataFrameVars = (dataFrames: DataFrame[]) => {
numeric = f; numeric = f;
} }
if (!title && f.config.title && f.config.title !== f.name) { if (!title && f.config.displayName && f.config.displayName !== f.name) {
title = f; title = f;
} }
} }
@ -181,7 +181,7 @@ const getDataFrameVars = (dataFrames: DataFrame[]) => {
if (title) { if (title) {
suggestions.push({ suggestions.push({
value: `__data.fields[${title.config.title}]`, value: `__data.fields[${title.config.displayName}]`,
label: `Select by title`, label: `Select by title`,
documentation: `Use the title to pick the field`, documentation: `Use the title to pick the field`,
origin: VariableOrigin.Fields, origin: VariableOrigin.Fields,

View File

@ -1,13 +1,7 @@
import '../datasource'; import '../datasource';
import { CloudWatchDatasource, MAX_ATTEMPTS } from '../datasource'; import { CloudWatchDatasource, MAX_ATTEMPTS } from '../datasource';
import * as redux from 'app/store/store'; import * as redux from 'app/store/store';
import { import { DataSourceInstanceSettings, dateMath, getFrameDisplayName, DataFrame, DataQueryResponse } from '@grafana/data';
DataSourceInstanceSettings,
dateMath,
getFrameDisplayTitle,
DataFrame,
DataQueryResponse,
} from '@grafana/data';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { CustomVariable } from 'app/features/templating/all'; import { CustomVariable } from 'app/features/templating/all';
import { CloudWatchQuery, CloudWatchMetricsQuery, CloudWatchLogsQueryStatus, LogAction } from '../types'; import { CloudWatchQuery, CloudWatchMetricsQuery, CloudWatchLogsQueryStatus, LogAction } from '../types';
@ -379,7 +373,7 @@ describe('CloudWatchDatasource', () => {
it('should return series list', done => { it('should return series list', done => {
ctx.ds.query(query).then((result: any) => { ctx.ds.query(query).then((result: any) => {
expect(getFrameDisplayTitle(result.data[0])).toBe(response.results.A.series[0].name); expect(getFrameDisplayName(result.data[0])).toBe(response.results.A.series[0].name);
expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]);
done(); done();
}); });
@ -395,7 +389,7 @@ describe('CloudWatchDatasource', () => {
it('should be built correctly if theres one search expressions returned in meta for a given query row', done => { it('should be built correctly if theres one search expressions returned in meta for a given query row', done => {
response.results['A'].meta.gmdMeta = [{ Expression: `REMOVE_EMPTY(SEARCH('some expression'))`, Period: '300' }]; response.results['A'].meta.gmdMeta = [{ Expression: `REMOVE_EMPTY(SEARCH('some expression'))`, Period: '300' }];
ctx.ds.query(query).then((result: any) => { ctx.ds.query(query).then((result: any) => {
expect(getFrameDisplayTitle(result.data[0])).toBe(response.results.A.series[0].name); expect(getFrameDisplayName(result.data[0])).toBe(response.results.A.series[0].name);
expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console');
expect(decodeURIComponent(result.data[0].fields[1].config.links[0].url)).toContain( expect(decodeURIComponent(result.data[0].fields[1].config.links[0].url)).toContain(
`region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'some expression\'))"}]}` `region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'some expression\'))"}]}`
@ -410,7 +404,7 @@ describe('CloudWatchDatasource', () => {
{ Expression: `REMOVE_EMPTY(SEARCH('second expression'))` }, { Expression: `REMOVE_EMPTY(SEARCH('second expression'))` },
]; ];
ctx.ds.query(query).then((result: any) => { ctx.ds.query(query).then((result: any) => {
expect(getFrameDisplayTitle(result.data[0])).toBe(response.results.A.series[0].name); expect(getFrameDisplayName(result.data[0])).toBe(response.results.A.series[0].name);
expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console');
expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain( expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain(
`region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'first expression\'))"},{"expression":"REMOVE_EMPTY(SEARCH(\'second expression\'))"}]}` `region=us-east-1#metricsV2:graph={"view":"timeSeries","stacked":false,"title":"A","start":"2016-12-31T15:00:00.000Z","end":"2016-12-31T16:00:00.000Z","region":"us-east-1","metrics":[{"expression":"REMOVE_EMPTY(SEARCH(\'first expression\'))"},{"expression":"REMOVE_EMPTY(SEARCH(\'second expression\'))"}]}`
@ -422,7 +416,7 @@ describe('CloudWatchDatasource', () => {
it('should be built correctly if the query is a metric stat query', done => { it('should be built correctly if the query is a metric stat query', done => {
response.results['A'].meta.gmdMeta = [{ Period: '300' }]; response.results['A'].meta.gmdMeta = [{ Period: '300' }];
ctx.ds.query(query).then((result: any) => { ctx.ds.query(query).then((result: any) => {
expect(getFrameDisplayTitle(result.data[0])).toBe(response.results.A.series[0].name); expect(getFrameDisplayName(result.data[0])).toBe(response.results.A.series[0].name);
expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console'); expect(result.data[0].fields[1].config.links[0].title).toBe('View in CloudWatch console');
expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain( expect(decodeURIComponent(result.data[0].fields[0].config.links[0].url)).toContain(
`region=us-east-1#metricsV2:graph={\"view\":\"timeSeries\",\"stacked\":false,\"title\":\"A\",\"start\":\"2016-12-31T15:00:00.000Z\",\"end\":\"2016-12-31T16:00:00.000Z\",\"region\":\"us-east-1\",\"metrics\":[[\"AWS/EC2\",\"CPUUtilization\",\"InstanceId\",\"i-12345678\",{\"stat\":\"Average\",\"period\":\"300\"}]]}` `region=us-east-1#metricsV2:graph={\"view\":\"timeSeries\",\"stacked\":false,\"title\":\"A\",\"start\":\"2016-12-31T15:00:00.000Z\",\"end\":\"2016-12-31T16:00:00.000Z\",\"region\":\"us-east-1\",\"metrics\":[[\"AWS/EC2\",\"CPUUtilization\",\"InstanceId\",\"i-12345678\",{\"stat\":\"Average\",\"period\":\"300\"}]]}`
@ -663,7 +657,7 @@ describe('CloudWatchDatasource', () => {
it('should return series list', done => { it('should return series list', done => {
ctx.ds.query(query).then((result: any) => { ctx.ds.query(query).then((result: any) => {
expect(getFrameDisplayTitle(result.data[0])).toBe(response.results.A.series[0].name); expect(getFrameDisplayName(result.data[0])).toBe(response.results.A.series[0].name);
expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]); expect(result.data[0].fields[1].values.buffer[0]).toBe(response.results.A.series[0].points[0][0]);
done(); done();
}); });

View File

@ -1,5 +1,5 @@
import Datasource from '../datasource'; import Datasource from '../datasource';
import { DataFrame, toUtc, getFrameDisplayTitle } from '@grafana/data'; import { DataFrame, toUtc, getFrameDisplayName } from '@grafana/data';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
@ -175,7 +175,7 @@ describe('AppInsightsDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
const data = results.data[0] as DataFrame; const data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('PrimaryResult'); expect(getFrameDisplayName(data)).toEqual('PrimaryResult');
expect(data.fields[0].values.length).toEqual(1); expect(data.fields[0].values.length).toEqual(1);
expect(data.fields[0].values.get(0)).toEqual(1558278660000); expect(data.fields[0].values.get(0)).toEqual(1558278660000);
expect(data.fields[1].values.get(0)).toEqual(2.2075); expect(data.fields[1].values.get(0)).toEqual(2.2075);
@ -218,7 +218,7 @@ describe('AppInsightsDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
const data = results.data[0] as DataFrame; const data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('paritionA'); expect(getFrameDisplayName(data)).toEqual('paritionA');
expect(data.fields[0].values.length).toEqual(1); expect(data.fields[0].values.length).toEqual(1);
expect(data.fields[0].values.get(0)).toEqual(1558278660000); expect(data.fields[0].values.get(0)).toEqual(1558278660000);
expect(data.fields[1].values.get(0)).toEqual(2.2075); expect(data.fields[1].values.get(0)).toEqual(2.2075);
@ -279,7 +279,7 @@ describe('AppInsightsDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
const data = results.data[0] as DataFrame; const data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('exceptions/server'); expect(getFrameDisplayName(data)).toEqual('exceptions/server');
expect(data.fields[0].values.get(0)).toEqual(1558278660000); expect(data.fields[0].values.get(0)).toEqual(1558278660000);
expect(data.fields[1].values.get(0)).toEqual(2.2075); expect(data.fields[1].values.get(0)).toEqual(2.2075);
}); });
@ -322,7 +322,7 @@ describe('AppInsightsDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
const data = results.data[0] as DataFrame; const data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('exceptions/server'); expect(getFrameDisplayName(data)).toEqual('exceptions/server');
expect(data.fields[0].values.length).toEqual(2); expect(data.fields[0].values.length).toEqual(2);
expect(data.fields[0].values.get(0)).toEqual(1504108800000); expect(data.fields[0].values.get(0)).toEqual(1504108800000);
expect(data.fields[1].values.get(0)).toEqual(3); expect(data.fields[1].values.get(0)).toEqual(3);
@ -376,14 +376,14 @@ describe('AppInsightsDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(2); expect(results.data.length).toBe(2);
let data = results.data[0] as DataFrame; let data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('exceptions/server{client/city="Miami"}'); expect(getFrameDisplayName(data)).toEqual('exceptions/server{client/city="Miami"}');
expect(data.fields[1].values.length).toEqual(2); expect(data.fields[1].values.length).toEqual(2);
expect(data.fields[0].values.get(0)).toEqual(1504108800000); expect(data.fields[0].values.get(0)).toEqual(1504108800000);
expect(data.fields[1].values.get(0)).toEqual(10); expect(data.fields[1].values.get(0)).toEqual(10);
expect(data.fields[0].values.get(1)).toEqual(1504112400000); expect(data.fields[0].values.get(1)).toEqual(1504112400000);
expect(data.fields[1].values.get(1)).toEqual(20); expect(data.fields[1].values.get(1)).toEqual(20);
data = results.data[1] as DataFrame; data = results.data[1] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('exceptions/server{client/city="San Antonio"}'); expect(getFrameDisplayName(data)).toEqual('exceptions/server{client/city="San Antonio"}');
expect(data.fields[1].values.length).toEqual(2); expect(data.fields[1].values.length).toEqual(2);
expect(data.fields[0].values.get(0)).toEqual(1504108800000); expect(data.fields[0].values.get(0)).toEqual(1504108800000);
expect(data.fields[1].values.get(0)).toEqual(1); expect(data.fields[1].values.get(0)).toEqual(1);

View File

@ -2,7 +2,7 @@ import AzureMonitorDatasource from '../datasource';
import FakeSchemaData from './__mocks__/schema'; import FakeSchemaData from './__mocks__/schema';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { KustoSchema, AzureLogsVariable } from '../types'; import { KustoSchema, AzureLogsVariable } from '../types';
import { toUtc, getFrameDisplayTitle } from '@grafana/data'; import { toUtc, getFrameDisplayName } from '@grafana/data';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
jest.mock('@grafana/runtime', () => ({ jest.mock('@grafana/runtime', () => ({
@ -204,7 +204,7 @@ describe('AzureLogAnalyticsDatasource', () => {
it('should return a list of datapoints', () => { it('should return a list of datapoints', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
expect(getFrameDisplayTitle(results.data[0])).toEqual('grafana-vm'); expect(getFrameDisplayName(results.data[0])).toEqual('grafana-vm');
expect(results.data[0].fields.length).toBe(2); expect(results.data[0].fields.length).toBe(2);
expect(results.data[0].name).toBe('grafana-vm'); expect(results.data[0].name).toBe('grafana-vm');
expect(results.data[0].fields[0].name).toBe('Time'); expect(results.data[0].fields[0].name).toBe('Time');

View File

@ -1,7 +1,7 @@
import AzureMonitorDatasource from '../datasource'; import AzureMonitorDatasource from '../datasource';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { toUtc, DataFrame, getFrameDisplayTitle } from '@grafana/data'; import { toUtc, DataFrame, getFrameDisplayName } from '@grafana/data';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
jest.mock('@grafana/runtime', () => ({ jest.mock('@grafana/runtime', () => ({
@ -137,7 +137,7 @@ describe('AzureMonitorDatasource', () => {
return ctx.ds.query(options).then((results: any) => { return ctx.ds.query(options).then((results: any) => {
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
const data = results.data[0] as DataFrame; const data = results.data[0] as DataFrame;
expect(getFrameDisplayTitle(data)).toEqual('Percentage CPU'); expect(getFrameDisplayName(data)).toEqual('Percentage CPU');
expect(data.fields[0].values.get(0)).toEqual(1558278660000); expect(data.fields[0].values.get(0)).toEqual(1558278660000);
expect(data.fields[1].values.get(0)).toEqual(2.2075); expect(data.fields[1].values.get(0)).toEqual(2.2075);
expect(data.fields[0].values.get(1)).toEqual(1558278720000); expect(data.fields[0].values.get(1)).toEqual(1558278720000);

View File

@ -174,7 +174,7 @@ export class GraphiteDatasource extends DataSourceApi<GraphiteQuery, GraphiteOpt
unit = 'ms'; unit = 'ms';
} }
stats.push({ title: key, value: meta.stats[key], unit }); stats.push({ displayName: key, value: meta.stats[key], unit });
} }
return stats; return stats;

View File

@ -2,7 +2,7 @@ import { GraphiteDatasource } from '../datasource';
import _ from 'lodash'; import _ from 'lodash';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { dateTime, getFrameDisplayTitle } from '@grafana/data'; import { dateTime, getFrameDisplayName } from '@grafana/data';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
jest.mock('@grafana/runtime', () => ({ jest.mock('@grafana/runtime', () => ({
@ -91,8 +91,8 @@ describe('graphiteDatasource', () => {
}); });
expect(result.data.length).toBe(2); expect(result.data.length).toBe(2);
expect(getFrameDisplayTitle(result.data[0])).toBe('seriesA'); expect(getFrameDisplayName(result.data[0])).toBe('seriesA');
expect(getFrameDisplayTitle(result.data[1])).toBe('seriesB'); expect(getFrameDisplayName(result.data[1])).toBe('seriesB');
expect(result.data[0].length).toBe(2); expect(result.data[0].length).toBe(2);
expect(result.data[0].meta.notices.length).toBe(1); expect(result.data[0].meta.notices.length).toBe(1);
expect(result.data[0].meta.notices[0].text).toBe('Data is rolled up, aggregated over 2h using Average function'); expect(result.data[0].meta.notices[0].text).toBe('Data is rolled up, aggregated over 2h using Average function');

View File

@ -30,8 +30,8 @@ export class LiveStreams {
} }
const data = new CircularDataFrame({ capacity: target.size }); const data = new CircularDataFrame({ capacity: target.size });
data.addField({ name: 'ts', type: FieldType.time, config: { title: 'Time' } }); data.addField({ name: 'ts', type: FieldType.time, config: { displayName: 'Time' } });
data.addField({ name: 'tsNs', type: FieldType.time, config: { title: 'Time ns' } }); data.addField({ name: 'tsNs', type: FieldType.time, config: { displayName: 'Time ns' } });
data.addField({ name: 'line', type: FieldType.string }).labels = parseLabels(target.query); data.addField({ name: 'line', type: FieldType.string }).labels = parseLabels(target.query);
data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line
data.addField({ name: 'id', type: FieldType.string }); data.addField({ name: 'id', type: FieldType.string });

View File

@ -97,8 +97,8 @@ describe('loki result transformer', () => {
}; };
const data = new CircularDataFrame({ capacity: 1 }); const data = new CircularDataFrame({ capacity: 1 });
data.addField({ name: 'ts', type: FieldType.time, config: { title: 'Time' } }); data.addField({ name: 'ts', type: FieldType.time, config: { displayName: 'Time' } });
data.addField({ name: 'tsNs', type: FieldType.time, config: { title: 'Time ns' } }); data.addField({ name: 'tsNs', type: FieldType.time, config: { displayName: 'Time ns' } });
data.addField({ name: 'line', type: FieldType.string }).labels = { job: 'grafana' }; data.addField({ name: 'line', type: FieldType.string }).labels = { job: 'grafana' };
data.addField({ name: 'labels', type: FieldType.other }); data.addField({ name: 'labels', type: FieldType.other });
data.addField({ name: 'id', type: FieldType.string }); data.addField({ name: 'id', type: FieldType.string });

View File

@ -77,10 +77,10 @@ function constructDataFrame(
const dataFrame = { const dataFrame = {
refId, refId,
fields: [ fields: [
{ name: 'ts', type: FieldType.time, config: { title: 'Time' }, values: times }, // Time { name: 'ts', type: FieldType.time, config: { displayName: 'Time' }, values: times }, // Time
{ name: 'line', type: FieldType.string, config: {}, values: lines, labels }, // Line { name: 'line', type: FieldType.string, config: {}, values: lines, labels }, // Line
{ name: 'id', type: FieldType.string, config: {}, values: uids }, { name: 'id', type: FieldType.string, config: {}, values: uids },
{ name: 'tsNs', type: FieldType.time, config: { title: 'Time ns' }, values: timesNs }, // Time { name: 'tsNs', type: FieldType.time, config: { displayName: 'Time ns' }, values: timesNs }, // Time
], ],
length: times.length, length: times.length,
}; };
@ -283,7 +283,7 @@ function lokiStatsToMetaStat(stats: LokiStats): QueryResultMetaStat[] {
unit = 'decbytes'; unit = 'decbytes';
} }
const title = `${_.capitalize(section)}: ${decamelize(label)}`; const title = `${_.capitalize(section)}: ${decamelize(label)}`;
result.push({ title, value, unit }); result.push({ displayName: title, value, unit });
} }
} }
return result; return result;

View File

@ -14,7 +14,7 @@ import {
dateTime, dateTime,
LoadingState, LoadingState,
toDataFrame, toDataFrame,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { PromOptions, PromQuery } from './types'; import { PromOptions, PromQuery } from './types';
import templateSrv from 'app/features/templating/template_srv'; import templateSrv from 'app/features/templating/template_srv';
@ -590,7 +590,7 @@ describe('PrometheusDatasource', () => {
it('should return series list', async () => { it('should return series list', async () => {
const frame = toDataFrame(results.data[0]); const frame = toDataFrame(results.data[0]);
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
expect(getFieldTitle(frame.fields[1])).toBe('test{job="testjob"}'); expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}');
}); });
}); });
@ -736,7 +736,7 @@ describe('PrometheusDatasource', () => {
const frame = toDataFrame(results.data[0]); const frame = toDataFrame(results.data[0]);
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
expect(frame.name).toBe('test{job="testjob"}'); expect(frame.name).toBe('test{job="testjob"}');
expect(getFieldTitle(frame.fields[1])).toBe('test{job="testjob"}'); expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}');
}); });
}); });
@ -1641,7 +1641,7 @@ describe('PrometheusDatasource for POST', () => {
it('should return series list', () => { it('should return series list', () => {
const frame = toDataFrame(results.data[0]); const frame = toDataFrame(results.data[0]);
expect(results.data.length).toBe(1); expect(results.data.length).toBe(1);
expect(getFieldTitle(frame.fields[1])).toBe('test{job="testjob"}'); expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}');
}); });
}); });

View File

@ -8,7 +8,7 @@ import {
DataFrame, DataFrame,
getTimeField, getTimeField,
dateTime, dateTime,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import TimeSeries from 'app/core/time_series2'; import TimeSeries from 'app/core/time_series2';
import config from 'app/core/config'; import config from 'app/core/config';
@ -43,7 +43,7 @@ export class DataProcessor {
if (field.type !== FieldType.number) { if (field.type !== FieldType.number) {
continue; continue;
} }
const name = getFieldTitle(field, series, dataList); const name = getFieldDisplayName(field, series, dataList);
const datapoints = []; const datapoints = [];
for (let r = 0; r < series.length; r++) { for (let r = 0; r < series.length; r++) {

View File

@ -17,7 +17,7 @@ import {
FieldColor, FieldColor,
FieldColorMode, FieldColorMode,
FieldConfigSource, FieldConfigSource,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { SeriesOptions, GraphOptions, GraphLegendEditorLegendOptions } from './types'; import { SeriesOptions, GraphOptions, GraphLegendEditorLegendOptions } from './types';
@ -123,7 +123,7 @@ export const getGraphSeriesModel = (
}); });
graphs.push({ graphs.push({
label: getFieldTitle(field, series, dataFrames), label: getFieldDisplayName(field, series, dataFrames),
data: points, data: points,
color: field.config.color?.fixedColor, color: field.config.color?.fixedColor,
info: statsDisplayValues, info: statsDisplayValues,

View File

@ -26,7 +26,7 @@ export function feedToDataFrame(feed: RssFeed): DataFrame {
return { return {
fields: [ fields: [
{ name: 'date', type: FieldType.time, config: { title: 'Date' }, values: date }, { name: 'date', type: FieldType.time, config: { displayName: 'Date' }, values: date },
{ name: 'title', type: FieldType.string, config: {}, values: title }, { name: 'title', type: FieldType.string, config: {}, values: title },
{ name: 'link', type: FieldType.string, config: {}, values: link }, { name: 'link', type: FieldType.string, config: {}, values: link },
{ name: 'content', type: FieldType.string, config: {}, values: content }, { name: 'content', type: FieldType.string, config: {}, values: content },

View File

@ -23,7 +23,7 @@ import {
PanelEvents, PanelEvents,
formattedValueToString, formattedValueToString,
locationUtil, locationUtil,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { convertOldAngularValueMapping } from '@grafana/ui'; import { convertOldAngularValueMapping } from '@grafana/ui';
@ -205,7 +205,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
processField(fieldInfo: FieldInfo) { processField(fieldInfo: FieldInfo) {
const { panel, dashboard } = this; const { panel, dashboard } = this;
const name = getFieldTitle(fieldInfo.field, fieldInfo.frame.frame, this.dataList as DataFrame[]); const name = getFieldDisplayName(fieldInfo.field, fieldInfo.frame.frame, this.dataList as DataFrame[]);
let calc = panel.valueName; let calc = panel.valueName;
let calcField = fieldInfo.field; let calcField = fieldInfo.field;
let val: any = undefined; let val: any = undefined;
@ -734,7 +734,7 @@ function getDistinctNames(data: DataFrame[]): DistinctFieldsInfo {
if (!distinct.first) { if (!distinct.first) {
distinct.first = f; distinct.first = f;
} }
let t = field.config.title; let t = field.config.displayName;
if (t && !distinct.byName[t]) { if (t && !distinct.byName[t]) {
distinct.byName[t] = f; distinct.byName[t] = f;
distinct.names.push(t); distinct.names.push(t);

View File

@ -1,5 +1,5 @@
import { SingleStatCtrl, ShowData } from '../module'; import { SingleStatCtrl, ShowData } from '../module';
import { dateTime, ReducerID, getFieldTitle } from '@grafana/data'; import { dateTime, ReducerID, getFieldDisplayName } from '@grafana/data';
import { LinkSrv } from 'app/features/panel/panellinks/link_srv'; import { LinkSrv } from 'app/features/panel/panellinks/link_srv';
import { LegacyResponseData } from '@grafana/data'; import { LegacyResponseData } from '@grafana/data';
import { DashboardModel } from 'app/features/dashboard/state'; import { DashboardModel } from 'app/features/dashboard/state';
@ -90,8 +90,8 @@ describe('SingleStatCtrl', () => {
}); });
it('Should use series avg as default main value', () => { it('Should use series avg as default main value', () => {
const title = getFieldTitle(ctx.data.field); const name = getFieldDisplayName(ctx.data.field);
expect(title).toBe('test.cpu1'); expect(name).toBe('test.cpu1');
}); });
it('should set formatted value', () => { it('should set formatted value', () => {

View File

@ -6,8 +6,8 @@ import {
PanelProps, PanelProps,
DataFrame, DataFrame,
SelectableValue, SelectableValue,
getFrameDisplayTitle, getFrameDisplayName,
getFieldTitle, getFieldDisplayName,
} from '@grafana/data'; } from '@grafana/data';
import { Options } from './types'; import { Options } from './types';
import { css } from 'emotion'; import { css } from 'emotion';
@ -34,7 +34,7 @@ export class TablePanel extends Component<Props> {
return; return;
} }
const fieldDisplayName = getFieldTitle(field, frame, data.series); const fieldDisplayName = getFieldDisplayName(field, frame, data.series);
const matcherId = FieldMatcherID.byName; const matcherId = FieldMatcherID.byName;
const propId = 'custom.width'; const propId = 'custom.width';
@ -108,7 +108,7 @@ export class TablePanel extends Component<Props> {
const currentIndex = this.getCurrentFrameIndex(); const currentIndex = this.getCurrentFrameIndex();
const names = data.series.map((frame, index) => { const names = data.series.map((frame, index) => {
return { return {
label: getFrameDisplayTitle(frame), label: getFrameDisplayName(frame),
value: index, value: index,
}; };
}); });