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.pre_viz_calls
							parent
							
								
									a7f0b36870
								
							
						
					
					
						commit
						d6a47ac9e8
					
				| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
Chart axes graphics and behavior.
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
from __future__ import annotations
 | 
			
		||||
from functools import lru_cache
 | 
			
		||||
from typing import Optional, Callable
 | 
			
		||||
from math import floor
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +28,7 @@ import pyqtgraph as pg
 | 
			
		|||
from PyQt5 import QtCore, QtGui, QtWidgets
 | 
			
		||||
from PyQt5.QtCore import QPointF
 | 
			
		||||
 | 
			
		||||
from . import _pg_overrides as pgo
 | 
			
		||||
from ..data._source import float_digits
 | 
			
		||||
from ._label import Label
 | 
			
		||||
from ._style import DpiAwareFont, hcolor, _font
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +48,7 @@ class Axis(pg.AxisItem):
 | 
			
		|||
    '''
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self,
 | 
			
		||||
        linkedsplits,
 | 
			
		||||
        plotitem: pgo.PlotItem,
 | 
			
		||||
        typical_max_str: str = '100 000.000',
 | 
			
		||||
        text_color: str = 'bracket',
 | 
			
		||||
        lru_cache_tick_strings: bool = True,
 | 
			
		||||
| 
						 | 
				
			
			@ -61,27 +63,32 @@ class Axis(pg.AxisItem):
 | 
			
		|||
        # XXX: pretty sure this makes things slower
 | 
			
		||||
        # self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache)
 | 
			
		||||
 | 
			
		||||
        self.linkedsplits = linkedsplits
 | 
			
		||||
        self.pi = plotitem
 | 
			
		||||
        self._dpi_font = _font
 | 
			
		||||
 | 
			
		||||
        self.setTickFont(_font.font)
 | 
			
		||||
        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',):
 | 
			
		||||
            text_offset = floor(0.25 * font_size)
 | 
			
		||||
 | 
			
		||||
        elif self.orientation in ('left', 'right'):
 | 
			
		||||
            text_offset = floor(font_size / 2)
 | 
			
		||||
 | 
			
		||||
        self.setStyle(**{
 | 
			
		||||
            'textFillLimits': [(0, 0.5)],
 | 
			
		||||
            'tickFont': self._dpi_font.font,
 | 
			
		||||
 | 
			
		||||
        if text_offset:
 | 
			
		||||
            style_conf.update({
 | 
			
		||||
                # offset of text *away from* axis line in px
 | 
			
		||||
                # use approx. half the font pixel size (height)
 | 
			
		||||
                'tickTextOffset': text_offset,
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
        self.setStyle(**style_conf)
 | 
			
		||||
        self.setTickFont(_font.font)
 | 
			
		||||
 | 
			
		||||
        # NOTE: this is for surrounding "border"
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +109,9 @@ class Axis(pg.AxisItem):
 | 
			
		|||
                maxsize=2**20
 | 
			
		||||
            )(self.tickStrings)
 | 
			
		||||
 | 
			
		||||
        # axis "sticky" labels
 | 
			
		||||
        self._stickies: dict[str, YAxisLabel] = {}
 | 
			
		||||
 | 
			
		||||
    # NOTE: only overriden to cast tick values entries into tuples
 | 
			
		||||
    # for use with the lru caching.
 | 
			
		||||
    def tickValues(
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +149,40 @@ class Axis(pg.AxisItem):
 | 
			
		|||
    def txt_offsets(self) -> tuple[int, int]:
 | 
			
		||||
        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):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +299,9 @@ class DynamicDateAxis(Axis):
 | 
			
		|||
 | 
			
		||||
    ) -> list[str]:
 | 
			
		||||
 | 
			
		||||
        chart = self.linkedsplits.chart
 | 
			
		||||
        # XX: ARGGGGG AG:LKSKDJF:LKJSDFD
 | 
			
		||||
        chart = self.pi.chart_widget
 | 
			
		||||
 | 
			
		||||
        flow = chart._flows[chart.name]
 | 
			
		||||
        shm = flow.shm
 | 
			
		||||
        bars = shm.array
 | 
			
		||||
| 
						 | 
				
			
			@ -533,16 +579,15 @@ class YAxisLabel(AxisLabel):
 | 
			
		|||
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self,
 | 
			
		||||
        chart,
 | 
			
		||||
        pi: pgo.PlotItem,
 | 
			
		||||
        *args,
 | 
			
		||||
        **kwargs
 | 
			
		||||
    ) -> None:
 | 
			
		||||
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        self._chart = chart
 | 
			
		||||
 | 
			
		||||
        chart.sigRangeChanged.connect(self.update_on_resize)
 | 
			
		||||
        self._pi = pi
 | 
			
		||||
        pi.sigRangeChanged.connect(self.update_on_resize)
 | 
			
		||||
 | 
			
		||||
        self._last_datum = (None, None)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -612,7 +657,7 @@ class YAxisLabel(AxisLabel):
 | 
			
		|||
            self._last_datum = (index, value)
 | 
			
		||||
 | 
			
		||||
        self.update_label(
 | 
			
		||||
            self._chart.mapFromView(QPointF(index, value)),
 | 
			
		||||
            self._pi.mapFromView(QPointF(index, value)),
 | 
			
		||||
            value
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue