feat: show total in waterfall chart (#35876)

This commit is contained in:
SBIN2010
2025-10-29 20:25:56 +03:00
committed by GitHub
parent 99b61143f6
commit 48ee0821d3
4 changed files with 151 additions and 108 deletions

View File

@@ -129,6 +129,18 @@ const config: ControlPanelConfig = {
{t('Series total setting')}
</ControlSubSectionHeader>,
],
[
{
name: 'show_total',
config: {
type: 'CheckboxControl',
label: t('Show total'),
renderTrigger: true,
default: true,
description: t('Display cumulative total at end'),
},
},
],
[
{
name: 'total_color',

View File

@@ -94,12 +94,14 @@ function transformer({
metric,
breakdown,
totalMark,
showTotal,
}: {
data: DataRecord[];
xAxis: string;
metric: string;
breakdown?: string;
totalMark: string;
showTotal: boolean;
}) {
// Group by series (temporary map)
const groupedData = data.reduce((acc, cur) => {
@@ -121,11 +123,13 @@ function transformer({
0,
);
// Push total per period to the end of period values array
tempValue.push({
[xAxis]: key,
[breakdown]: totalMark,
[metric]: sum,
});
if (showTotal) {
tempValue.push({
[xAxis]: key,
[breakdown]: totalMark,
[metric]: sum,
});
}
transformedData.push(...tempValue);
});
} else {
@@ -141,10 +145,12 @@ function transformer({
});
total += sum;
});
transformedData.push({
[xAxis]: totalMark,
[metric]: total,
});
if (showTotal) {
transformedData.push({
[xAxis]: totalMark,
[metric]: total,
});
}
}
return transformedData;
@@ -183,6 +189,7 @@ export default function transformProps(
xAxisLabel,
yAxisFormat,
showValue,
showTotal,
totalLabel,
increaseLabel,
decreaseLabel,
@@ -220,6 +227,7 @@ export default function transformProps(
xAxis: xAxisName,
metric: metricLabel,
totalMark,
showTotal,
});
const assistData: ISeriesData[] = [];

View File

@@ -60,6 +60,7 @@ export type EchartsWaterfallFormData = QueryFormData &
increaseLabel?: string;
decreaseLabel?: string;
totalLabel?: string;
showTotal: boolean;
};
export const DEFAULT_FORM_DATA: Partial<EchartsWaterfallFormData> = {

View File

@@ -39,107 +39,129 @@ const extractSeriesName = (props: WaterfallChartTransformedProps) => {
return series.map(item => item.name);
};
describe('Waterfall tranformProps', () => {
const data = [
{ year: '2019', name: 'Sylvester', sum: 10 },
{ year: '2019', name: 'Arnold', sum: 3 },
{ year: '2020', name: 'Sylvester', sum: -10 },
{ year: '2020', name: 'Arnold', sum: 5 },
];
const data = [
{ year: '2019', name: 'Sylvester', sum: 10 },
{ year: '2019', name: 'Arnold', sum: 3 },
{ year: '2020', name: 'Sylvester', sum: -10 },
{ year: '2020', name: 'Arnold', sum: 5 },
];
const formData = {
colorScheme: 'bnbColors',
datasource: '3__table',
x_axis: 'year',
metric: 'sum',
increaseColor: { r: 0, b: 0, g: 0 },
decreaseColor: { r: 0, b: 0, g: 0 },
totalColor: { r: 0, b: 0, g: 0 },
};
const formData = {
colorScheme: 'bnbColors',
datasource: '3__table',
x_axis: 'year',
metric: 'sum',
increaseColor: { r: 0, b: 0, g: 0 },
decreaseColor: { r: 0, b: 0, g: 0 },
totalColor: { r: 0, b: 0, g: 0 },
showTotal: true,
};
it('should tranform chart props for viz when breakdown not exist', () => {
const chartProps = new ChartProps({
formData: { ...formData, series: 'bar' },
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect(extractSeries(transformedProps)).toEqual([
[0, 8, '-'],
[13, '-', '-'],
['-', 5, '-'],
['-', '-', 8],
]);
});
it('should tranform chart props for viz when breakdown exist', () => {
const chartProps = new ChartProps({
formData: { ...formData, groupby: 'name' },
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect(extractSeries(transformedProps)).toEqual([
[0, 10, '-', 3, 3, '-'],
[10, 3, '-', '-', 5, '-'],
['-', '-', '-', 10, '-', '-'],
['-', '-', 13, '-', '-', 8],
]);
});
it('renaming series names, checking legend and X axis labels', () => {
const chartProps = new ChartProps({
formData: {
...formData,
increaseLabel: 'sale increase',
decreaseLabel: 'sale decrease',
totalLabel: 'sale total',
test('should tranform chart props for viz when breakdown not exist', () => {
const chartProps = new ChartProps({
formData: { ...formData, series: 'bar' },
width: 800,
height: 600,
queriesData: [
{
data,
},
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect((transformedProps.echartOptions.legend as any).data).toEqual([
'sale increase',
'sale decrease',
'sale total',
]);
expect((transformedProps.echartOptions.xAxis as any).data).toEqual([
'2019',
'2020',
'sale total',
]);
expect(extractSeriesName(transformedProps)).toEqual([
'Assist',
'sale increase',
'sale decrease',
'sale total',
]);
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect(extractSeries(transformedProps)).toEqual([
[0, 8, '-'],
[13, '-', '-'],
['-', 5, '-'],
['-', '-', 8],
]);
});
test('should tranform chart props for viz when breakdown exist', () => {
const chartProps = new ChartProps({
formData: { ...formData, groupby: 'name' },
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect(extractSeries(transformedProps)).toEqual([
[0, 10, '-', 3, 3, '-'],
[10, 3, '-', '-', 5, '-'],
['-', '-', '-', 10, '-', '-'],
['-', '-', 13, '-', '-', 8],
]);
});
test('renaming series names, checking legend and X axis labels', () => {
const chartProps = new ChartProps({
formData: {
...formData,
increaseLabel: 'sale increase',
decreaseLabel: 'sale decrease',
totalLabel: 'sale total',
},
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect((transformedProps.echartOptions.legend as any).data).toEqual([
'sale increase',
'sale decrease',
'sale total',
]);
expect((transformedProps.echartOptions.xAxis as any).data).toEqual([
'2019',
'2020',
'sale total',
]);
expect(extractSeriesName(transformedProps)).toEqual([
'Assist',
'sale increase',
'sale decrease',
'sale total',
]);
});
test('hide totals', () => {
const chartProps = new ChartProps({
formData: { ...formData, series: 'bar', showTotal: false },
width: 800,
height: 600,
queriesData: [
{
data,
},
],
theme: supersetTheme,
});
const transformedProps = transformProps(
chartProps as unknown as EchartsWaterfallChartProps,
);
expect(extractSeries(transformedProps)).toEqual([
[0, 8],
[13, '-'],
['-', 5],
['-', '-'],
]);
});