Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PieChart: Support row data in pie charts #34755

Merged
merged 5 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/grafana-data/src/field/fieldColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
}
Expand Down
77 changes: 77 additions & 0 deletions packages/grafana-data/src/field/fieldDisplay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
35 changes: 34 additions & 1 deletion packages/grafana-data/src/field/fieldDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];
Expand Down Expand Up @@ -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 !== '') {
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down
12 changes: 3 additions & 9 deletions public/app/plugins/panel/piechart/module.tsx
Original file line number Diff line number Diff line change
@@ -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<PieChartOptions>(PieChartPanel)
.setPanelChangeHandler(PieChartPanelChangedHandler)
Expand All @@ -25,15 +26,8 @@ export const plugin = new PanelPlugin<PieChartOptions>(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',
Expand Down