From 658cc5dd2d6a95bb819518af0b623849874c5d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 28 May 2021 07:29:57 +0200 Subject: [PATCH] PieChart: Support row data in pie chart (#34755) * PieChart: Support row data in pie chart * Make color override work * removed thing * Minor refactoring --- packages/grafana-data/src/field/fieldColor.ts | 3 +- .../src/field/fieldDisplay.test.ts | 77 +++++++++++++++++++ .../grafana-data/src/field/fieldDisplay.ts | 35 ++++++++- public/app/plugins/panel/piechart/module.tsx | 12 +-- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/packages/grafana-data/src/field/fieldColor.ts b/packages/grafana-data/src/field/fieldColor.ts index 4432301236a..ffbdf95ac23 100644 --- a/packages/grafana-data/src/field/fieldColor.ts +++ b/packages/grafana-data/src/field/fieldColor.ts @@ -187,9 +187,8 @@ export class FieldColorSchemeMode implements FieldColorMode { }; } } else { - const seriesIndex = field.state?.seriesIndex ?? 0; - return (_: number, _percent: number, _threshold?: Threshold) => { + const seriesIndex = field.state?.seriesIndex ?? 0; return colors[seriesIndex % colors.length]; }; } diff --git a/packages/grafana-data/src/field/fieldDisplay.test.ts b/packages/grafana-data/src/field/fieldDisplay.test.ts index 9043f145ee9..b08b56a9d62 100644 --- a/packages/grafana-data/src/field/fieldDisplay.test.ts +++ b/packages/grafana-data/src/field/fieldDisplay.test.ts @@ -285,6 +285,83 @@ describe('FieldDisplay', () => { expect(result[3].display.title).toEqual('B SensorB'); }); + it('When showing all values set seriesIndex in a way so that values get unique color', () => { + const options = createDisplayOptions({ + reduceOptions: { + values: true, + calcs: [], + }, + data: [ + toDataFrame({ + fields: [ + { + name: 'Name', + values: ['A', 'B'], + }, + { + name: 'SensorA', + values: [10, 20], + config: { + color: { mode: 'palette-classic' }, + }, + }, + ], + }), + ], + }); + + const result = getFieldDisplayValues(options); + expect(result[0].display.color).toEqual('#73BF69'); + expect(result[1].display.color).toEqual('#F2CC0C'); + }); + + it('When showing all values lookup color via an override', () => { + const options = createDisplayOptions({ + reduceOptions: { + values: true, + calcs: [], + }, + fieldConfig: { + overrides: [ + { + matcher: { id: 'byName', options: 'A' }, + properties: [ + { + id: 'color', + value: { + mode: 'fixed', + fixedColor: '#AAA', + }, + }, + ], + }, + ], + defaults: {}, + }, + data: [ + toDataFrame({ + fields: [ + { + name: 'Name', + values: ['A', 'B'], + }, + { + name: 'SensorA', + values: [10, 20], + config: { + color: { mode: 'palette-classic' }, + }, + }, + ], + }), + ], + }); + + const result = getFieldDisplayValues(options); + expect(result[0].display.color).toEqual('#AAA'); + expect(result[1].display.color).toEqual('#F2CC0C'); + }); + it('Multiple other string fields', () => { const options = createDisplayOptions({ reduceOptions: { diff --git a/packages/grafana-data/src/field/fieldDisplay.ts b/packages/grafana-data/src/field/fieldDisplay.ts index 9f0b2bb4e25..fffe8c6c8bf 100644 --- a/packages/grafana-data/src/field/fieldDisplay.ts +++ b/packages/grafana-data/src/field/fieldDisplay.ts @@ -78,7 +78,7 @@ export interface GetFieldDisplayValuesOptions { export const DEFAULT_FIELD_DISPLAY_VALUES_LIMIT = 25; export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): FieldDisplay[] => { - const { replaceVariables, reduceOptions, timeZone } = options; + const { replaceVariables, reduceOptions, timeZone, theme } = options; const calcs = reduceOptions.calcs.length ? reduceOptions.calcs : [ReducerID.last]; const values: FieldDisplay[] = []; @@ -152,6 +152,8 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi } } + field.state = setIndexForPaletteColor(field, values.length); + const displayValue = display(field.values.get(j)); if (displayName !== '') { @@ -163,6 +165,11 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi displayValue.title = getSmartDisplayNameForRow(dataFrame, field, j); } + const overrideColor = lookupRowColorFromOverride(displayValue, options.fieldConfig); + if (overrideColor) { + displayValue.color = theme.visualization.getColorByName(overrideColor); + } + values.push({ name: '', field: config, @@ -269,6 +276,32 @@ function getSmartDisplayNameForRow(frame: DataFrame, field: Field, rowIndex: num return parts.join(' '); } +/** + * Palette color modes use series index (field index) which does not work for when displaing rows + * So updating seriesIndex here makes the palette color modes work in "All values" mode + */ +function setIndexForPaletteColor(field: Field, currentLength: number) { + return { + ...field.state, + seriesIndex: currentLength, + }; +} + +/** + * This function makes overrides that set color work for row values + */ +function lookupRowColorFromOverride(display: DisplayValue, fieldConfig: FieldConfigSource) { + for (const override of fieldConfig.overrides) { + if (override.matcher.id === 'byName' && override.matcher.options === display.title) { + for (const prop of override.properties) { + if (prop.id === 'color' && prop.value) { + return prop.value.fixedColor; + } + } + } + } +} + export function hasLinks(field: Field): boolean { return field.config?.links?.length ? field.config.links.length > 0 : false; } diff --git a/public/app/plugins/panel/piechart/module.tsx b/public/app/plugins/panel/piechart/module.tsx index 1b5e683b234..409aaa1fce9 100644 --- a/public/app/plugins/panel/piechart/module.tsx +++ b/public/app/plugins/panel/piechart/module.tsx @@ -1,8 +1,9 @@ -import { FieldColorModeId, FieldConfigProperty, PanelPlugin, ReducerID, standardEditorsRegistry } from '@grafana/data'; +import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; import { PieChartPanel } from './PieChartPanel'; import { PieChartOptions, PieChartType, PieChartLabels, PieChartLegendValues } from './types'; import { LegendDisplayMode, commonOptionsBuilder } from '@grafana/ui'; import { PieChartPanelChangedHandler } from './migrations'; +import { addStandardDataReduceOptions } from '../stat/types'; export const plugin = new PanelPlugin(PieChartPanel) .setPanelChangeHandler(PieChartPanelChangedHandler) @@ -25,15 +26,8 @@ export const plugin = new PanelPlugin(PieChartPanel) }, }) .setPanelOptions((builder) => { + addStandardDataReduceOptions(builder); builder - .addCustomEditor({ - id: 'reduceOptions.calcs', - path: 'reduceOptions.calcs', - name: 'Calculation', - description: 'Choose a reducer function / calculation', - editor: standardEditorsRegistry.get('stats-picker').editor as any, - defaultValue: [ReducerID.lastNotNull], - }) .addRadio({ name: 'Piechart type', description: 'How the piechart should be rendered',