Drop Qt interaction signal usage

It's kind of hard to understand with the C++ fan-out to multiple views
(imo a cluster-f#$*&) and seems honestly just plain faster to loop (in
python) through all the linked view handlers XD

Core adjustments:
- make the panning and wheel-scroll handlers just call
  `.maybe_downsample_graphics()` directly; drop all signal emissions.
- make `.maybe_downsample_graphics()` loop through all vizs per subchart
  and use the new pipeline-style call sequence of:
  - `Viz.update_graphics() -> <read_slc>: tuple`
  - `Viz.maxmin(i_read_range=<read_slc>) -> yrange: tuple`
  - `Viz.plot.vb._set_yrange(yrange=yrange)`
  which inlines all the necessary calls in the most efficient way whilst
  leveraging `.maxmin()` caching and ymxmn-from-m4-during-render to
  boot.
- drop registering `._set_yrange()` for handling `.sigRangeChangedManually`.
multichartz_backup
Tyler Goodlet 2023-01-18 15:07:15 -05:00
parent 6d119d56d2
commit 909ecd80a1
1 changed files with 59 additions and 39 deletions

View File

@ -395,6 +395,10 @@ class ChartView(ViewBox):
self._ic = None self._ic = None
self._yranger: Callable | None = None self._yranger: Callable | None = None
# TODO: probably just assign this whenever a new `PlotItem` is
# allocated since they're 1to1 with views..
self._viz: Viz | None = None
def start_ic( def start_ic(
self, self,
) -> None: ) -> None:
@ -533,6 +537,7 @@ class ChartView(ViewBox):
# scale_y = 1.3 ** (center.y() * -1 / 20) # scale_y = 1.3 ** (center.y() * -1 / 20)
self.scaleBy(s, center) self.scaleBy(s, center)
# zoom in view-box area
else: else:
# use right-most point of current curve graphic # use right-most point of current curve graphic
xl = viz.graphics.x_last() xl = viz.graphics.x_last()
@ -552,7 +557,7 @@ class ChartView(ViewBox):
# update, but i gotta feelin that because this one is signal # update, but i gotta feelin that because this one is signal
# based (and thus not necessarily sync invoked right away) # based (and thus not necessarily sync invoked right away)
# that calling the resize method manually might work better. # that calling the resize method manually might work better.
self.sigRangeChangedManually.emit(mask) # self.sigRangeChangedManually.emit(mask)
# XXX: without this is seems as though sometimes # XXX: without this is seems as though sometimes
# when zooming in from far out (and maybe vice versa?) # when zooming in from far out (and maybe vice versa?)
@ -581,7 +586,10 @@ class ChartView(ViewBox):
button = ev.button() button = ev.button()
# Ignore axes if mouse is disabled # Ignore axes if mouse is disabled
mouseEnabled = np.array(self.state['mouseEnabled'], dtype=np.float) mouseEnabled = np.array(
self.state['mouseEnabled'],
dtype=np.float,
)
mask = mouseEnabled.copy() mask = mouseEnabled.copy()
if axis is not None: if axis is not None:
mask[1-axis] = 0.0 mask[1-axis] = 0.0
@ -664,7 +672,10 @@ class ChartView(ViewBox):
if x is not None or y is not None: if x is not None or y is not None:
self.translateBy(x=x, y=y) self.translateBy(x=x, y=y)
self.sigRangeChangedManually.emit(self.state['mouseEnabled']) # self.sigRangeChangedManually.emit(mask)
# self.state['mouseEnabled']
# )
self.maybe_downsample_graphics()
if ev.isFinish(): if ev.isFinish():
self.signal_ic() self.signal_ic()
@ -672,8 +683,8 @@ class ChartView(ViewBox):
# self._ic = None # self._ic = None
# self.chart.resume_all_feeds() # self.chart.resume_all_feeds()
# XXX: WHY # # XXX: WHY
ev.accept() # ev.accept()
# WEIRD "RIGHT-CLICK CENTER ZOOM" MODE # WEIRD "RIGHT-CLICK CENTER ZOOM" MODE
elif button & QtCore.Qt.RightButton: elif button & QtCore.Qt.RightButton:
@ -695,10 +706,12 @@ class ChartView(ViewBox):
center = Point(tr.map(ev.buttonDownPos(QtCore.Qt.RightButton))) center = Point(tr.map(ev.buttonDownPos(QtCore.Qt.RightButton)))
self._resetTarget() self._resetTarget()
self.scaleBy(x=x, y=y, center=center) self.scaleBy(x=x, y=y, center=center)
self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
# XXX: WHY # self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
ev.accept() self.maybe_downsample_graphics()
# XXX: WHY
ev.accept()
# def mouseClickEvent(self, event: QtCore.QEvent) -> None: # def mouseClickEvent(self, event: QtCore.QEvent) -> None:
# '''This routine is rerouted to an async handler. # '''This routine is rerouted to an async handler.
@ -837,12 +850,6 @@ class ChartView(ViewBox):
viz=viz, viz=viz,
) )
# widget-UIs/splitter(s) resizing
src_vb.sigResized.connect(self._yranger)
# mouse wheel doesn't emit XRangeChanged
src_vb.sigRangeChangedManually.connect(self._yranger)
# re-sampling trigger: # re-sampling trigger:
# TODO: a smarter way to avoid calling this needlessly? # TODO: a smarter way to avoid calling this needlessly?
# 2 things i can think of: # 2 things i can think of:
@ -850,25 +857,34 @@ class ChartView(ViewBox):
# iterate those. # iterate those.
# - only register this when certain downsample-able graphics are # - only register this when certain downsample-able graphics are
# "added to scene". # "added to scene".
src_vb.sigRangeChangedManually.connect( # src_vb.sigRangeChangedManually.connect(
# self.maybe_downsample_graphics
# )
# widget-UIs/splitter(s) resizing
src_vb.sigResized.connect(
self.maybe_downsample_graphics self.maybe_downsample_graphics
) )
# mouse wheel doesn't emit XRangeChanged
# src_vb.sigRangeChangedManually.connect(self._yranger)
def disable_auto_yrange(self) -> None: def disable_auto_yrange(self) -> None:
# XXX: not entirely sure why we can't de-reg this.. # XXX: not entirely sure why we can't de-reg this..
self.sigResized.disconnect( self.sigResized.disconnect(
self._yranger, # self._yranger,
)
self.sigRangeChangedManually.disconnect(
self._yranger,
)
self.sigRangeChangedManually.disconnect(
self.maybe_downsample_graphics self.maybe_downsample_graphics
) )
# self.sigRangeChangedManually.disconnect(
# self._yranger,
# )
# self.sigRangeChangedManually.disconnect(
# self.maybe_downsample_graphics
# )
def x_uppx(self) -> float: def x_uppx(self) -> float:
''' '''
Return the "number of x units" within a single Return the "number of x units" within a single
@ -889,7 +905,6 @@ class ChartView(ViewBox):
def maybe_downsample_graphics( def maybe_downsample_graphics(
self, self,
autoscale_overlays: bool = False,
): ):
profiler = Profiler( profiler = Profiler(
msg=f'ChartView.maybe_downsample_graphics() for {self.name}', msg=f'ChartView.maybe_downsample_graphics() for {self.name}',
@ -912,10 +927,10 @@ class ChartView(ViewBox):
plots |= linked.subplots plots |= linked.subplots
for chart_name, chart in plots.items(): for chart_name, chart in plots.items():
for name, flow in chart._vizs.items(): for name, viz in chart._vizs.items():
if ( if (
not flow.render not viz.render
# XXX: super important to be aware of this. # XXX: super important to be aware of this.
# or not flow.graphics.isVisible() # or not flow.graphics.isVisible()
@ -925,19 +940,24 @@ class ChartView(ViewBox):
# pass in no array which will read and render from the last # pass in no array which will read and render from the last
# passed array (normally provided by the display loop.) # passed array (normally provided by the display loop.)
chart.update_graphics_from_flow(name) i_read_range, _ = viz.update_graphics()
out = viz.maxmin(i_read_range=i_read_range)
if out is None:
log.warning(f'No yrange provided for {name}!?')
return
(
ixrng,
_,
yrange
) = out
# for each overlay on this chart auto-scale the # print(
# y-range to max-min values. # f'i_read_range: {i_read_range}\n'
# if autoscale_overlays: # f'ixrng: {ixrng}\n'
# overlay = chart.pi_overlay # f'yrange: {yrange}\n'
# if overlay: # )
# for pi in overlay.overlays: viz.plot.vb._set_yrange(yrange=yrange)
# pi.vb._set_yrange(
# # TODO: get the range once up front... profiler(f'autoscaled overlays {chart_name}')
# # bars_range=br,
# viz=pi.viz,
# )
# profiler('autoscaled linked plots')
profiler(f'<{chart_name}>.update_graphics_from_flow({name})') profiler(f'<{chart_name}>.update_graphics_from_flow({name})')