From 39fc1bf7105044179073d1c3c1ed53dd2d5b9a33 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Thu, 14 Oct 2021 13:23:41 +0100 Subject: [PATCH] Fix: State timeline panel not to crash when only one threshold (#40371) (#40457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 1e9aeb6f19f10d74965e257a1a7c5be4e562ba62) Co-authored-by: Zoltán Bedi --- .../panel/state-timeline/utils.test.ts | 89 ++++++++++++++++++- .../app/plugins/panel/state-timeline/utils.ts | 6 +- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/panel/state-timeline/utils.test.ts b/public/app/plugins/panel/state-timeline/utils.test.ts index b45ca35e38e..0988a31b121 100644 --- a/public/app/plugins/panel/state-timeline/utils.test.ts +++ b/public/app/plugins/panel/state-timeline/utils.test.ts @@ -1,5 +1,6 @@ -import { ArrayVector, createTheme, FieldType, toDataFrame } from '@grafana/data'; -import { findNextStateIndex, prepareTimelineFields } from './utils'; +import { ArrayVector, createTheme, FieldType, ThresholdsMode, toDataFrame } from '@grafana/data'; +import { LegendDisplayMode } from '@grafana/schema'; +import { findNextStateIndex, getThresholdItems, prepareTimelineFields, prepareTimelineLegendItems } from './utils'; const theme = createTheme(); @@ -136,3 +137,87 @@ describe('findNextStateIndex', () => { }); }); }); + +describe('getThresholdItems', () => { + it('should handle only one threshold', () => { + const result = getThresholdItems( + { thresholds: { mode: ThresholdsMode.Absolute, steps: [{ color: 'black', value: 0 }] } }, + theme + ); + + expect(result).toHaveLength(1); + }); +}); + +describe('prepareTimelineLegendItems', () => { + it('should return legend items', () => { + const frame: any = [ + { + refId: 'A', + fields: [ + { + name: 'time', + config: { + color: { + mode: 'thresholds', + }, + thresholds: { + mode: 'absolute', + steps: [ + { + color: 'green', + value: null, + }, + ], + }, + }, + values: new ArrayVector([ + 1634092733455, + 1634092763455, + 1634092793455, + 1634092823455, + 1634092853455, + 1634092883455, + 1634092913455, + 1634092943455, + 1634092973455, + 1634093003455, + ]), + display: (value: string) => ({ + text: value, + color: undefined, + numeric: NaN, + }), + }, + { + name: 'A-series', + config: { + color: { + mode: 'thresholds', + }, + thresholds: { + mode: 'absolute', + steps: [ + { + color: 'green', + value: null, + }, + ], + }, + }, + values: new ArrayVector(['< -∞', null, null, null, null, null, null, null, null, null]), + display: (value?: string) => ({ + text: value || '', + color: 'green', + numeric: NaN, + }), + }, + ], + }, + ]; + + const result = prepareTimelineLegendItems(frame, { displayMode: LegendDisplayMode.List } as any, theme); + + expect(result).toHaveLength(1); + }); +}); diff --git a/public/app/plugins/panel/state-timeline/utils.ts b/public/app/plugins/panel/state-timeline/utils.ts index 7397aa2e038..e060c2180be 100644 --- a/public/app/plugins/panel/state-timeline/utils.ts +++ b/public/app/plugins/panel/state-timeline/utils.ts @@ -422,7 +422,7 @@ export function getThresholdItems(fieldConfig: FieldConfig, theme: GrafanaTheme2 for (let i = 1; i <= steps.length; i++) { const step = steps[i - 1]; items.push({ - label: i === 1 ? `< ${fmt(steps[i].value)}` : `${fmt(step.value)}+`, + label: i === 1 ? `< ${fmt(step.value)}` : `${fmt(step.value)}+`, color: theme.visualization.getColorByName(step.color), yAxis: 1, }); @@ -465,7 +465,9 @@ export function prepareTimelineLegendItems( fields.forEach((field) => { field.values.toArray().forEach((v) => { let state = field.display!(v); - stateColors.set(state.text, state.color!); + if (state.color) { + stateColors.set(state.text, state.color!); + } }); });