|
|
@@ -77,6 +77,13 @@ _C_TEXT_DARK = {
|
|
|
_MAX_VLINES = 400
|
|
|
|
|
|
|
|
|
+class _XOnlyViewBox(pg.ViewBox):
|
|
|
+ """ViewBox that zooms only the X axis on mouse wheel."""
|
|
|
+
|
|
|
+ def wheelEvent(self, ev, axis=None):
|
|
|
+ super().wheelEvent(ev, axis=0) # axis=0 → X only
|
|
|
+
|
|
|
+
|
|
|
class PlotPanel(QWidget):
|
|
|
"""
|
|
|
All waveforms and sync gates on a shared time axis.
|
|
|
@@ -168,6 +175,7 @@ class PlotPanel(QWidget):
|
|
|
cumtimes = np.cumsum([0.0] + list(durs))
|
|
|
self._draw_boundaries(cumtimes)
|
|
|
self._draw_delay_regions()
|
|
|
+ self._finalize_x_axis()
|
|
|
self._attach_mouse_events()
|
|
|
|
|
|
# Apply visibility.
|
|
|
@@ -238,6 +246,7 @@ class PlotPanel(QWidget):
|
|
|
self._draw_boundaries(cumtimes)
|
|
|
|
|
|
self._draw_delay_regions()
|
|
|
+ self._finalize_x_axis()
|
|
|
self._attach_mouse_events()
|
|
|
|
|
|
# Apply stored visibility state (same logic as plot_all)
|
|
|
@@ -263,6 +272,20 @@ class PlotPanel(QWidget):
|
|
|
if key in self._row_btns:
|
|
|
self._row_btns[key].setChecked(on)
|
|
|
|
|
|
+ def zoom_to_block(self, sync_index: int) -> None:
|
|
|
+ """
|
|
|
+ Center the view on the block and zoom so it occupies ~the middle third.
|
|
|
+ Double-padding on both sides: view_width = 3 * block_duration.
|
|
|
+ """
|
|
|
+ for row in self._block_rows:
|
|
|
+ if row.sync_index == sync_index:
|
|
|
+ dur = max(row.t_end - row.t_start, 1e-9)
|
|
|
+ mid = (row.t_start + row.t_end) / 2.0
|
|
|
+ half = dur * 1.5 # 3× block width total → block is central third
|
|
|
+ if self._ref_plot:
|
|
|
+ self._ref_plot.setXRange(mid - half, mid + half, padding=0)
|
|
|
+ break
|
|
|
+
|
|
|
def highlight_block(self, sync_index: int) -> None:
|
|
|
for row in self._block_rows:
|
|
|
if row.sync_index == sync_index:
|
|
|
@@ -490,12 +513,19 @@ class PlotPanel(QWidget):
|
|
|
# ------------------------------------------------------------------ #
|
|
|
|
|
|
def _add_row(self, key: str, label: str, units: str, h: int) -> pg.PlotItem:
|
|
|
- pw = pg.PlotWidget()
|
|
|
+ dark = system_is_dark()
|
|
|
+ lbl_color = "#ccccee" if dark else "#333355"
|
|
|
+
|
|
|
+ pw = pg.PlotWidget(viewBox=_XOnlyViewBox())
|
|
|
pw.setMinimumHeight(h)
|
|
|
pw.setMaximumHeight(h + 40)
|
|
|
p = pw.getPlotItem()
|
|
|
- p.setLabel("left", label, units=units)
|
|
|
+ p.setLabel("left", label, units=units, color=lbl_color, size="9pt")
|
|
|
p.showGrid(x=True, y=True, alpha=0.25)
|
|
|
+ # X-axis tick numbers hidden by default; shown only on the last row
|
|
|
+ p.getAxis("bottom").setStyle(showValues=False)
|
|
|
+ p.getAxis("bottom").setLabel("")
|
|
|
+
|
|
|
self._plot_widgets[key] = pw
|
|
|
self._plots[key] = p
|
|
|
self._plot_area_lay.addWidget(pw)
|
|
|
@@ -505,6 +535,23 @@ class PlotPanel(QWidget):
|
|
|
p.setXLink(self._ref_plot)
|
|
|
return p
|
|
|
|
|
|
+ def _finalize_x_axis(self) -> None:
|
|
|
+ """Show X-axis ticks + label only on the last (bottom) row."""
|
|
|
+ dark = system_is_dark()
|
|
|
+ lbl_color = "#ccccee" if dark else "#333355"
|
|
|
+ keys = list(self._plots.keys())
|
|
|
+ for i, key in enumerate(keys):
|
|
|
+ ax = self._plots[key].getAxis("bottom")
|
|
|
+ if i == len(keys) - 1:
|
|
|
+ ax.setStyle(showValues=True)
|
|
|
+ self._plots[key].setLabel(
|
|
|
+ "bottom", "Время", units="с",
|
|
|
+ color=lbl_color, size="9pt",
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ ax.setStyle(showValues=False)
|
|
|
+ ax.setLabel("")
|
|
|
+
|
|
|
def _add_row_btn(self, key: str, label: str, color_key: str) -> None:
|
|
|
_text = _C_TEXT_DARK if system_is_dark() else _C_TEXT_LIGHT
|
|
|
color = _text.get(color_key, _C.get(color_key, "#555555"))
|