Plot tab: auto-zoom Y axis on first draw after connect / trace change

Track a _needs_autozoom flag per plot. Set True at startup, on
reconnect (clear_data), and when a trace is added or removed. In
_redraw, when the flag is set and visible data exists, fit the Y range
to the data (with 10% margin) then clear the flag — subsequent live
updates leave the user's manual Y zoom undisturbed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 16:50:14 +02:00
co-authored by Claude Sonnet 4.6
parent 849473acc0
commit ad3cbf4859
+12
View File
@@ -466,6 +466,7 @@ class PlotTab(QWidget):
self._chip_bars: list[QHBoxLayout] = []
self._date_labels: list[QLabel] = []
self._tooltips: list[PlotTooltip] = []
self._needs_autozoom: list[bool] = [True] * self.NUM_PLOTS
for i in range(self.NUM_PLOTS):
cell = QWidget()
@@ -563,6 +564,7 @@ class PlotTab(QWidget):
return
traces.append(key)
self._add_chip(plot_idx, key, len(traces) - 1)
self._needs_autozoom[plot_idx] = True
self._save_settings()
self._redraw()
@@ -584,6 +586,7 @@ class PlotTab(QWidget):
return
self._traces[plot_idx].remove(key)
self._rebuild_chips(plot_idx)
self._needs_autozoom[plot_idx] = True
self._save_settings()
self._redraw()
@@ -604,6 +607,7 @@ class PlotTab(QWidget):
self._units.clear()
for tt in self._tooltips:
tt.hide()
self._needs_autozoom = [True] * self.NUM_PLOTS
self._redraw()
def update(self, snapshot: dict):
@@ -702,6 +706,7 @@ class PlotTab(QWidget):
pi.legend.clear()
x_min = None
y_all: list[float] = []
for j, key in enumerate(self._traces[i]):
if key not in self._series:
continue
@@ -710,6 +715,7 @@ class PlotTab(QWidget):
continue
times, values = zip(*series)
x_min = times[0] if x_min is None else min(x_min, times[0])
y_all.extend(values)
label = f"{_trace_label(key)} [{self._units.get(key, '')}]"
pw.plot(
list(times), list(values),
@@ -720,6 +726,12 @@ class PlotTab(QWidget):
x_lo = x_min if x_min is not None else cutoff
pw.setXRange(x_lo, now, padding=0.02)
if y_all and self._needs_autozoom[i]:
y_min, y_max = min(y_all), max(y_all)
margin = max((y_max - y_min) * 0.1, 1.0)
pw.setYRange(y_min - margin, y_max + margin, padding=0)
self._needs_autozoom[i] = False
d_lo = datetime.fromtimestamp(x_lo).date()
d_hi = datetime.fromtimestamp(now).date()
if d_lo == d_hi: