diff --git a/public/app/plugins/panel/state-timeline/TimelineChart.tsx b/public/app/plugins/panel/state-timeline/TimelineChart.tsx index e4d6b9850c3..72ee7e27640 100755 --- a/public/app/plugins/panel/state-timeline/TimelineChart.tsx +++ b/public/app/plugins/panel/state-timeline/TimelineChart.tsx @@ -10,7 +10,7 @@ import { VizLegend, VizLegendItem, } from '@grafana/ui'; -import { DataFrame, FieldType, TimeRange } from '@grafana/data'; +import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data'; import { preparePlotConfigBuilder } from './utils'; import { TimelineMode, TimelineOptions, TimelineValueAlignment } from './types'; @@ -34,6 +34,19 @@ export class TimelineChart extends React.Component { static contextType = PanelContextRoot; panelContext: PanelContext = {} as PanelContext; + getValueColor = (frameIdx: number, fieldIdx: number, value: any) => { + const field = this.props.frames[frameIdx].fields[fieldIdx]; + + if (field.display) { + const disp = field.display(value); // will apply color modes + if (disp.color) { + return disp.color; + } + } + + return FALLBACK_COLOR; + }; + prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => { this.panelContext = this.context as PanelContext; const { eventBus, sync } = this.panelContext; @@ -48,6 +61,7 @@ export class TimelineChart extends React.Component { // When there is only one row, use the full space rowHeight: alignedFrame.fields.length > 2 ? this.props.rowHeight : 1, + getValueColor: this.getValueColor, }); }; diff --git a/public/app/plugins/panel/state-timeline/types.ts b/public/app/plugins/panel/state-timeline/types.ts index 1c3a298827e..ecd1f5f56e8 100644 --- a/public/app/plugins/panel/state-timeline/types.ts +++ b/public/app/plugins/panel/state-timeline/types.ts @@ -18,6 +18,7 @@ export interface TimelineOptions extends OptionsWithLegend, OptionsWithTooltip { alignValue?: TimelineValueAlignment; sync?: () => DashboardCursorSync; + getValueColor?: (frameIdx: number, fieldIdx: number, value: any) => string; } export type TimelineValueAlignment = 'center' | 'left' | 'right'; diff --git a/public/app/plugins/panel/state-timeline/utils.ts b/public/app/plugins/panel/state-timeline/utils.ts index 1b5a7ff3036..07b4d336c2d 100644 --- a/public/app/plugins/panel/state-timeline/utils.ts +++ b/public/app/plugins/panel/state-timeline/utils.ts @@ -70,6 +70,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ showValue, alignValue, mergeValues, + getValueColor, }) => { const builder = new UPlotConfigBuilder(timeZone); @@ -81,14 +82,15 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ return !(mode && field.display && mode.startsWith('continuous-')); }; - const getValueColor = (seriesIdx: number, value: any) => { + const getValueColorFn = (seriesIdx: number, value: any) => { const field = frame.fields[seriesIdx]; - if (field.display) { - const disp = field.display(value); // will apply color modes - if (disp.color) { - return disp.color; - } + if ( + field.state?.origin?.fieldIndex !== undefined && + field.state?.origin?.frameIndex !== undefined && + getValueColor + ) { + return getValueColor(field.state?.origin?.frameIndex, field.state?.origin?.fieldIndex, value); } return FALLBACK_COLOR; @@ -107,7 +109,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ theme, label: (seriesIdx) => getFieldDisplayName(frame.fields[seriesIdx], frame), getFieldConfig: (seriesIdx) => frame.fields[seriesIdx].config.custom, - getValueColor, + getValueColor: getValueColorFn, getTimeRange, // hardcoded formatter for state values formatValue: (seriesIdx, value) => formattedValueToString(frame.fields[seriesIdx].display!(value)),