Skip to content

Commit

Permalink
feat(plugin-chart-echarts): add aggregate total for the Pie/Donuct ch…
Browse files Browse the repository at this point in the history
…art (#19622)
  • Loading branch information
stephenLYZ authored and pull[bot] committed Aug 2, 2024
1 parent 450300c commit f0bb761
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,18 @@ const config: ControlPanelConfig = {
},
},
],
[
{
name: 'show_total',
config: {
type: 'CheckboxControl',
label: t('Show Total'),
default: false,
renderTrigger: true,
description: t('Whether to display the aggregate count'),
},
},
],
// eslint-disable-next-line react/jsx-key
[<h1 className="section-header">{t('Pie shape')}</h1>],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getTimeFormatter,
NumberFormats,
NumberFormatter,
t,
} from '@superset-ui/core';
import { CallbackDataParams } from 'echarts/types/src/util/types';
import { EChartsCoreOption, PieSeriesOption } from 'echarts';
Expand All @@ -45,6 +46,7 @@ import {
} from '../utils/series';
import { defaultGrid, defaultTooltip } from '../defaults';
import { OpacityEnum } from '../constants';
import { convertInteger } from '../utils/convertInteger';

const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);

Expand Down Expand Up @@ -82,6 +84,54 @@ export function formatPieLabel({
}
}

function getTotalValuePadding({
chartPadding,
donut,
width,
height,
}: {
chartPadding: {
bottom: number;
left: number;
right: number;
top: number;
};
donut: boolean;
width: number;
height: number;
}) {
const padding: {
left?: string;
top?: string;
} = {
top: donut ? 'middle' : '0',
left: 'center',
};
const LEGEND_HEIGHT = 15;
const LEGEND_WIDTH = 215;
if (chartPadding.top) {
padding.top = donut
? `${50 + ((chartPadding.top - LEGEND_HEIGHT) / height / 2) * 100}%`
: `${((chartPadding.top + LEGEND_HEIGHT) / height) * 100}%`;
}
if (chartPadding.bottom) {
padding.top = donut
? `${50 - ((chartPadding.bottom + LEGEND_HEIGHT) / height / 2) * 100}%`
: '0';
}
if (chartPadding.left) {
padding.left = `${
50 + ((chartPadding.left - LEGEND_WIDTH) / width / 2) * 100
}%`;
}
if (chartPadding.right) {
padding.left = `${
50 - ((chartPadding.right + LEGEND_WIDTH) / width / 2) * 100
}%`;
}
return padding;
}

export default function transformProps(
chartProps: EchartsPieChartProps,
): PieChartTransformedProps {
Expand Down Expand Up @@ -110,6 +160,7 @@ export default function transformProps(
showLabelsThreshold,
emitFilter,
sliceId,
showTotal,
}: EchartsPieFormData = {
...DEFAULT_LEGEND_FORM_DATA,
...DEFAULT_PIE_FORM_DATA,
Expand Down Expand Up @@ -147,6 +198,7 @@ export default function transformProps(

const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
const numberFormatter = getNumberFormatter(numberFormat);
let totalValue = 0;

const transformedData: PieSeriesOption[] = data.map(datum => {
const name = extractGroupbyLabel({
Expand All @@ -158,9 +210,14 @@ export default function transformProps(

const isFiltered =
filterState.selectedValues && !filterState.selectedValues.includes(name);
const value = datum[metricLabel];

if (typeof value === 'number' || typeof value === 'string') {
totalValue += convertInteger(value);
}

return {
value: datum[metricLabel],
value,
name,
itemStyle: {
color: colorFn(name, sliceId),
Expand Down Expand Up @@ -197,10 +254,16 @@ export default function transformProps(
color: '#000000',
};

const chartPadding = getChartPadding(
showLegend,
legendOrientation,
legendMargin,
);

const series: PieSeriesOption[] = [
{
type: 'pie',
...getChartPadding(showLegend, legendOrientation, legendMargin),
...chartPadding,
animation: false,
radius: [`${donut ? innerRadius : 0}%`, `${outerRadius}%`],
center: ['50%', '50%'],
Expand Down Expand Up @@ -248,6 +311,18 @@ export default function transformProps(
...getLegendProps(legendType, legendOrientation, showLegend),
data: keys,
},
graphic: showTotal
? {
type: 'text',
...getTotalValuePadding({ chartPadding, donut, width, height }),
style: {
text: t(`Total: ${numberFormatter(totalValue)}`),
fontSize: 16,
fontWeight: 'bold',
},
z: 10,
}
: null,
series,
};

Expand Down

0 comments on commit f0bb761

Please sign in to comment.