@@ -189,7 +189,7 @@ type ColumnFilterCache = egui::util::cache::FrameCache<IndexSet<String>, CacheA>
189
189
impl egui:: util:: cache:: ComputerMut < ( & Column , & Vec < JsonArrayEntries < String > > , & String ) , IndexSet < String > > for CacheA {
190
190
fn compute ( & mut self , ( column, nodes, parent_pointer) : ( & Column , & Vec < JsonArrayEntries < String > > , & String ) ) -> IndexSet < String > {
191
191
let mut unique_values = IndexSet :: new ( ) ;
192
- if matches ! ( column . value_type , ValueType :: String ) {
192
+ if ArrayTable :: is_filterable ( column ) {
193
193
nodes. iter ( ) . enumerate ( ) . map ( |( i, row) | {
194
194
ArrayTable :: get_pointer_for_column ( parent_pointer, & & row. entries , i, column) . filter ( |entry| entry. value . is_some ( ) ) . map ( |entry| entry. value . clone ( ) . unwrap ( ) )
195
195
} ) . for_each ( |value| {
@@ -198,7 +198,22 @@ impl egui::util::cache::ComputerMut<(&Column, &Vec<JsonArrayEntries<String>>, &S
198
198
}
199
199
} )
200
200
}
201
- unique_values. sort_by ( |a, b| a. cmp ( b) ) ;
201
+ if matches ! ( column. value_type, ValueType :: Number ) {
202
+ unique_values. sort_by ( |a, b| {
203
+ let num_a = a. parse :: < f64 > ( ) ;
204
+ let num_b = b. parse :: < f64 > ( ) ;
205
+
206
+ // Compare parsed numbers; handle parse errors by pushing them to the end
207
+ match ( num_a, num_b) {
208
+ ( Ok ( a) , Ok ( b) ) => a. partial_cmp ( & b) . unwrap_or ( std:: cmp:: Ordering :: Equal ) ,
209
+ ( Ok ( _) , Err ( _) ) => std:: cmp:: Ordering :: Less , // Numbers are less than errors
210
+ ( Err ( _) , Ok ( _) ) => std:: cmp:: Ordering :: Greater , // Errors are greater than numbers
211
+ ( Err ( _) , Err ( _) ) => std:: cmp:: Ordering :: Equal , // Treat errors equally
212
+ }
213
+ } ) ;
214
+ } else {
215
+ unique_values. sort_by ( |a, b| a. cmp ( b) ) ;
216
+ }
202
217
unique_values
203
218
}
204
219
}
@@ -416,14 +431,14 @@ impl ArrayTable {
416
431
if column. name . eq ( "" ) {
417
432
return ;
418
433
}
419
- let response = icon:: button ( ui, THUMBTACK , if pinned_column_table { "Unpin column" } else { "Pin column to left" } ) ;
434
+ let response = icon:: button ( ui, THUMBTACK , Some ( if pinned_column_table { "Unpin column" } else { "Pin column to left" } ) , None ) ;
420
435
if response. clicked ( ) {
421
436
pinned_column = Some ( index) ;
422
437
}
423
438
let column_id = Id :: new ( & name) ;
424
439
let checked_filtered_values = self . columns_filter . get ( & column. name ) ;
425
440
PopupMenu :: new ( column_id. with ( "filter" ) )
426
- . show_ui ( ui, |ui| icon:: button_with_color ( ui, FILTER , "Filter column by" , if checked_filtered_values. is_some ( ) { Some ( ACTIVE_COLOR ) } else { None } ) ,
441
+ . show_ui ( ui, |ui| icon:: button ( ui, FILTER , None , if checked_filtered_values. is_some ( ) { Some ( ACTIVE_COLOR ) } else { None } ) ,
427
442
|ui| {
428
443
let mut chcked = if let Some ( filters) = checked_filtered_values {
429
444
filters. contains ( & NON_NULL_FILTER_VALUE . to_owned ( ) )
@@ -434,7 +449,7 @@ impl ArrayTable {
434
449
clicked_filter_non_null_column = Some ( name) ;
435
450
}
436
451
437
- if matches ! ( column . value_type , ValueType :: String ) {
452
+ if Self :: is_filterable ( column ) {
438
453
let values = ui. memory_mut ( |mem| {
439
454
let cache = mem. caches . cache :: < ColumnFilterCache > ( ) ;
440
455
@@ -672,6 +687,11 @@ impl ArrayTable {
672
687
array_response
673
688
}
674
689
690
+ #[ inline]
691
+ fn is_filterable ( column : & Column ) -> bool {
692
+ !( matches ! ( column. value_type, ValueType :: Object ( _) ) || matches ! ( column. value_type, ValueType :: Array ( _) ) || matches ! ( column. value_type, ValueType :: Null ) )
693
+ }
694
+
675
695
fn open_subtable ( row_index : usize , entry : & FlatJsonValue < String > , content : String ) -> Option < SubTable > {
676
696
// if matches!(entry.pointer.value_type, ValueType::Object(false)) {
677
697
// let options = ParseOptions::default().parse_array(true).keep_object_raw_data(false).start_parse_at(entry.pointer.pointer.clone())
0 commit comments