Only move x-axis sticky when we mouse-over a new index

Avoid drawing a new new sticky position if the mouse hasn't moved to the
next (rounded) index in terms of the scene's coordinates. This completes
the "discrete-ization" of the mouse/cursor UX.

Finalizing this feature helped discover and solve
pyqtgraph/pyqtgraph#1418 which masssively improves interaction
performance throughout the whole lib!

Hide stickys on startup until cursor shows up on plot.
bar_select
Tyler Goodlet 2020-10-24 20:18:21 -04:00
parent ece57b2a1d
commit f32763d992
1 changed files with 25 additions and 10 deletions

View File

@ -7,14 +7,14 @@ from typing import List
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QLineF from PyQt5.QtCore import QLineF, QPointF
# from .quantdom.utils import timeit # from .quantdom.utils import timeit
from ._style import _xaxis_at, hcolor, _font from ._style import _xaxis_at, hcolor, _font
from ._axes import YAxisLabel, XAxisLabel from ._axes import YAxisLabel, XAxisLabel
_mouse_rate_limit = 40 # calc current screen refresh rate? _mouse_rate_limit = 60 # calc current screen refresh rate?
_debounce_delay = 1/2e3 _debounce_delay = 1/2e3
_ch_label_opac = 1 _ch_label_opac = 1
@ -89,13 +89,17 @@ class CrossHair(pg.GraphicsObject):
# add ``pg.graphicsItems.InfiniteLine``s # add ``pg.graphicsItems.InfiniteLine``s
# vertical and horizonal lines and a y-axis label # vertical and horizonal lines and a y-axis label
vl = plot.addLine(x=0, pen=self.lines_pen, movable=False) vl = plot.addLine(x=0, pen=self.lines_pen, movable=False)
hl = plot.addLine(y=0, pen=self.lines_pen, movable=False) hl = plot.addLine(y=0, pen=self.lines_pen, movable=False)
hl.hide()
yl = YAxisLabel( yl = YAxisLabel(
parent=plot.getAxis('right'), parent=plot.getAxis('right'),
digits=digits or self.digits, digits=digits or self.digits,
opacity=_ch_label_opac, opacity=_ch_label_opac,
color=self.pen, bg_color='default',
) )
yl.hide() # on startup if mouse is off screen
# TODO: checkout what ``.sigDelayed`` can be used for # TODO: checkout what ``.sigDelayed`` can be used for
# (emitted once a sufficient delay occurs in mouse movement) # (emitted once a sufficient delay occurs in mouse movement)
@ -133,8 +137,10 @@ class CrossHair(pg.GraphicsObject):
self.xaxis_label = XAxisLabel( self.xaxis_label = XAxisLabel(
parent=self.plots[plot_index].getAxis('bottom'), parent=self.plots[plot_index].getAxis('bottom'),
opacity=_ch_label_opac, opacity=_ch_label_opac,
color=self.pen, bg_color='default',
) )
# place label off-screen during startup
self.xaxis_label.setPos(self.plots[0].mapFromView(QPointF(0, 0)))
def add_curve_cursor( def add_curve_cursor(
self, self,
@ -197,22 +203,31 @@ class CrossHair(pg.GraphicsObject):
if ix != lastx: if ix != lastx:
for plot, opts in self.graphics.items(): for plot, opts in self.graphics.items():
# move the vertical line to the current "center of bar" # move the vertical line to the current "center of bar"
opts['vl'].setX(ix) opts['vl'].setX(ix)
# update the chart's "contents" label # update the chart's "contents" label
plot._update_contents_label(ix) plot._update_contents_label(ix)
# update the label on the bottom of the crosshair
self.xaxis_label.update_label(
abs_pos=pos,
data=x
)
# update all subscribed curve dots # update all subscribed curve dots
for cursor in opts.get('cursors', ()): for cursor in opts.get('cursors', ()):
cursor.setIndex(ix) cursor.setIndex(ix)
# update the label on the bottom of the crosshair
self.xaxis_label.update_label(
# XXX: requires:
# https://github.com/pyqtgraph/pyqtgraph/pull/1418
# otherwise gobbles tons of CPU..
# map back to abs (label-local) coordinates
abs_pos=plot.mapFromView(QPointF(ix, y)),
data=x,
)
self._lastx = ix
def boundingRect(self): def boundingRect(self):
try: try:
return self.active_plot.boundingRect() return self.active_plot.boundingRect()
@ -300,7 +315,7 @@ class BarItems(pg.GraphicsObject):
# 0.5 is no overlap between arms, 1.0 is full overlap # 0.5 is no overlap between arms, 1.0 is full overlap
w: float = 0.43 w: float = 0.43
bars_pen = pg.mkPen(hcolor('pikers')) bars_pen = pg.mkPen(hcolor('bracket'))
# XXX: tina mode, see below # XXX: tina mode, see below
# bull_brush = pg.mkPen('#00cc00') # bull_brush = pg.mkPen('#00cc00')