mirror of
https://github.com/apache/superset.git
synced 2024-09-06 13:57:40 -04:00
feat(plugin-chart-echarts): add aggregate total for the Pie/Donuct chart (#19622)
This commit is contained in:
parent
b45f89b954
commit
a6bf041edd
@ -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>],
|
||||
[
|
||||
|
@ -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';
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
@ -110,6 +160,7 @@ export default function transformProps(
|
||||
showLabelsThreshold,
|
||||
emitFilter,
|
||||
sliceId,
|
||||
showTotal,
|
||||
}: EchartsPieFormData = {
|
||||
...DEFAULT_LEGEND_FORM_DATA,
|
||||
...DEFAULT_PIE_FORM_DATA,
|
||||
@ -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({
|
||||
@ -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),
|
||||
@ -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%'],
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user