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',
+    ]);
+  });
+});

Reply via email to