Skip to content

Commit ec86ee7

Browse files
committed
fix: float number sort in Table
#922
1 parent 662d4a1 commit ec86ee7

File tree

1 file changed

+66
-1
lines changed
  • frontend/src/views/chat/component/charts

1 file changed

+66
-1
lines changed

frontend/src/views/chat/component/charts/Table.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,68 @@ import {
77
type S2Options,
88
type SortMethod,
99
TableSheet,
10+
type SortFuncParam,
1011
} from '@antv/s2'
1112
import { debounce, filter } from 'lodash-es'
1213
import { i18n } from '@/i18n'
1314
import '@antv/s2/dist/s2.min.css'
1415

1516
const { t } = i18n.global
1617

18+
const createSmartSortFunc = (sortMethod: string) => {
19+
const compareNumericString = (a: string, b: string): number => {
20+
const isNegA = a.startsWith('-')
21+
const isNegB = b.startsWith('-')
22+
23+
// 负数 < 正数
24+
if (isNegA && !isNegB) return -1
25+
if (!isNegA && isNegB) return 1
26+
27+
const [intA, decA = ''] = isNegA ? a.slice(1).split('.') : a.split('.')
28+
const [intB, decB = ''] = isNegB ? b.slice(1).split('.') : b.split('.')
29+
30+
// 都是正数
31+
if (!isNegA && !isNegB) {
32+
if (intA.length !== intB.length) return intA.length - intB.length
33+
const intCmp = intA.localeCompare(intB)
34+
if (intCmp !== 0) return intCmp
35+
if (decA && decB) return decA.localeCompare(decB)
36+
return decA ? 1 : decB ? -1 : 0
37+
}
38+
39+
// 都是负数:绝对值大的实际值小,比较结果取反
40+
if (intA.length !== intB.length) return -(intA.length - intB.length)
41+
const intCmp = intA.localeCompare(intB)
42+
if (intCmp !== 0) return -intCmp
43+
if (decA && decB) return -decA.localeCompare(decB)
44+
return decA ? 1 : decB ? -1 : 0
45+
}
46+
47+
return (params: SortFuncParam) => {
48+
const { data, sortFieldId } = params
49+
if (!data || data.length === 0) return data
50+
const isAsc = sortMethod.toLowerCase() === 'asc'
51+
return [...data].sort((a: any, b: any) => {
52+
const valA = a[sortFieldId],
53+
valB = b[sortFieldId]
54+
if (valA == null) return isAsc ? -1 : 1
55+
if (valB == null) return isAsc ? 1 : -1
56+
const strA = String(valA),
57+
strB = String(valB)
58+
const isNumA = !isNaN(Number(strA)) && strA.trim() !== ''
59+
const isNumB = !isNaN(Number(strB)) && strB.trim() !== ''
60+
if (isNumA && !isNumB) return isAsc ? -1 : 1
61+
if (!isNumA && isNumB) return isAsc ? 1 : -1
62+
if (isNumA && isNumB) {
63+
const cmp = compareNumericString(strA, strB)
64+
return isAsc ? cmp : -cmp
65+
}
66+
const cmp = strA.localeCompare(strB)
67+
return isAsc ? cmp : -cmp
68+
})
69+
}
70+
}
71+
1772
export class Table extends BaseChart {
1873
table?: TableSheet = undefined
1974

@@ -81,7 +136,17 @@ export class Table extends BaseChart {
81136
const sortOrder = ['none', 'desc', 'asc']
82137
const nextMethod = sortOrder[(sortOrder.indexOf(currentMethod) + 1) % sortOrder.length]
83138
sortState[fieldId] = nextMethod
84-
s2.groupSortByMethod(nextMethod === 'none' ? 'none' : (nextMethod as SortMethod), meta)
139+
if (nextMethod === 'none') {
140+
s2.emit(S2Event.RANGE_SORT, [{ sortFieldId: fieldId, sortMethod: 'none' as SortMethod }])
141+
} else {
142+
s2.emit(S2Event.RANGE_SORT, [
143+
{
144+
sortFieldId: fieldId,
145+
sortMethod: nextMethod as SortMethod,
146+
sortFunc: createSmartSortFunc(nextMethod),
147+
},
148+
])
149+
}
85150
s2.render()
86151
}
87152
}

0 commit comments

Comments
 (0)