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

vavila pushed a commit to branch fix/use-natural-compare-for-series-sorting
in repository https://gitbox.apache.org/repos/asf/superset.git

commit ac7c4fd2aeb008596439237786cf9e5b8eddf0f8
Author: Vitor Avila <[email protected]>
AuthorDate: Tue Mar 25 15:46:28 2025 -0300

    fix(echarts): Sort series by name using naturalCompare
---
 superset-frontend/package-lock.json                |   4 +-
 .../plugins/plugin-chart-echarts/package.json      |   5 +-
 .../plugin-chart-echarts/src/utils/series.ts       |   8 +-
 .../plugin-chart-echarts/test/utils/series.test.ts | 111 +++++++++++++++++++++
 .../plugin-chart-echarts/types/external.d.ts       |   5 +
 5 files changed, 127 insertions(+), 6 deletions(-)

diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index 89f7f03163..40362d5e1c 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -34043,7 +34043,6 @@
       "version": "1.4.0",
       "resolved": 
"https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz";,
       "integrity": 
"sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/nearley": {
@@ -50730,7 +50729,8 @@
         "@types/react-redux": "^7.1.10",
         "d3-array": "^1.2.0",
         "dayjs": "^1.11.13",
-        "lodash": "^4.17.21"
+        "lodash": "^4.17.21",
+        "natural-compare-lite": "^1.4.0"
       },
       "peerDependencies": {
         "@superset-ui/chart-controls": "*",
diff --git a/superset-frontend/plugins/plugin-chart-echarts/package.json 
b/superset-frontend/plugins/plugin-chart-echarts/package.json
index 64da86afdc..5a23f54e43 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/package.json
+++ b/superset-frontend/plugins/plugin-chart-echarts/package.json
@@ -24,10 +24,11 @@
     "lib"
   ],
   "dependencies": {
+    "@types/react-redux": "^7.1.10",
     "d3-array": "^1.2.0",
-    "lodash": "^4.17.21",
     "dayjs": "^1.11.13",
-    "@types/react-redux": "^7.1.10"
+    "lodash": "^4.17.21",
+    "natural-compare-lite": "^1.4.0"
   },
   "peerDependencies": {
     "@superset-ui/chart-controls": "*",
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts 
b/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
index ef10fb9d3b..2afc7c5924 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
@@ -38,6 +38,7 @@ import { format } from 'echarts/core';
 import type { LegendComponentOption } from 'echarts/components';
 import type { SeriesOption } from 'echarts';
 import { isEmpty, maxBy, meanBy, minBy, orderBy, sumBy } from 'lodash';
+import naturalCompare from 'natural-compare-lite';
 import {
   NULL_STRING,
   StackControlsValue,
@@ -157,8 +158,11 @@ export function sortAndFilterSeries(
       aggregator = name => ({ name, value: meanBy(rows, name) });
       break;
     default:
-      aggregator = name => ({ name, value: name.toLowerCase() });
-      break;
+      return [...seriesNames].sort((a, b) =>
+        sortSeriesAscending
+          ? naturalCompare(a.toLowerCase(), b.toLowerCase())
+          : naturalCompare(b.toLowerCase(), a.toLowerCase()),
+      );
   }
 
   const sortedValues = seriesNames.map(aggregator);
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts 
b/superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts
index 7054f6019a..67a0bab9e6 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts
@@ -67,6 +67,39 @@ const sortData: DataRecord[] = [
   { my_x_axis: null, x: 4, y: 3, z: 7 },
 ];
 
+const sortDataWithNumbers: DataRecord[] = [
+  {
+    my_x_axis: 'my_axis',
+    '9. September': 6,
+    6: 1,
+    '11. November': 8,
+    8: 2,
+    '10. October': 1,
+    10: 4,
+    '3. March': 2,
+    '8. August': 6,
+    2: 1,
+    12: 3,
+    9: 1,
+    '1. January': 1,
+    '4. April': 12,
+    '2. February': 9,
+    5: 4,
+    3: 1,
+    11: 2,
+    '12. December': 4,
+    1: 7,
+    '6. June': 1,
+    4: 5,
+    7: 2,
+    c: 0,
+    '7. July': 2,
+    d: 0,
+    '5. May': 4,
+    a: 1,
+  },
+];
+
 const totalStackedValues = [3, 15, 14];
 
 test('sortRows by name ascending', () => {
@@ -288,6 +321,84 @@ test('sortAndFilterSeries by name descending', () => {
     sortAndFilterSeries(sortData, 'my_x_axis', [], SortSeriesType.Name, false),
   ).toEqual(['z', 'y', 'x']);
 });
+test('sortAndFilterSeries by name with numbers asc', () => {
+  expect(
+    sortAndFilterSeries(
+      sortDataWithNumbers,
+      'my_x_axis',
+      [],
+      SortSeriesType.Name,
+      true,
+    ),
+  ).toEqual([
+    '1',
+    '1. January',
+    '2',
+    '2. February',
+    '3',
+    '3. March',
+    '4',
+    '4. April',
+    '5',
+    '5. May',
+    '6',
+    '6. June',
+    '7',
+    '7. July',
+    '8',
+    '8. August',
+    '9',
+    '9. September',
+    '10',
+    '10. October',
+    '11',
+    '11. November',
+    '12',
+    '12. December',
+    'a',
+    'c',
+    'd',
+  ]);
+});
+test('sortAndFilterSeries by name with numbers desc', () => {
+  expect(
+    sortAndFilterSeries(
+      sortDataWithNumbers,
+      'my_x_axis',
+      [],
+      SortSeriesType.Name,
+      false,
+    ),
+  ).toEqual([
+    'd',
+    'c',
+    'a',
+    '12. December',
+    '12',
+    '11. November',
+    '11',
+    '10. October',
+    '10',
+    '9. September',
+    '9',
+    '8. August',
+    '8',
+    '7. July',
+    '7',
+    '6. June',
+    '6',
+    '5. May',
+    '5',
+    '4. April',
+    '4',
+    '3. March',
+    '3',
+    '2. February',
+    '2',
+    '1. January',
+    '1',
+  ]);
+});
 
 describe('extractSeries', () => {
   it('should generate a valid ECharts timeseries series object', () => {
diff --git a/superset-frontend/plugins/plugin-chart-echarts/types/external.d.ts 
b/superset-frontend/plugins/plugin-chart-echarts/types/external.d.ts
index ecdf68a745..584b549004 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/types/external.d.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/types/external.d.ts
@@ -23,3 +23,8 @@ declare module '*.png' {
 }
 
 declare module '*.jpg';
+
+declare module 'natural-compare-lite' {
+  function naturalCompare(a: string, b: string): number;
+  export default naturalCompare;
+}

Reply via email to