This is an automated email from the ASF dual-hosted git repository. rusackas 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 dc7a8844eb feat(pie): add sort legend (#34323) dc7a8844eb is described below commit dc7a8844eb01f0d6f71df706824e26fd4f6d10aa Author: SBIN2010 <132096459+sbin2...@users.noreply.github.com> AuthorDate: Fri Aug 29 22:19:14 2025 +0300 feat(pie): add sort legend (#34323) --- .../plugin-chart-echarts/src/Pie/controlPanel.tsx | 3 +- .../plugin-chart-echarts/src/Pie/transformProps.ts | 8 +- .../plugins/plugin-chart-echarts/src/Pie/types.ts | 1 + .../plugins/plugin-chart-echarts/src/controls.tsx | 18 ++++ .../test/Pie/transformProps.test.ts | 100 +++++++++++++++++++++ 5 files changed, 128 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 4f93c0ed2c..7695272b68 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx @@ -29,7 +29,7 @@ import { sharedControls, } from '@superset-ui/chart-controls'; import { DEFAULT_FORM_DATA } from './types'; -import { legendSection } from '../controls'; +import { legendSection, legendSortControl } from '../controls'; const { donut, @@ -119,6 +119,7 @@ const config: ControlPanelConfig = { }, ], ...legendSection, + [legendSortControl], // eslint-disable-next-line react/jsx-key [<ControlSubSectionHeader>{t('Labels')}</ControlSubSectionHeader>], [ 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 e3980a02b3..e6fee12248 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/transformProps.ts @@ -151,6 +151,7 @@ export default function transformProps( legendMargin, legendOrientation, legendType, + legendSort, metric = '', numberFormat, currencyFormat, @@ -435,7 +436,12 @@ export default function transformProps( }, legend: { ...getLegendProps(legendType, legendOrientation, showLegend, theme), - data: transformedData.map(datum => datum.name), + data: transformedData + .map(datum => datum.name) + .sort((a: string, b: string) => { + if (!legendSort) return 0; + return legendSort === 'asc' ? a.localeCompare(b) : b.localeCompare(a); + }), }, graphic: showTotal ? { diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/types.ts index c684dcf457..a72a43906d 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/types.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/types.ts @@ -40,6 +40,7 @@ export type EchartsPieFormData = QueryFormData & labelType: EchartsPieLabelType; labelTemplate: string | null; labelsOutside: boolean; + legendSort: 'asc' | 'desc' | null; metric?: string; outerRadius: number; showLabels: boolean; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx index 088d5b7ba0..ac8ba387f5 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/controls.tsx @@ -97,6 +97,24 @@ const legendOrientationControl: ControlSetItem = { }, }; +export const legendSortControl: ControlSetItem = { + name: 'legendSort', + config: { + type: 'SelectControl', + label: t('Sort legend'), + default: null, + renderTrigger: true, + choices: [ + ['asc', t('Label ascending')], + ['desc', t('Label descending')], + [null, t('Sort by data')], + ], + description: t('Changes the sort value of the items in the legend only'), + visibility: ({ controls }: ControlPanelsContainerProps) => + Boolean(controls?.show_legend?.value), + }, +}; + export const legendSection: ControlSetRow[] = [ [<ControlSubSectionHeader>{t('Legend')}</ControlSubSectionHeader>], [showLegendControl], diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/Pie/transformProps.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/Pie/transformProps.test.ts index 087f1f4929..00c883d91d 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/test/Pie/transformProps.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/test/Pie/transformProps.test.ts @@ -445,3 +445,103 @@ describe('Other category', () => { expect(data[3].isOther).toBe(true); }); }); + +describe('Sort Legend', () => { + const defaultFormData: SqlaFormData = { + colorScheme: 'bnbColors', + datasource: '3__table', + granularity_sqla: 'ds', + metric: 'metric', + groupby: ['foo', 'bar'], + viz_type: 'my_viz', + }; + + const getChartProps = (formData: Partial<SqlaFormData>) => + new ChartProps({ + formData: { + ...defaultFormData, + ...formData, + }, + width: 800, + height: 600, + queriesData: [ + { + data: [ + { + foo: 'A foo', + bar: 'A bar', + metric: 1, + }, + { + foo: 'D foo', + bar: 'D bar', + metric: 2, + }, + + { + foo: 'C foo', + bar: 'C bar', + metric: 3, + }, + { + foo: 'B foo', + bar: 'B bar', + metric: 4, + }, + + { + foo: 'E foo', + bar: 'E bar', + metric: 5, + }, + ], + }, + ], + theme: supersetTheme, + }); + + it('sort legend by data', () => { + const chartProps = getChartProps({ + legendSort: null, + }); + const transformed = transformProps(chartProps as EchartsPieChartProps); + + expect((transformed.echartOptions.legend as any).data).toEqual([ + 'A foo, A bar', + 'D foo, D bar', + 'C foo, C bar', + 'B foo, B bar', + 'E foo, E bar', + ]); + }); + + it('sort legend by label ascending', () => { + const chartProps = getChartProps({ + legendSort: 'asc', + }); + const transformed = transformProps(chartProps as EchartsPieChartProps); + + expect((transformed.echartOptions.legend as any).data).toEqual([ + 'A foo, A bar', + 'B foo, B bar', + 'C foo, C bar', + 'D foo, D bar', + 'E foo, E bar', + ]); + }); + + it('sort legend by label descending', () => { + const chartProps = getChartProps({ + legendSort: 'desc', + }); + const transformed = transformProps(chartProps as EchartsPieChartProps); + + expect((transformed.echartOptions.legend as any).data).toEqual([ + 'E foo, E bar', + 'D foo, D bar', + 'C foo, C bar', + 'B foo, B bar', + 'A foo, A bar', + ]); + }); +});