@@ -7,13 +7,68 @@ import {
77 type S2Options ,
88 type SortMethod ,
99 TableSheet ,
10+ type SortFuncParam ,
1011} from '@antv/s2'
1112import { debounce , filter } from 'lodash-es'
1213import { i18n } from '@/i18n'
1314import '@antv/s2/dist/s2.min.css'
1415
1516const { 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+
1772export 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