11import asyncio
22import datetime
33import json
4+ import math
45import os
6+ from functools import partial
57from pathlib import Path
68
79from trame .app import TrameApp , asynchronous , file_upload
@@ -420,22 +422,18 @@ async def data_loading_open(self, simulation, connectivity):
420422 if values is not None
421423 else []
422424 )
425+
423426 if values is not None and len (values ) > 1 :
424427 n_cols += 1
425- available_tracks .append ({ "title" : name , "value" : name } )
428+ available_tracks .append (name )
426429 self .state .toolbar_slider_cols = 12 / n_cols if n_cols else 12
427430 self .state .animation_tracks = available_tracks
428431 self .state .animation_track = (
429- self .state .animation_tracks [0 ]["value" ]
430- if available_tracks
431- else None
432+ self .state .animation_tracks [0 ] if available_tracks else None
432433 )
433434
434- from functools import partial
435-
436435 # Initialize dynamic index variables for each dimension
437- for track in available_tracks :
438- dim_name = track ["value" ]
436+ for dim_name in available_tracks :
439437 index_var = f"{ dim_name } _idx"
440438 if "time" in index_var :
441439 self .state [index_var ] = 50
@@ -461,6 +459,19 @@ async def _data_load_variables(self):
461459 # Flatten the list of lists
462460 flattened_vars = [var for var_list in vars_to_show .values () for var in var_list ]
463461
462+ # Compute used dimensions
463+ used_dims = set ()
464+ for dims in self .selected_variables .keys ():
465+ used_dims .update (dims )
466+ self .state .available_animation_tracks = [
467+ n for n in self .state .animation_tracks if n in used_dims
468+ ]
469+ self .state .animation_track = (
470+ self .state .available_animation_tracks [0 ]
471+ if self .state .available_animation_tracks
472+ else None
473+ )
474+
464475 self .source .LoadVariables (flattened_vars )
465476
466477 # Trigger source update + compute avg
@@ -498,13 +509,21 @@ async def _on_projection(self, projection, **_):
498509 await asyncio .sleep (0.1 )
499510 self .view_manager .reset_camera ()
500511
501- @change ("active_tools" , "animation_tracks " )
512+ @change ("active_tools" , "available_animation_tracks " )
502513 def _on_toolbar_change (self , active_tools , ** _ ):
503514 top_padding = 0
504515 for name in active_tools :
505516 if name == "select-slice-time" :
506- track_count = len (self .state .animation_tracks or [])
507- rows_needed = max (1 , (track_count + 2 ) // 3 ) # 3 sliders per row
517+ track_count = len (self .state .available_animation_tracks or [])
518+ rows_needed = 1
519+ if track_count > 3 :
520+ if track_count % 3 == 0 or (track_count + 1 ) % 3 == 0 :
521+ rows_needed = math .ceil (track_count / 3 )
522+ elif track_count % 2 == 0 :
523+ rows_needed = track_count / 2
524+ else :
525+ rows_needed = math .ceil (track_count / 3 )
526+
508527 top_padding += 70 * rows_needed
509528 else :
510529 top_padding += toolbars .SIZES .get (name , 0 )
0 commit comments