From 88fbdd6716a49ef82d529769e9e078add6d1d9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 25 Aug 2020 09:50:37 +0200 Subject: [PATCH] DisplayProcessor: Show strings as strings (#27097) * WIP: strings and numbers * Works in displayProcessor but units are not applied in applyFieldOverride * removed bit * Updated * Added docs * fixed typo --- .../panels/field-configuration-options.md | 19 ++++++++++------ .../panels/visualizations/table-panel.md | 7 ++++++ .../src/field/displayProcessor.test.ts | 22 +++++++++++++++++++ .../src/field/displayProcessor.ts | 5 +++-- .../src/valueFormats/categories.ts | 17 +++++++------- .../src/valueFormats/valueFormats.ts | 4 ++++ 6 files changed, 57 insertions(+), 17 deletions(-) diff --git a/docs/sources/panels/field-configuration-options.md b/docs/sources/panels/field-configuration-options.md index 89ef84dbd07..5f8a706b909 100644 --- a/docs/sources/panels/field-configuration-options.md +++ b/docs/sources/panels/field-configuration-options.md @@ -156,13 +156,13 @@ When multiple stats, fields, or series are shown, this field controls the title Given a field with a name of Temp, and labels of {"Loc"="PBI", "Sensor"="3"} -| Expression syntax | Example | Renders to | Explanation | -| ---------------------------- | ---------------------- | --------------------------------- | ----------- | -| `${__field.displayName}` | Same as syntax | `Temp {Loc="PBI", Sensor="3"}` | Displays the field name, and labels in `{}` if they are present. If there is only one label key in the response, then for the label portion, Grafana displays the value of the label without the enclosing braces. | -| `${__field.name}` | Same as syntax | `Temp` | Displays the name of the field (without labels). | -| `${__field.labels}` | Same as syntax | `Loc="PBI", Sensor="3"` | Displays the labels without the name. | -| `${__field.labels.X}` | `${__field.labels.Loc}` | `PBI` | Displays the value of the specified label key. | -| `${__field.labels.__values}` | Same as Syntax | `PBI, 3` | Displays the values of the labels separated by a comma (without label keys). | +| Expression syntax | Example | Renders to | Explanation | +| ---------------------------- | ----------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `${__field.displayName}` | Same as syntax | `Temp {Loc="PBI", Sensor="3"}` | Displays the field name, and labels in `{}` if they are present. If there is only one label key in the response, then for the label portion, Grafana displays the value of the label without the enclosing braces. | +| `${__field.name}` | Same as syntax | `Temp` | Displays the name of the field (without labels). | +| `${__field.labels}` | Same as syntax | `Loc="PBI", Sensor="3"` | Displays the labels without the name. | +| `${__field.labels.X}` | `${__field.labels.Loc}` | `PBI` | Displays the value of the specified label key. | +| `${__field.labels.__values}` | Same as Syntax | `PBI, 3` | Displays the values of the labels separated by a comma (without label keys). | If the value is an empty string after rendering the expression for a particular field, then the default display method is used. @@ -201,6 +201,11 @@ You can also paste a native emoji in the unit picker and pick it as a custom uni {{< docs-imagebox img="/img/docs/v66/custom_unit_burger2.png" max-width="600px" caption="Custom unit emoji" >}} +#### String unit + +Grafana can sometime be too aggressive in parsing strings and displaying them as numbers. To make Grafana show the original +string create a field override and add a unit property with the `string` unit. + ### Thresholds Thresholds allow you to change the color of a field based on the value. diff --git a/docs/sources/panels/visualizations/table-panel.md b/docs/sources/panels/visualizations/table-panel.md index 29f8473dcdf..9b239674605 100644 --- a/docs/sources/panels/visualizations/table-panel.md +++ b/docs/sources/panels/visualizations/table-panel.md @@ -26,3 +26,10 @@ Table visualizations allow you to apply: ## Display options - **Show header -** Show or hide column names imported from your data source.. + +## Tips + +### Display original string value + +Grafana can sometime be too aggressive in parsing strings and displaying them as numbers. To make Grafana show the original +string create a field override and add a unit property with the `string` unit. diff --git a/packages/grafana-data/src/field/displayProcessor.test.ts b/packages/grafana-data/src/field/displayProcessor.test.ts index cd7cb9d60c3..bf8db95340b 100644 --- a/packages/grafana-data/src/field/displayProcessor.test.ts +++ b/packages/grafana-data/src/field/displayProcessor.test.ts @@ -303,4 +303,26 @@ describe('Date display options', () => { expect(processor('2020-08-01T08:48:43.783337Z').text).toEqual('2020-08-01 08:48:43'); }); + + describe('number formatting for string values', () => { + it('should preserve string unchanged if unit is strings', () => { + const processor = getDisplayProcessor({ + field: { + type: FieldType.string, + config: { unit: 'string' }, + }, + }); + expect(processor('22.1122334455').text).toEqual('22.1122334455'); + }); + + it('should format string as number if no unit', () => { + const processor = getDisplayProcessor({ + field: { + type: FieldType.string, + config: { decimals: 2 }, + }, + }); + expect(processor('22.1122334455').text).toEqual('22.11'); + }); + }); }); diff --git a/packages/grafana-data/src/field/displayProcessor.ts b/packages/grafana-data/src/field/displayProcessor.ts index 121e4ab83db..480e778c1ca 100644 --- a/packages/grafana-data/src/field/displayProcessor.ts +++ b/packages/grafana-data/src/field/displayProcessor.ts @@ -46,13 +46,14 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP return (value: any) => { const { mappings } = config; + const isStringUnit = unit === 'string'; if (hasDateUnit && typeof value === 'string') { value = dateTime(value).valueOf(); } let text = _.toString(value); - let numeric = toNumber(value); + let numeric = isStringUnit ? NaN : toNumber(value); let prefix: string | undefined = undefined; let suffix: string | undefined = undefined; let shouldFormat = true; @@ -62,7 +63,7 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP if (mappedValue) { text = mappedValue.text; - const v = toNumber(text); + const v = isStringUnit ? NaN : toNumber(text); if (!isNaN(v)) { numeric = v; diff --git a/packages/grafana-data/src/valueFormats/categories.ts b/packages/grafana-data/src/valueFormats/categories.ts index 80a2b754c4d..a2107c6b4c4 100644 --- a/packages/grafana-data/src/valueFormats/categories.ts +++ b/packages/grafana-data/src/valueFormats/categories.ts @@ -1,4 +1,4 @@ -import { locale, scaledUnits, simpleCountUnit, toFixedUnit, ValueFormatCategory } from './valueFormats'; +import { locale, scaledUnits, simpleCountUnit, toFixedUnit, ValueFormatCategory, stringFormater } from './valueFormats'; import { dateTimeAsIso, dateTimeAsUS, @@ -26,19 +26,20 @@ export const getCategories = (): ValueFormatCategory[] => [ name: 'Misc', formats: [ { name: 'none', id: 'none', fn: toFixedUnit('') }, + { name: 'String', id: 'string', fn: stringFormater }, { name: 'short', id: 'short', fn: scaledUnits(1000, ['', ' K', ' Mil', ' Bil', ' Tri', ' Quadr', ' Quint', ' Sext', ' Sept']), }, - { name: 'percent (0-100)', id: 'percent', fn: toPercent }, - { name: 'percent (0.0-1.0)', id: 'percentunit', fn: toPercentUnit }, + { name: 'Percent (0-100)', id: 'percent', fn: toPercent }, + { name: 'Percent (0.0-1.0)', id: 'percentunit', fn: toPercentUnit }, { name: 'Humidity (%H)', id: 'humidity', fn: toFixedUnit('%H') }, - { name: 'decibel', id: 'dB', fn: toFixedUnit('dB') }, - { name: 'hexadecimal (0x)', id: 'hex0x', fn: toHex0x }, - { name: 'hexadecimal', id: 'hex', fn: toHex }, - { name: 'scientific notation', id: 'sci', fn: sci }, - { name: 'locale format', id: 'locale', fn: locale }, + { name: 'Decibel', id: 'dB', fn: toFixedUnit('dB') }, + { name: 'Hexadecimal (0x)', id: 'hex0x', fn: toHex0x }, + { name: 'Hexadecimal', id: 'hex', fn: toHex }, + { name: 'Scientific notation', id: 'sci', fn: sci }, + { name: 'Locale format', id: 'locale', fn: locale }, { name: 'Pixels', id: 'pixel', fn: toFixedUnit('px') }, ], }, diff --git a/packages/grafana-data/src/valueFormats/valueFormats.ts b/packages/grafana-data/src/valueFormats/valueFormats.ts index ea1e4b87f54..425ff847ab8 100644 --- a/packages/grafana-data/src/valueFormats/valueFormats.ts +++ b/packages/grafana-data/src/valueFormats/valueFormats.ts @@ -156,6 +156,10 @@ export function simpleCountUnit(symbol: string): ValueFormatter { }; } +export function stringFormater(value: number): FormattedValue { + return { text: `${value}` }; +} + function buildFormats() { categories = getCategories();