Add initial y-axis zoom

y_zoom
Tyler Goodlet 2020-12-30 12:55:02 -05:00
parent f3a0b1e91e
commit 81b10b9dfc
2 changed files with 66 additions and 36 deletions

View File

@ -384,7 +384,6 @@ class ChartPlotWidget(pg.PlotWidget):
# self.setViewportMargins(0, 0, 0, 0) # self.setViewportMargins(0, 0, 0, 0)
self._ohlc = array # readonly view of ohlc data self._ohlc = array # readonly view of ohlc data
self.default_view()
self._arrays = {} # readonly view of overlays self._arrays = {} # readonly view of overlays
self._graphics = {} # registry of underlying graphics self._graphics = {} # registry of underlying graphics
@ -406,6 +405,8 @@ class ChartPlotWidget(pg.PlotWidget):
# show background grid # show background grid
self.showGrid(x=True, y=True, alpha=0.5) self.showGrid(x=True, y=True, alpha=0.5)
self.default_view()
# TODO: stick in config # TODO: stick in config
# use cross-hair for cursor? # use cross-hair for cursor?
# self.setCursor(QtCore.Qt.CrossCursor) # self.setCursor(QtCore.Qt.CrossCursor)
@ -478,10 +479,13 @@ class ChartPlotWidget(pg.PlotWidget):
""" """
xlast = self._ohlc[index]['index'] xlast = self._ohlc[index]['index']
print(xlast)
begin = xlast - _bars_to_left_in_follow_mode begin = xlast - _bars_to_left_in_follow_mode
end = xlast + _bars_from_right_in_follow_mode end = xlast + _bars_from_right_in_follow_mode
# remove any custom user yrange setttings
if self._static_yrange == 'axis':
self._static_yrange = None
self.plotItem.vb.setXRange( self.plotItem.vb.setXRange(
min=begin, min=begin,
max=end, max=end,
@ -697,7 +701,12 @@ class ChartPlotWidget(pg.PlotWidget):
data set. data set.
""" """
if self._static_yrange is not None: set_range = True
if self._static_yrange == 'axis':
set_range = False
elif self._static_yrange is not None:
ylow, yhigh = self._static_yrange ylow, yhigh = self._static_yrange
elif yrange is not None: elif yrange is not None:
@ -761,11 +770,19 @@ class ChartPlotWidget(pg.PlotWidget):
ylow = np.nanmin(bars) ylow = np.nanmin(bars)
yhigh = np.nanmax(bars) yhigh = np.nanmax(bars)
if set_range:
# view margins: stay within a % of the "true range" # view margins: stay within a % of the "true range"
diff = yhigh - ylow diff = yhigh - ylow
ylow = ylow - (diff * 0.04) ylow = ylow - (diff * 0.04)
yhigh = yhigh + (diff * 0.04) yhigh = yhigh + (diff * 0.04)
self.setLimits(
yMin=ylow,
yMax=yhigh,
)
self.setYRange(ylow, yhigh)
# def _label_h(self, yhigh: float, ylow: float) -> float:
# # compute contents label "height" in view terms # # compute contents label "height" in view terms
# # to avoid having data "contents" overlap with them # # to avoid having data "contents" overlap with them
# if self._labels: # if self._labels:
@ -791,14 +808,8 @@ class ChartPlotWidget(pg.PlotWidget):
# if label_h > yhigh - ylow: # if label_h > yhigh - ylow:
# label_h = 0 # label_h = 0
# print(f"bounds (ylow, yhigh): {(ylow, yhigh)}")
label_h = 0
self.setLimits( # print(f"bounds (ylow, yhigh): {(ylow, yhigh)}")
yMin=ylow,
yMax=yhigh + label_h,
)
self.setYRange(ylow, yhigh + label_h)
def enterEvent(self, ev): # noqa def enterEvent(self, ev): # noqa
# pg.PlotWidget.enterEvent(self, ev) # pg.PlotWidget.enterEvent(self, ev)
@ -1137,7 +1148,7 @@ async def spawn_fsps(
"""Start an fsp subactor async. """Start an fsp subactor async.
""" """
print(f'FSP NAME: {fsp_name}') # print(f'FSP NAME: {fsp_name}')
portal = await n.run_in_actor( portal = await n.run_in_actor(
# subactor entrypoint # subactor entrypoint

View File

@ -17,6 +17,8 @@
""" """
UX interaction customs. UX interaction customs.
""" """
from typing import Optional
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph import ViewBox, Point, QtCore, QtGui from pyqtgraph import ViewBox, Point, QtCore, QtGui
from pyqtgraph import functions as fn from pyqtgraph import functions as fn
@ -144,7 +146,7 @@ class SelectRect(QtGui.QGraphicsRectItem):
x1, x2 = start_pos.x(), end_pos.x() x1, x2 = start_pos.x(), end_pos.x()
# TODO: heh, could probably use a max-min streamin algo here too # TODO: heh, could probably use a max-min streamin algo here too
ymn, xmn = min(y1, y2), min(x1, x2) _, xmn = min(y1, y2), min(x1, x2)
ymx, xmx = max(y1, y2), max(x1, x2) ymx, xmx = max(y1, y2), max(x1, x2)
pchng = (y2 - y1) / y1 * 100 pchng = (y2 - y1) / y1 * 100
@ -277,7 +279,11 @@ class ChartView(ViewBox):
ev.accept() ev.accept()
self.sigRangeChangedManually.emit(mask) self.sigRangeChangedManually.emit(mask)
def mouseDragEvent(self, ev, axis=None): def mouseDragEvent(
self,
ev,
axis: Optional[int] = None,
) -> None:
# if axis is specified, event will only affect that axis. # if axis is specified, event will only affect that axis.
ev.accept() # we accept all buttons ev.accept() # we accept all buttons
@ -295,6 +301,18 @@ class ChartView(ViewBox):
# Scale or translate based on mouse button # Scale or translate based on mouse button
if ev.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MidButton): if ev.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MidButton):
# zoom only y-axis when click-n-drag on it
if axis == 1:
# set a static y range special value on chart widget to
# prevent sizing to data in view.
self._chart._static_yrange = 'axis'
scale_y = 1.3 ** (dif.y() * -1 / 20)
self.setLimits(yMin=None, yMax=None)
# print(scale_y)
self.scaleBy((0, scale_y))
if self.state['mouseMode'] == ViewBox.RectMode: if self.state['mouseMode'] == ViewBox.RectMode:
down_pos = ev.buttonDownPos() down_pos = ev.buttonDownPos()
@ -333,6 +351,7 @@ class ChartView(ViewBox):
self.sigRangeChangedManually.emit(self.state['mouseEnabled']) self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
elif ev.button() & QtCore.Qt.RightButton: elif ev.button() & QtCore.Qt.RightButton:
# print "vb.rightDrag" # print "vb.rightDrag"
if self.state['aspectLocked'] is not False: if self.state['aspectLocked'] is not False:
mask[0] = 0 mask[0] = 0