Add `Axis.add_sticky()` for creating axis labels
We have this method on our `ChartPlotWidget` but it makes more sense to directly associate axis-labels with, well, the label's parent axis XD. We add `._stickies: dict[str, YAxisLabel]` to replace `ChartPlotWidget._ysticks` and pass in the `pg.PlotItem` to each axis instance, stored as `Axis.pi` instead of handing around linked split references (which are way out of scope for a single axis). More work needs to be done to remove dependence on `.chart: ChartPlotWidget` references in the date axis type as per comments.axis_sticky_api
parent
34fac364fd
commit
31af7a2c99
|
@ -18,6 +18,7 @@
|
||||||
Chart axes graphics and behavior.
|
Chart axes graphics and behavior.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
from math import floor
|
from math import floor
|
||||||
|
@ -27,6 +28,7 @@ import pyqtgraph as pg
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtCore import QPointF
|
from PyQt5.QtCore import QPointF
|
||||||
|
|
||||||
|
from . import _pg_overrides as pgo
|
||||||
from ..data._source import float_digits
|
from ..data._source import float_digits
|
||||||
from ._label import Label
|
from ._label import Label
|
||||||
from ._style import DpiAwareFont, hcolor, _font
|
from ._style import DpiAwareFont, hcolor, _font
|
||||||
|
@ -46,7 +48,7 @@ class Axis(pg.AxisItem):
|
||||||
'''
|
'''
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
linkedsplits,
|
plotitem: pgo.PlotItem,
|
||||||
typical_max_str: str = '100 000.000',
|
typical_max_str: str = '100 000.000',
|
||||||
text_color: str = 'bracket',
|
text_color: str = 'bracket',
|
||||||
lru_cache_tick_strings: bool = True,
|
lru_cache_tick_strings: bool = True,
|
||||||
|
@ -61,27 +63,32 @@ class Axis(pg.AxisItem):
|
||||||
# XXX: pretty sure this makes things slower
|
# XXX: pretty sure this makes things slower
|
||||||
# self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache)
|
# self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache)
|
||||||
|
|
||||||
self.linkedsplits = linkedsplits
|
self.pi = plotitem
|
||||||
self._dpi_font = _font
|
self._dpi_font = _font
|
||||||
|
|
||||||
self.setTickFont(_font.font)
|
self.setTickFont(_font.font)
|
||||||
font_size = self._dpi_font.font.pixelSize()
|
font_size = self._dpi_font.font.pixelSize()
|
||||||
|
|
||||||
|
style_conf = {
|
||||||
|
'textFillLimits': [(0, 0.5)],
|
||||||
|
'tickFont': self._dpi_font.font,
|
||||||
|
|
||||||
|
}
|
||||||
|
text_offset = None
|
||||||
if self.orientation in ('bottom',):
|
if self.orientation in ('bottom',):
|
||||||
text_offset = floor(0.25 * font_size)
|
text_offset = floor(0.25 * font_size)
|
||||||
|
|
||||||
elif self.orientation in ('left', 'right'):
|
elif self.orientation in ('left', 'right'):
|
||||||
text_offset = floor(font_size / 2)
|
text_offset = floor(font_size / 2)
|
||||||
|
|
||||||
self.setStyle(**{
|
if text_offset:
|
||||||
'textFillLimits': [(0, 0.5)],
|
style_conf.update({
|
||||||
'tickFont': self._dpi_font.font,
|
# offset of text *away from* axis line in px
|
||||||
|
# use approx. half the font pixel size (height)
|
||||||
# offset of text *away from* axis line in px
|
'tickTextOffset': text_offset,
|
||||||
# use approx. half the font pixel size (height)
|
})
|
||||||
'tickTextOffset': text_offset,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
self.setStyle(**style_conf)
|
||||||
self.setTickFont(_font.font)
|
self.setTickFont(_font.font)
|
||||||
|
|
||||||
# NOTE: this is for surrounding "border"
|
# NOTE: this is for surrounding "border"
|
||||||
|
@ -102,6 +109,9 @@ class Axis(pg.AxisItem):
|
||||||
maxsize=2**20
|
maxsize=2**20
|
||||||
)(self.tickStrings)
|
)(self.tickStrings)
|
||||||
|
|
||||||
|
# axis "sticky" labels
|
||||||
|
self._stickies: dict[str, YAxisLabel] = {}
|
||||||
|
|
||||||
# NOTE: only overriden to cast tick values entries into tuples
|
# NOTE: only overriden to cast tick values entries into tuples
|
||||||
# for use with the lru caching.
|
# for use with the lru caching.
|
||||||
def tickValues(
|
def tickValues(
|
||||||
|
@ -139,6 +149,40 @@ class Axis(pg.AxisItem):
|
||||||
def txt_offsets(self) -> tuple[int, int]:
|
def txt_offsets(self) -> tuple[int, int]:
|
||||||
return tuple(self.style['tickTextOffset'])
|
return tuple(self.style['tickTextOffset'])
|
||||||
|
|
||||||
|
def add_sticky(
|
||||||
|
self,
|
||||||
|
pi: pgo.PlotItem,
|
||||||
|
name: None | str = None,
|
||||||
|
digits: None | int = 2,
|
||||||
|
# axis_name: str = 'right',
|
||||||
|
bg_color='bracket',
|
||||||
|
|
||||||
|
) -> YAxisLabel:
|
||||||
|
|
||||||
|
# if the sticky is for our symbol
|
||||||
|
# use the tick size precision for display
|
||||||
|
name = name or pi.name
|
||||||
|
digits = digits or 2
|
||||||
|
|
||||||
|
# TODO: ``._ysticks`` should really be an attr on each
|
||||||
|
# ``PlotItem`` no instead of the (containing because of
|
||||||
|
# overlays) widget?
|
||||||
|
|
||||||
|
# add y-axis "last" value label
|
||||||
|
sticky = self._stickies[name] = YAxisLabel(
|
||||||
|
pi=pi,
|
||||||
|
parent=self,
|
||||||
|
# TODO: pass this from symbol data
|
||||||
|
digits=digits,
|
||||||
|
opacity=1,
|
||||||
|
bg_color=bg_color,
|
||||||
|
)
|
||||||
|
|
||||||
|
pi.sigRangeChanged.connect(sticky.update_on_resize)
|
||||||
|
# pi.addItem(sticky)
|
||||||
|
# pi.addItem(last)
|
||||||
|
return sticky
|
||||||
|
|
||||||
|
|
||||||
class PriceAxis(Axis):
|
class PriceAxis(Axis):
|
||||||
|
|
||||||
|
@ -255,7 +299,9 @@ class DynamicDateAxis(Axis):
|
||||||
|
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
|
|
||||||
chart = self.linkedsplits.chart
|
# XX: ARGGGGG AG:LKSKDJF:LKJSDFD
|
||||||
|
chart = self.pi.chart_widget
|
||||||
|
|
||||||
flow = chart._flows[chart.name]
|
flow = chart._flows[chart.name]
|
||||||
shm = flow.shm
|
shm = flow.shm
|
||||||
bars = shm.array
|
bars = shm.array
|
||||||
|
@ -533,16 +579,15 @@ class YAxisLabel(AxisLabel):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
chart,
|
pi: pgo.PlotItem,
|
||||||
*args,
|
*args,
|
||||||
**kwargs
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self._chart = chart
|
self._pi = pi
|
||||||
|
pi.sigRangeChanged.connect(self.update_on_resize)
|
||||||
chart.sigRangeChanged.connect(self.update_on_resize)
|
|
||||||
|
|
||||||
self._last_datum = (None, None)
|
self._last_datum = (None, None)
|
||||||
|
|
||||||
|
@ -612,7 +657,7 @@ class YAxisLabel(AxisLabel):
|
||||||
self._last_datum = (index, value)
|
self._last_datum = (index, value)
|
||||||
|
|
||||||
self.update_label(
|
self.update_label(
|
||||||
self._chart.mapFromView(QPointF(index, value)),
|
self._pi.mapFromView(QPointF(index, value)),
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue