diff --git a/packages/grafana-data/src/utils/arrayUtils.test.ts b/packages/grafana-data/src/utils/arrayUtils.test.ts index 892624c5bb2..b41c3e728b7 100644 --- a/packages/grafana-data/src/utils/arrayUtils.test.ts +++ b/packages/grafana-data/src/utils/arrayUtils.test.ts @@ -7,21 +7,24 @@ describe('arrayUtils', () => { const testArrayNumeric = [1, 10, null, 2, undefined, 5, 6, ' ', 7, 9, 8, 3, 4]; const testArrayString = ['1', '10', null, '2', undefined, '5', '6', ' ', '7', '9', '8', '3', '4']; const testArrayFloatingPoint = ['1.0', '2.7', '0.5', ' ', null, '2', undefined]; + const testArrayVariableFloatingPoint = [1.1234567, 2.7, 1.23456, ' ', null, 2, undefined]; const testArrayText = ['baz', ' ', 'foo', null, 'bar', undefined]; const testArrayMixed = ['baz', ' ', 1, 'foo', '1.5', '0.5', null, 'bar', undefined]; it.each` - order | testArray | expected - ${SortOrder.Ascending} | ${testArrayNumeric} | ${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ' ', null, undefined]} - ${SortOrder.Descending} | ${testArrayNumeric} | ${[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ' ', null, undefined]} - ${SortOrder.Ascending} | ${testArrayString} | ${['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ' ', null, undefined]} - ${SortOrder.Descending} | ${testArrayString} | ${['10', '9', '8', '7', '6', '5', '4', '3', '2', '1', ' ', null, undefined]} - ${SortOrder.Ascending} | ${testArrayFloatingPoint} | ${['0.5', '1.0', '2', '2.7', null, ' ', undefined]} - ${SortOrder.Descending} | ${testArrayFloatingPoint} | ${['2.7', '2', '1.0', '0.5', null, ' ', undefined]} - ${SortOrder.Ascending} | ${testArrayText} | ${['bar', 'baz', 'foo', null, ' ', undefined]} - ${SortOrder.Descending} | ${testArrayText} | ${['foo', 'baz', 'bar', null, ' ', undefined]} - ${SortOrder.Ascending} | ${testArrayMixed} | ${['0.5', 1, '1.5', 'bar', 'baz', 'foo', null, ' ', undefined]} - ${SortOrder.Descending} | ${testArrayMixed} | ${['foo', 'baz', 'bar', '1.5', 1, '0.5', null, ' ', undefined]} + order | testArray | expected + ${SortOrder.Ascending} | ${testArrayNumeric} | ${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ' ', null, undefined]} + ${SortOrder.Descending} | ${testArrayNumeric} | ${[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ' ', null, undefined]} + ${SortOrder.Ascending} | ${testArrayString} | ${['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ' ', null, undefined]} + ${SortOrder.Descending} | ${testArrayString} | ${['10', '9', '8', '7', '6', '5', '4', '3', '2', '1', ' ', null, undefined]} + ${SortOrder.Ascending} | ${testArrayFloatingPoint} | ${['0.5', '1.0', '2', '2.7', null, ' ', undefined]} + ${SortOrder.Descending} | ${testArrayFloatingPoint} | ${['2.7', '2', '1.0', '0.5', null, ' ', undefined]} + ${SortOrder.Ascending} | ${testArrayText} | ${['bar', 'baz', 'foo', null, ' ', undefined]} + ${SortOrder.Descending} | ${testArrayText} | ${['foo', 'baz', 'bar', null, ' ', undefined]} + ${SortOrder.Ascending} | ${testArrayMixed} | ${['0.5', 1, '1.5', 'bar', 'baz', 'foo', null, ' ', undefined]} + ${SortOrder.Descending} | ${testArrayMixed} | ${['foo', 'baz', 'bar', '1.5', 1, '0.5', null, ' ', undefined]} + ${SortOrder.Ascending} | ${testArrayVariableFloatingPoint} | ${[1.1234567, 1.23456, 2, 2.7, null, ' ', undefined]} + ${SortOrder.Descending} | ${testArrayVariableFloatingPoint} | ${[2.7, 2, 1.23456, 1.1234567, null, ' ', undefined]} `('$order', ({ order, testArray, expected }) => { const sorted = [...testArray].sort(sortValues(order)); expect(sorted).toEqual(expected); diff --git a/packages/grafana-data/src/utils/arrayUtils.ts b/packages/grafana-data/src/utils/arrayUtils.ts index e8f4ab405d3..147969965ca 100644 --- a/packages/grafana-data/src/utils/arrayUtils.ts +++ b/packages/grafana-data/src/utils/arrayUtils.ts @@ -12,6 +12,8 @@ export function moveItemImmutably(arr: T[], from: number, to: number) { * Null/undefined/empty string values are always sorted to the end regardless of the sort order provided */ const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); +const numericCompare = (a: number, b: number) => a - b; + export function sortValues(sort: SortOrder.Ascending | SortOrder.Descending) { return (a: any, b: any) => { if (a === b) { @@ -25,9 +27,16 @@ export function sortValues(sort: SortOrder.Ascending | SortOrder.Descending) { return 1; } - if (sort === SortOrder.Descending) { - return collator.compare(b, a); + let compareFn: (a: any, b: any) => number = collator.compare; + + if (typeof a === 'number' && typeof b === 'number') { + compareFn = numericCompare; } - return collator.compare(a, b); + + if (sort === SortOrder.Descending) { + return compareFn(b, a); + } + + return compareFn(a, b); }; }