This is an automated email from the ASF dual-hosted git repository. vavila pushed a commit to branch feat/natural-compare-sorting in repository https://gitbox.apache.org/repos/asf/superset.git
commit 51ac6c9491f792bd88dad2bd8b3212fc3bc968d0 Author: Vitor Avila <[email protected]> AuthorDate: Tue Mar 25 10:34:50 2025 -0300 feat(echarts): Use naturalCompare for series sorting --- superset-frontend/package-lock.json | 5 +- superset-frontend/package.json | 1 + .../plugin-chart-echarts/src/utils/series.ts | 8 ++- .../plugin-chart-echarts/test/utils/series.test.ts | 75 ++++++++++++++++++++++ .../plugin-chart-echarts/types/external.d.ts | 5 ++ 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 89f7f03163..c234c050a4 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -99,6 +99,7 @@ "mousetrap": "^1.6.5", "mustache": "^4.2.0", "nanoid": "^5.0.9", + "natural-compare-lite": "^1.4.0", "ol": "^7.5.2", "polished": "^4.3.1", "prop-types": "^15.8.1", @@ -34042,9 +34043,7 @@ "node_modules/natural-compare-lite": { "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" + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" }, "node_modules/nearley": { "version": "2.20.1", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 5a1ce072d9..53fd32cc83 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -166,6 +166,7 @@ "mousetrap": "^1.6.5", "mustache": "^4.2.0", "nanoid": "^5.0.9", + "natural-compare-lite": "^1.4.0", "ol": "^7.5.2", "polished": "^4.3.1", "prop-types": "^15.8.1", 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..2bb870ceb4 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,27 @@ const sortData: DataRecord[] = [ { my_x_axis: null, x: 4, y: 3, z: 7 }, ]; +const sortDataWithNumbers: DataRecord[] = [ + { + my_x_axis: 'my_axis', + 6: 1, + 8: 2, + 10: 4, + 2: 1, + 12: 3, + 9: 1, + 5: 4, + 3: 1, + 11: 2, + 1: 7, + 4: 5, + 7: 2, + c: 0, + d: 0, + a: 1, + }, +]; + const totalStackedValues = [3, 15, 14]; test('sortRows by name ascending', () => { @@ -288,6 +309,60 @@ test('sortAndFilterSeries by name descending', () => { sortAndFilterSeries(sortData, 'my_x_axis', [], SortSeriesType.Name, false), ).toEqual(['z', 'y', 'x']); }); +test('sortAndFilterSeries by name with integers asc', () => { + expect( + sortAndFilterSeries( + sortDataWithNumbers, + 'my_x_axis', + [], + SortSeriesType.Name, + true, + ), + ).toEqual([ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + 'a', + 'c', + 'd', + ]); +}); +test('sortAndFilterSeries by name with integers desc', () => { + expect( + sortAndFilterSeries( + sortDataWithNumbers, + 'my_x_axis', + [], + SortSeriesType.Name, + false, + ), + ).toEqual([ + 'd', + 'c', + 'a', + '12', + '11', + '10', + '9', + '8', + '7', + '6', + '5', + '4', + '3', + '2', + '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; +}
