diff --git a/packages/grafana-data/src/dataframe/processDataFrame.ts b/packages/grafana-data/src/dataframe/processDataFrame.ts index ff9685f1ee4..69d57700769 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.ts @@ -95,7 +95,7 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame { ]; if (timeSeries.title) { - (fields[1].config as FieldConfig).displayName = timeSeries.title; + (fields[1].config as FieldConfig).displayNameFromDS = timeSeries.title; } return { diff --git a/packages/grafana-data/src/field/fieldState.ts b/packages/grafana-data/src/field/fieldState.ts index d0bf5b18a38..10d1bd736e8 100644 --- a/packages/grafana-data/src/field/fieldState.ts +++ b/packages/grafana-data/src/field/fieldState.ts @@ -58,6 +58,10 @@ function calculateFieldDisplayName(field: Field, frame?: DataFrame, allFrames?: return displayName; } + if (frame && field.config?.displayNameFromDS) { + return field.config.displayNameFromDS; + } + // This is an ugly exception for time field // 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 diff --git a/packages/grafana-data/src/types/dataFrame.ts b/packages/grafana-data/src/types/dataFrame.ts index 380cab80a00..cefbe58045f 100644 --- a/packages/grafana-data/src/types/dataFrame.ts +++ b/packages/grafana-data/src/types/dataFrame.ts @@ -23,7 +23,20 @@ export enum FieldType { * Plugins may extend this with additional properties. Something like series overrides */ export interface FieldConfig { - displayName?: string; // The display value for this field. This supports template variables blank is auto + /** + * The display value for this field. This supports template variables blank is auto + */ + displayName?: string; + + /** + * This can be used by data sources that return and explicit naming structure for values and labels + * When this property is configured, this value is used rather than the default naming strategy. + */ + displayNameFromDS?: string; + + /** + * True if data source field supports ad-hoc filters + */ filterable?: boolean; // Numeric Options diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index b611b2ac70d..79c426ef0f8 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -625,7 +625,7 @@ describe('PrometheusDatasource', () => { it('should return series list', async () => { const frame = toDataFrame(results.data[0]); expect(results.data.length).toBe(1); - expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}'); + expect(getFieldDisplayName(frame.fields[1], frame)).toBe('test{job="testjob"}'); }); }); @@ -771,7 +771,7 @@ describe('PrometheusDatasource', () => { const frame = toDataFrame(results.data[0]); expect(results.data.length).toBe(1); expect(frame.name).toBe('test{job="testjob"}'); - expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}'); + expect(getFieldDisplayName(frame.fields[1], frame)).toBe('test{job="testjob"}'); }); }); @@ -1721,7 +1721,7 @@ describe('PrometheusDatasource for POST', () => { it('should return series list', () => { const frame = toDataFrame(results.data[0]); expect(results.data.length).toBe(1); - expect(getFieldDisplayName(frame.fields[1])).toBe('test{job="testjob"}'); + expect(getFieldDisplayName(frame.fields[1], frame)).toBe('test{job="testjob"}'); }); });