[v9.3.x] Fix Barchart legend calcs when stacking is percent (#62176)
Fix Barchart legend calcs when stacking is percent (#61449)
* Fix Barchart legend calcs when stacking is percent
* doc change
* Refactor + tests
(cherry picked from commit ab7a4e5f28)
This commit is contained in:
@@ -218,7 +218,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
|
||||
}
|
||||
}
|
||||
|
||||
return <PlotLegend data={info.viz} config={config} maxHeight="35%" maxWidth="60%" {...options.legend} />;
|
||||
return <PlotLegend data={[info.legend]} config={config} maxHeight="35%" maxWidth="60%" {...options.legend} />;
|
||||
};
|
||||
|
||||
const rawValue = (seriesIdx: number, valueIdx: number) => {
|
||||
|
||||
@@ -10,6 +10,12 @@ export interface BarChartDisplayValues {
|
||||
*/
|
||||
viz: [DataFrame];
|
||||
|
||||
/**
|
||||
* The fields we can display, first field is X axis.
|
||||
* Contains same data as viz, but without config modifications (e.g: unit override)
|
||||
*/
|
||||
legend: DataFrame;
|
||||
|
||||
/** Potentialy color by a field value */
|
||||
colorByField?: Field;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
SortOrder,
|
||||
} from '@grafana/schema';
|
||||
|
||||
import { PanelFieldConfig } from './models.gen';
|
||||
import { PanelFieldConfig, PanelOptions } from './models.gen';
|
||||
import { BarChartOptionsEX, prepareBarChartDisplayValues, preparePlotConfigBuilder } from './utils';
|
||||
|
||||
function mockDataFrame() {
|
||||
@@ -202,6 +202,19 @@ describe('BarChart utils', () => {
|
||||
|
||||
const field = displayValues.viz[0].fields[1];
|
||||
expect(field.values.toArray()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
-10,
|
||||
null,
|
||||
10,
|
||||
null,
|
||||
null,
|
||||
]
|
||||
`);
|
||||
|
||||
const displayLegendValuesAsc = assertIsDefined('legend' in result ? result : null).legend;
|
||||
const legendField = displayLegendValuesAsc.fields[1];
|
||||
|
||||
expect(legendField.values.toArray()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
-10,
|
||||
null,
|
||||
@@ -231,6 +244,12 @@ describe('BarChart utils', () => {
|
||||
expect(displayValuesAsc.fields[2].name).toBe('c');
|
||||
expect(displayValuesAsc.fields[3].name).toBe('b');
|
||||
|
||||
const displayLegendValuesAsc = assertIsDefined('legend' in resultAsc ? resultAsc : null).legend;
|
||||
expect(displayLegendValuesAsc.fields[0].type).toBe(FieldType.string);
|
||||
expect(displayLegendValuesAsc.fields[1].name).toBe('a');
|
||||
expect(displayLegendValuesAsc.fields[2].name).toBe('c');
|
||||
expect(displayLegendValuesAsc.fields[3].name).toBe('b');
|
||||
|
||||
const resultDesc = prepareBarChartDisplayValues([frame], createTheme(), {
|
||||
legend: { sortBy: 'Min', sortDesc: true },
|
||||
} as any);
|
||||
@@ -239,6 +258,32 @@ describe('BarChart utils', () => {
|
||||
expect(displayValuesDesc.fields[1].name).toBe('b');
|
||||
expect(displayValuesDesc.fields[2].name).toBe('c');
|
||||
expect(displayValuesDesc.fields[3].name).toBe('a');
|
||||
|
||||
const displayLegendValuesDesc = assertIsDefined('legend' in resultDesc ? resultDesc : null).legend;
|
||||
expect(displayLegendValuesDesc.fields[0].type).toBe(FieldType.string);
|
||||
expect(displayLegendValuesDesc.fields[1].name).toBe('b');
|
||||
expect(displayLegendValuesDesc.fields[2].name).toBe('c');
|
||||
expect(displayLegendValuesDesc.fields[3].name).toBe('a');
|
||||
});
|
||||
|
||||
it('should remove unit from legend values when stacking is percent', () => {
|
||||
const frame = new MutableDataFrame({
|
||||
fields: [
|
||||
{ name: 'string', type: FieldType.string, values: ['a', 'b', 'c'] },
|
||||
{ name: 'a', values: [-10, 20, 10], state: { calcs: { min: -10 } } },
|
||||
{ name: 'b', values: [20, 20, 20], state: { calcs: { min: 20 } } },
|
||||
{ name: 'c', values: [10, 10, 10], state: { calcs: { min: 10 } } },
|
||||
],
|
||||
});
|
||||
|
||||
const resultAsc = prepareBarChartDisplayValues([frame], createTheme(), {
|
||||
stacking: StackingMode.Percent,
|
||||
} as PanelOptions);
|
||||
const displayLegendValuesAsc = assertIsDefined('legend' in resultAsc ? resultAsc : null).legend;
|
||||
|
||||
expect(displayLegendValuesAsc.fields[1].config.unit).toBeUndefined();
|
||||
expect(displayLegendValuesAsc.fields[2].config.unit).toBeUndefined();
|
||||
expect(displayLegendValuesAsc.fields[3].config.unit).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -464,6 +464,27 @@ export function prepareBarChartDisplayValues(
|
||||
);
|
||||
}
|
||||
|
||||
let legendFields: Field[] = fields;
|
||||
if (options.stacking === StackingMode.Percent) {
|
||||
legendFields = fields.map((field) => {
|
||||
const alignedFrameField = frame.fields.find((f) => f.name === field.name)!;
|
||||
|
||||
const copy = {
|
||||
...field,
|
||||
config: {
|
||||
...alignedFrameField.config,
|
||||
},
|
||||
values: field.values,
|
||||
};
|
||||
|
||||
copy.display = getDisplayProcessor({ field: copy, theme });
|
||||
|
||||
return copy;
|
||||
});
|
||||
|
||||
legendFields.unshift(firstField);
|
||||
}
|
||||
|
||||
// String field is first
|
||||
fields.unshift(firstField);
|
||||
|
||||
@@ -476,6 +497,10 @@ export function prepareBarChartDisplayValues(
|
||||
fields: fields, // ideally: fields.filter((f) => !Boolean(f.config.custom?.hideFrom?.viz)),
|
||||
},
|
||||
],
|
||||
legend: {
|
||||
fields: legendFields,
|
||||
length: firstField.values.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user