diff --git a/src/e3sm_quickview/app.py b/src/e3sm_quickview/app.py index a740518..09c2812 100644 --- a/src/e3sm_quickview/app.py +++ b/src/e3sm_quickview/app.py @@ -442,20 +442,26 @@ async def data_loading_open(self, simulation, connectivity): # Update Layer/Time values and ui layout n_cols = 0 available_tracks = [] + dim_units = {} for name, dim in self.source.dimensions.items(): values = dim.data # Convert to list for JSON serialization - self.state[name] = ( - values.tolist() - if hasattr(values, "tolist") - else list(values) - if values is not None - else [] - ) + if values is not None: + self.state[name] = ( + values.tolist() + if hasattr(values, "tolist") + else list(values) + ) + else: + self.state[name] = list(range(dim.size)) - if values is not None and len(values) > 1: + if dim.size > 1: n_cols += 1 available_tracks.append(name) + if dim.units: + dim_units[name] = dim.units + + self.state.dim_units = dim_units self.state.toolbar_slider_cols = 12 / n_cols if n_cols else 12 self.state.animation_tracks = available_tracks self.state.animation_track = ( diff --git a/src/e3sm_quickview/components/toolbars.py b/src/e3sm_quickview/components/toolbars.py index c5abcbf..80aa22d 100644 --- a/src/e3sm_quickview/components/toolbars.py +++ b/src/e3sm_quickview/components/toolbars.py @@ -366,7 +366,7 @@ def __init__(self): ) v3.VSpacer() v3.VLabel( - "{{ t_values ? parseFloat(t_values[t_idx]).toFixed(2) : '' }} hPa (k={{ t_idx }})", + "{{ dim_units[track] ? parseFloat(t_values[t_idx]).toFixed(2) + ' ' + dim_units[track] : 'Index value: ' + t_idx }} (k={{ t_idx }})", classes="text-body-2", ) v3.VSlider( @@ -418,7 +418,7 @@ def __init__(self): classes="text-subtitle-2 ml-2 mt-1", ) v3.VLabel( - "{{ t_values ? parseFloat(t_values[Number(t_idx)]).toFixed(2) : '' }} hPa", + "{{ dim_units[track] ? parseFloat(t_values[Number(t_idx)]).toFixed(2) + ' ' + dim_units[track] : 'Index value: ' + t_idx }}", classes="text-body-2 text-no-wrap ml-2 mt-1", ) @@ -438,7 +438,7 @@ def __init__(self): ) with v3.VRow(classes="ma-0 px-2 align-center"): v3.VSelect( - v_model=("animation_track", "timestamps"), + v_model=("animation_track", None), items=("available_animation_tracks", []), flat=True, variant="plain", @@ -450,7 +450,7 @@ def __init__(self): v3.VSlider( v_model=("animation_step", 1), min=0, - max=("amimation_step_max", 0), + max=("animation_step_max", 0), step=1, hide_details=True, density="compact", @@ -472,14 +472,14 @@ def __init__(self): v3.VIconBtn( icon="mdi-chevron-right", flat=True, - disabled=("animation_step === amimation_step_max",), - click="animation_step = Math.min(amimation_step_max, animation_step + 1)", + disabled=("animation_step === animation_step_max",), + click="animation_step = Math.min(animation_step_max, animation_step + 1)", ) v3.VIconBtn( icon="mdi-page-last", - disabled=("animation_step === amimation_step_max",), + disabled=("animation_step === animation_step_max",), flat=True, - click="animation_step = amimation_step_max", + click="animation_step = animation_step_max", ) v3.VDivider(vertical=True, classes="mx-2") v3.VIconBtn( @@ -491,10 +491,12 @@ def __init__(self): @change("animation_track") def _on_animation_track_change(self, animation_track, **_): self.state.animation_step = 0 - self.state.amimation_step_max = 0 + self.state.animation_step_max = 0 if animation_track: - self.state.amimation_step_max = len(self.state[animation_track]) - 1 + values = self.state[animation_track] + if values: + self.state.animation_step_max = len(values) - 1 @change("animation_step") def _on_animation_step(self, animation_track, animation_step, **_): @@ -510,7 +512,7 @@ async def _run_animation(self): with self.state as s: while s.animation_play: await asyncio.sleep(0.1) - if s.animation_step < s.amimation_step_max: + if s.animation_step < s.animation_step_max: with s: s.animation_step += 1 await self.server.network_completion