1212from accwidgets .graph import StaticPlotWidget
1313from accwidgets .graph .widgets .plotitem import ExViewBox
1414from accwidgets .graph .widgets .plotwidget import GridOrientationOptions
15- from qtpy .QtCore import Signal , Qt , QRectF , QEvent
15+ from qtpy .QtCore import Signal , Qt
1616
1717if TYPE_CHECKING :
18+ from pyqtgraph .GraphicsScene import mouseEvents
1819 from qtpy .QtWidgets import QGraphicsSceneMouseEvent
1920
20-
21+ YAXES_WIDTH : int = 60
2122
2223class ObservablePlotDataItem (pg .PlotDataItem ):
2324 """A PlotDataItem that emits a signal when visibility changes."""
@@ -41,8 +42,10 @@ def __init__(self, *args, **kwargs) -> None:
4142 self .addWidget (self .top , row = 0 , col = 0 )
4243 self .addWidget (self .bottom , row = 1 , col = 0 )
4344
44- # self.top.setMouseMode(pg.ViewBox.RectMode)
45- # self.bottom.setMouseMode(pg.ViewBox.PanMode)
45+ # set margins, so the axes line up
46+ for plot in (self .top , self .bottom ):
47+ plot .setContentsMargins (0 , 0 , 0 , 0 )
48+ plot .plotItem .getAxis ("left" ).setWidth (YAXES_WIDTH ) # keep constant
4649
4750 @property
4851 def plots (self ) -> tuple [pg .PlotWidget , pg .PlotWidget ]:
@@ -81,15 +84,17 @@ class ZoomingViewBox(ExViewBox):
8184 def __init__ (self , * args , ** kwargs ) -> None :
8285 super ().__init__ (* args , ** kwargs )
8386 self .setMouseMode (ZoomingViewBox .RectMode ) # mode that makes zooming rectangles
84- self ._zoom_history : list [QRectF ] = []
8587
8688 def suggestPadding (self , axis ):
89+ """ Suggests padding (between the data and the axis) for the autoRange function.
90+ For our purposes, we do not want any padding on the x-axis. """
8791 if axis == 0 :
8892 return 0.0 # disable padding for x axis
8993 return super ().suggestPadding (axis )
9094
9195 def set_y_range_to_n_sigma (self , n_sigma ):
92- """ Set the y-range to a number of standard deviations of the containing data. """
96+ """ Set the y-range to a number of standard deviations,
97+ assuming the data is taken from a normal distribution. """
9398 # Get the data from all curves in the viewbox
9499 all_data = []
95100 for item in self .allChildren ():
@@ -110,37 +115,52 @@ def set_y_range_to_n_sigma(self, n_sigma):
110115
111116 self .setYRange (y_min , y_max , padding = 0 )
112117
113- def mouseClickEvent (self , ev : QGraphicsSceneMouseEvent ):
118+ def mouseClickEvent (self , ev : mouseEvents . MouseClickEvent ):
114119 if ev .button () == Qt .MouseButton .MiddleButton :
115- self ._zoom_history .append (self .viewRect ())
116- for nsigma in (6 , 4 , 2 ):
117- self .set_y_range_to_n_sigma (nsigma )
118- self ._zoom_history .append (self .viewRect ())
119120 ev .accept ()
121+ self .auto_zoom ()
120122 return
121-
123+
124+ if ev .button () == Qt .MouseButton .RightButton :
125+ ev .accept ()
126+ if ev .modifiers () == Qt .KeyboardModifier .AltModifier :
127+ self .raiseContextMenu (ev )
128+ return
129+
130+ self .undo_zoom (reset = ev .modifiers () == Qt .KeyboardModifier .ShiftModifier )
131+ return
132+
122133 super ().mouseClickEvent (ev )
123134
124135 def mouseDoubleClickEvent (self , ev : QGraphicsSceneMouseEvent ):
125136 if ev .button () == Qt .MouseButton .LeftButton :
126- # Undo zoom history ---
127- if not len (self ._zoom_history ):
128- self .autoRange ()
129- self ._zoom_history .append (self .viewRect ())
130- ev .accept ()
131- return
132-
133- if ev .modifiers () == Qt .KeyboardModifier .ShiftModifier :
134- # go all the way back to the start
135- self .setRange (self ._zoom_history [0 ])
136- self ._zoom_history = []
137- else :
138- # go one step back
139- self .setRange (self ._zoom_history .pop ())
140137 ev .accept ()
141- return
138+ self .undo_zoom (reset = ev .modifiers () == Qt .KeyboardModifier .ShiftModifier )
139+ return
142140
143141 super ().mouseDoubleClickEvent (ev )
144-
145142
143+ def undo_zoom (self , reset : bool = False ):
144+ """ Go back in zoom history. """
145+ if self .axHistoryPointer == 0 :
146+ self .enableAutoRange ()
147+ self .axHistoryPointer = - 1
148+ self .save_view ()
149+ return
150+
151+ if reset :
152+ # Go back to the first zoom
153+ self .scaleHistory (- len (self .axHistory ))
154+ return
155+
156+ # go one step back
157+ self .scaleHistory (- 1 )
158+
159+ def auto_zoom (self ):
160+ for nsigma in (6 , 4 , 2 ):
161+ self .set_y_range_to_n_sigma (nsigma )
162+ self .save_view ()
146163
164+ def save_view (self ):
165+ self .axHistoryPointer += 1
166+ self .axHistory = self .axHistory [:self .axHistoryPointer ] + [self .viewRect ()]
0 commit comments