Add custom `.formatter` support to our `PriceAxis`
Allow passing in a formatter function for processing tick values on an axis. This makes it easy to for example, `piker.calc.humanize()` dollar volume on a subchart. Factor `set_min_tick()` into the `PriceAxis` since it's not used on any x-axis data thus far.vlm_plotz
parent
cec08f20ba
commit
9321eab471
|
@ -19,7 +19,7 @@ Chart axes graphics and behavior.
|
|||
|
||||
"""
|
||||
from functools import partial
|
||||
from typing import List, Tuple, Optional
|
||||
from typing import List, Tuple, Optional, Callable
|
||||
from math import floor
|
||||
|
||||
import pandas as pd
|
||||
|
@ -29,7 +29,6 @@ from PyQt5.QtCore import QPointF
|
|||
|
||||
from ._style import DpiAwareFont, hcolor, _font
|
||||
from ..data._source import float_digits
|
||||
from ..calc import humanize
|
||||
|
||||
_axis_pen = pg.mkPen(hcolor('bracket'))
|
||||
|
||||
|
@ -43,7 +42,6 @@ class Axis(pg.AxisItem):
|
|||
self,
|
||||
linkedsplits,
|
||||
typical_max_str: str = '100 000.000',
|
||||
min_tick: int = 2,
|
||||
**kwargs
|
||||
|
||||
) -> None:
|
||||
|
@ -53,7 +51,6 @@ class Axis(pg.AxisItem):
|
|||
# self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache)
|
||||
|
||||
self.linkedsplits = linkedsplits
|
||||
self._min_tick = min_tick
|
||||
self._dpi_font = _font
|
||||
|
||||
self.setTickFont(_font.font)
|
||||
|
@ -84,9 +81,6 @@ class Axis(pg.AxisItem):
|
|||
def size_to_values(self) -> None:
|
||||
pass
|
||||
|
||||
def set_min_tick(self, size: int) -> None:
|
||||
self._min_tick = size
|
||||
|
||||
def txt_offsets(self) -> Tuple[int, int]:
|
||||
return tuple(self.style['tickTextOffset'])
|
||||
|
||||
|
@ -96,26 +90,34 @@ class PriceAxis(Axis):
|
|||
def __init__(
|
||||
self,
|
||||
*args,
|
||||
humanize: bool = True,
|
||||
digits: int = 2,
|
||||
min_tick: int = 2,
|
||||
formatter: Optional[Callable[[float], str]] = None,
|
||||
**kwargs
|
||||
|
||||
) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.humanize = humanize
|
||||
self.digits = digits
|
||||
self.formatter = formatter
|
||||
self._min_tick: int = min_tick
|
||||
|
||||
def set_min_tick(
|
||||
self,
|
||||
size: int
|
||||
) -> None:
|
||||
self._min_tick = size
|
||||
|
||||
def size_to_values(self) -> None:
|
||||
# self.typical_br = _font._qfm.boundingRect(typical_max_str)
|
||||
self.setWidth(self.typical_br.width())
|
||||
|
||||
# XXX: drop for now since it just eats up h space
|
||||
|
||||
def tickStrings(
|
||||
self,
|
||||
vals,
|
||||
scale,
|
||||
spacing,
|
||||
):
|
||||
vals: tuple[float],
|
||||
scale: float,
|
||||
spacing: float,
|
||||
|
||||
) -> list[str]:
|
||||
# TODO: figure out how to enforce min tick spacing by passing it
|
||||
# into the parent type
|
||||
digits = max(
|
||||
|
@ -126,7 +128,7 @@ class PriceAxis(Axis):
|
|||
# print(f'vals: {vals}\nscale: {scale}\nspacing: {spacing}')
|
||||
# print(f'digits: {digits}')
|
||||
|
||||
if not self.humanize:
|
||||
if not self.formatter:
|
||||
return [
|
||||
('{value:,.{digits}f}').format(
|
||||
digits=digits,
|
||||
|
@ -134,7 +136,7 @@ class PriceAxis(Axis):
|
|||
).replace(',', ' ') for v in vals
|
||||
]
|
||||
else:
|
||||
return list(map(partial(humanize, digits=self.digits), vals))
|
||||
return list(map(self.formatter, vals))
|
||||
|
||||
|
||||
class DynamicDateAxis(Axis):
|
||||
|
@ -154,6 +156,7 @@ class DynamicDateAxis(Axis):
|
|||
def _indexes_to_timestrs(
|
||||
self,
|
||||
indexes: List[int],
|
||||
|
||||
) -> List[str]:
|
||||
|
||||
chart = self.linkedsplits.chart
|
||||
|
@ -183,9 +186,10 @@ class DynamicDateAxis(Axis):
|
|||
def tickStrings(
|
||||
self,
|
||||
values: tuple[float],
|
||||
scale,
|
||||
spacing,
|
||||
):
|
||||
scale: float,
|
||||
spacing: float,
|
||||
|
||||
) -> list[str]:
|
||||
# info = self.tickStrings.cache_info()
|
||||
# print(info)
|
||||
return self._indexes_to_timestrs(values)
|
||||
|
|
Loading…
Reference in New Issue