@@ -1187,6 +1187,10 @@ def get_sequence_adapter(data):
11871187
11881188@adapter_for (collections .abc .Mapping )
11891189class MappingAdapter (AbstractAdapter ):
1190+ def __init__ (self , data , attributes ):
1191+ super ().__init__ (data , attributes = attributes )
1192+ self .sorted_data = data
1193+
11901194 def shape2d (self ):
11911195 return len (self .data ), 1
11921196
@@ -1204,12 +1208,45 @@ def get_vlabels_values(self, start, stop):
12041208 # the absence of stale cache problem. Performance-wise, we could cache keys() and
12051209 # values() here (instead of in __init__) if start or stop is above some threshold
12061210 # but I am unsure it is worth the added complexity.
1207- return [[k ] for k in itertools .islice (self .data .keys (), start , stop )]
1211+ return [[k ] for k in itertools .islice (self .sorted_data .keys (), start , stop )]
12081212
12091213 def get_values (self , h_start , v_start , h_stop , v_stop ):
1210- values_chunk = itertools .islice (self .data .values (), v_start , v_stop )
1214+ values_chunk = itertools .islice (self .sorted_data .values (), v_start , v_stop )
12111215 return [[v ] for v in values_chunk ]
12121216
1217+ def can_sort_hlabel (self , row_idx , col_idx ):
1218+ return True
1219+
1220+ def sort_hlabel (self , row_idx , col_idx , ascending ):
1221+ assert row_idx == 0
1222+ assert col_idx == 0
1223+ try :
1224+ # first try the values themselves as sort key...
1225+ self .sorted_data = dict (sorted (self .data .items (),
1226+ key = lambda items : items [1 ],
1227+ reverse = not ascending ))
1228+ except TypeError :
1229+ # ... but that will fail for unsortable types or mixed type mappings
1230+ # for those cases, we fall back to sorting by str.
1231+ # We should keep this (str vs repr) in sync with
1232+ # AbstractArrayModel._format_value, so that the sorting order
1233+ # matches the displayed values.
1234+
1235+ # By using the following commented code, we could also sort all
1236+ # numbers after strings and that would allow sorting them more
1237+ # naturally (9 before 10), but might be unexpected for users.
1238+ # Unsure what is best.
1239+ # def get_key(items):
1240+ # value = items[1]
1241+ # if isinstance(value, (int, float)):
1242+ # return True, value
1243+ # else:
1244+ # return False, str(value)
1245+ self .sorted_data = dict (sorted (self .data .items (),
1246+ key = lambda items : str (items [1 ]),
1247+ reverse = not ascending ))
1248+ self ._current_sort = [(1 , 0 , ascending )]
1249+
12131250
12141251# @adapter_for(object)
12151252# class ObjectAdapter(AbstractAdapter):
0 commit comments