This is an automated email from the ASF dual-hosted git repository.

yongjiezhao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new a6bf041edd feat(plugin-chart-echarts): add aggregate total for the 
Pie/Donuct chart (#19622)
a6bf041edd is described below

commit a6bf041eddcde0247461f35c806414df00ef105e
Author: Stephen Liu <[email protected]>
AuthorDate: Mon Apr 11 13:56:45 2022 +0800

    feat(plugin-chart-echarts): add aggregate total for the Pie/Donuct chart 
(#19622)
---
 .../plugin-chart-echarts/src/Pie/controlPanel.tsx  | 12 ++++
 .../plugin-chart-echarts/src/Pie/transformProps.ts | 79 +++++++++++++++++++++-
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx 
b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
index aab4af5458..c195c5e221 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx
@@ -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>],
         [
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts 
b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
index 237f4ae001..aeeec088b0 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts
@@ -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,
   };
 

Reply via email to