jotpluggler: better defaults for zooming/fitting (#36149)

better defaults for zooming/fitting
pull/36150/head
Jimmy 1 week ago committed by GitHub
parent 63df46bf22
commit 8d3b919ef6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      tools/jotpluggler/pluggle.py
  2. 32
      tools/jotpluggler/views.py

@ -66,6 +66,7 @@ class PlaybackManager:
self.is_playing = False
self.current_time_s = 0.0
self.duration_s = 0.0
self.num_segments = 0
self.x_axis_bounds = (0.0, 0.0) # (min_time, max_time)
self.x_axis_observers = [] # callbacks for x-axis changes
@ -131,6 +132,7 @@ class MainController:
self.data_tree = DataTree(self.data_manager, self.playback_manager)
self.layout_manager = LayoutManager(self.data_manager, self.playback_manager, self.worker_manager, scale=self.scale)
self.data_manager.add_observer(self.on_data_loaded)
self._total_segments = 0
def _create_global_themes(self):
with dpg.theme(tag="line_theme"):
@ -158,10 +160,15 @@ class MainController:
duration = data.get('duration', 0.0)
self.playback_manager.set_route_duration(duration)
if data.get('reset'):
if data.get('metadata_loaded'):
self.playback_manager.num_segments = data.get('total_segments', 0)
self._total_segments = data.get('total_segments', 0)
dpg.set_value("load_status", f"Loading... 0/{self._total_segments} segments processed")
elif data.get('reset'):
self.playback_manager.current_time_s = 0.0
self.playback_manager.duration_s = 0.0
self.playback_manager.is_playing = False
self._total_segments = 0
dpg.set_value("load_status", "Loading...")
dpg.set_value("timeline_slider", 0.0)
dpg.configure_item("timeline_slider", max_value=0.0)
@ -173,7 +180,7 @@ class MainController:
dpg.configure_item("load_button", enabled=True)
elif data.get('segment_added'):
segment_count = data.get('segment_count', 0)
dpg.set_value("load_status", f"Loading... {segment_count} segments processed")
dpg.set_value("load_status", f"Loading... {segment_count}/{self._total_segments} segments processed")
dpg.configure_item("timeline_slider", max_value=duration)

@ -63,6 +63,7 @@ class TimeSeriesPanel(ViewPanel):
self._last_x_limits = (0.0, 0.0)
self._queued_x_sync: tuple | None = None
self._queued_reallow_x_zoom = False
self._total_segments = self.playback_manager.num_segments
def to_dict(self) -> dict:
return {
@ -89,6 +90,7 @@ class TimeSeriesPanel(ViewPanel):
dpg.bind_item_theme(timeline_series_tag, "timeline_theme")
self._new_data = True
self._queued_x_sync = self.playback_manager.x_axis_bounds
self._ui_created = True
def update(self):
@ -107,7 +109,19 @@ class TimeSeriesPanel(ViewPanel):
if self._queued_reallow_x_zoom:
self._queued_reallow_x_zoom = False
dpg.set_axis_limits_auto(self.x_axis_tag)
if tuple(dpg.get_axis_limits(self.x_axis_tag)) == self._last_x_limits:
dpg.set_axis_limits_auto(self.x_axis_tag)
else:
self._queued_x_sync = self._last_x_limits # retry, likely too early
return
if self._new_data: # handle new data in main thread
self._new_data = False
if self._total_segments > 0:
dpg.set_axis_limits_constraints(self.x_axis_tag, -10, self._total_segments * 60 + 10)
self._fit_y_axis(*dpg.get_axis_limits(self.x_axis_tag))
for series_path in list(self._series_data.keys()):
self.add_series(series_path, update=True)
current_limits = dpg.get_axis_limits(self.x_axis_tag)
# downsample if plot zoom changed significantly
@ -120,12 +134,6 @@ class TimeSeriesPanel(ViewPanel):
self._last_x_limits = current_limits
self._fit_y_axis(current_limits[0], current_limits[1])
if self._new_data: # handle new data in main thread
self._new_data = False
dpg.set_axis_limits_constraints(self.x_axis_tag, -10, (self.playback_manager.duration_s + 10))
for series_path in list(self._series_data.keys()):
self.add_series(series_path, update=True)
while self._results_deque: # handle downsampled results in main thread
results = self._results_deque.popleft()
for series_path, downsampled_time, downsampled_values in results:
@ -223,8 +231,7 @@ class TimeSeriesPanel(ViewPanel):
else:
line_series_tag = dpg.add_line_series(x=time_array, y=value_array.astype(float), label=series_path, parent=self.y_axis_tag, tag=series_tag)
dpg.bind_item_theme(line_series_tag, "line_theme")
dpg.fit_axis_data(self.x_axis_tag)
dpg.fit_axis_data(self.y_axis_tag)
self._fit_y_axis(*dpg.get_axis_limits(self.x_axis_tag))
plot_duration = dpg.get_axis_limits(self.x_axis_tag)[1] - dpg.get_axis_limits(self.x_axis_tag)[0]
self._downsample_all_series(plot_duration)
@ -252,7 +259,12 @@ class TimeSeriesPanel(ViewPanel):
del self._series_data[series_path]
def on_data_loaded(self, data: dict):
self._new_data = True
with self._update_lock:
self._new_data = True
if data.get('metadata_loaded'):
self._total_segments = data.get('total_segments', 0)
limits = (-10, self._total_segments * 60 + 10)
self._queued_x_sync = limits
def _on_series_drop(self, sender, app_data, user_data):
self.add_series(app_data)

Loading…
Cancel
Save