Size axis labels based on text contents
Compute the size in pixels the label based on the label's contents. Eventually we want to have an update system that can iterate through axes and labels to do this whenever needed (eg. after widget is moved to a new screen with a different DPI).bar_select
parent
55f34dfed0
commit
89d48afb6c
|
@ -11,6 +11,8 @@ from PyQt5.QtCore import QPointF
|
||||||
from ._style import _font, hcolor
|
from ._style import _font, hcolor
|
||||||
from ..data._source import float_digits
|
from ..data._source import float_digits
|
||||||
|
|
||||||
|
_axis_pen = pg.mkPen(hcolor('bracket'))
|
||||||
|
|
||||||
|
|
||||||
class PriceAxis(pg.AxisItem):
|
class PriceAxis(pg.AxisItem):
|
||||||
|
|
||||||
|
@ -21,15 +23,18 @@ class PriceAxis(pg.AxisItem):
|
||||||
self.setTickFont(_font)
|
self.setTickFont(_font)
|
||||||
self.setStyle(**{
|
self.setStyle(**{
|
||||||
'textFillLimits': [(0, 0.666)],
|
'textFillLimits': [(0, 0.666)],
|
||||||
|
'tickFont': _font,
|
||||||
# 'tickTextWidth': 100,
|
# 'tickTextWidth': 100,
|
||||||
# 'tickTextHeight': 20,
|
# 'tickTextHeight': 20,
|
||||||
'tickFont': _font,
|
|
||||||
# 'tickTextWidth': 40,
|
# 'tickTextWidth': 40,
|
||||||
# 'autoExpandTextSpace': True,
|
# 'autoExpandTextSpace': True,
|
||||||
# 'maxTickLength': -20,
|
# 'maxTickLength': -20,
|
||||||
# 'stopAxisAtTick': (True, True), # doesn't work well on price
|
# 'stopAxisAtTick': (True, True), # doesn't work well on price
|
||||||
})
|
})
|
||||||
# self.setLabel(**{'font-size': '10pt'})
|
# self.setLabel(**{'font-size': '10pt'})
|
||||||
|
self.setTickFont(_font)
|
||||||
|
self.setPen(_axis_pen)
|
||||||
|
|
||||||
self.setWidth(40)
|
self.setWidth(40)
|
||||||
|
|
||||||
# XXX: drop for now since it just eats up h space
|
# XXX: drop for now since it just eats up h space
|
||||||
|
@ -63,11 +68,12 @@ class DynamicDateAxis(pg.AxisItem):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.linked_charts = linked_charts
|
self.linked_charts = linked_charts
|
||||||
self.setTickFont(_font)
|
self.setTickFont(_font)
|
||||||
|
self.setPen(_axis_pen)
|
||||||
|
|
||||||
# default styling
|
# default styling
|
||||||
self.setStyle(**{
|
self.setStyle(**{
|
||||||
# tickTextOffset=4,
|
# tickTextOffset=4,
|
||||||
'textFillLimits': [(0, 0.70)],
|
'textFillLimits': [(0, 0.666)],
|
||||||
'tickFont': _font,
|
'tickFont': _font,
|
||||||
})
|
})
|
||||||
self.setHeight(11)
|
self.setHeight(11)
|
||||||
|
@ -95,6 +101,10 @@ class DynamicDateAxis(pg.AxisItem):
|
||||||
|
|
||||||
class AxisLabel(pg.GraphicsObject):
|
class AxisLabel(pg.GraphicsObject):
|
||||||
|
|
||||||
|
_font = _font
|
||||||
|
_w_margin = 0
|
||||||
|
_h_margin = 3
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
parent: pg.GraphicsObject,
|
parent: pg.GraphicsObject,
|
||||||
|
@ -108,6 +118,7 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
self.opacity = opacity
|
self.opacity = opacity
|
||||||
self.label_str = ''
|
self.label_str = ''
|
||||||
self.digits = digits
|
self.digits = digits
|
||||||
|
self._txt_br: QtCore.QRect = None
|
||||||
|
|
||||||
self.bg_color = pg.mkColor(hcolor(bg_color))
|
self.bg_color = pg.mkColor(hcolor(bg_color))
|
||||||
self.fg_color = pg.mkColor(hcolor(fg_color))
|
self.fg_color = pg.mkColor(hcolor(fg_color))
|
||||||
|
@ -115,34 +126,52 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
self.pic = QtGui.QPicture()
|
self.pic = QtGui.QPicture()
|
||||||
p = QtGui.QPainter(self.pic)
|
p = QtGui.QPainter(self.pic)
|
||||||
|
|
||||||
self.rect = QtCore.QRectF(0, 0, 40, 11)
|
self.rect = None
|
||||||
|
|
||||||
p.setPen(self.fg_color)
|
p.setPen(self.fg_color)
|
||||||
p.setOpacity(self.opacity)
|
p.setOpacity(self.opacity)
|
||||||
p.fillRect(self.rect, self.bg_color)
|
|
||||||
|
|
||||||
# this adds a nice black outline around the label for some odd
|
|
||||||
# reason; ok by us
|
|
||||||
p.drawRect(self.rect)
|
|
||||||
|
|
||||||
self.setFlag(self.ItemIgnoresTransformations)
|
self.setFlag(self.ItemIgnoresTransformations)
|
||||||
|
|
||||||
|
def _size_br_from_str(self, value: str) -> None:
|
||||||
|
"""Do our best to render the bounding rect to a set margin
|
||||||
|
around provided string contents.
|
||||||
|
|
||||||
|
"""
|
||||||
|
txt_br = self._font._fm.boundingRect(value)
|
||||||
|
h, w = txt_br.height(), txt_br.width()
|
||||||
|
self.rect = QtCore.QRectF(
|
||||||
|
0, 0,
|
||||||
|
w + self._w_margin,
|
||||||
|
h + self._h_margin
|
||||||
|
)
|
||||||
|
|
||||||
def paint(self, p, option, widget):
|
def paint(self, p, option, widget):
|
||||||
p.drawPicture(0, 0, self.pic)
|
p.drawPicture(0, 0, self.pic)
|
||||||
|
|
||||||
if self.label_str:
|
if self.label_str:
|
||||||
|
|
||||||
|
if not self.rect:
|
||||||
|
self._size_br_from_str(self.label_str)
|
||||||
|
|
||||||
p.setFont(_font)
|
p.setFont(_font)
|
||||||
p.setPen(self.fg_color)
|
p.setPen(self.fg_color)
|
||||||
p.drawText(self.rect, self.text_flags, self.label_str)
|
p.fillRect(self.rect, self.bg_color)
|
||||||
|
|
||||||
|
# this adds a nice black outline around the label for some odd
|
||||||
|
# reason; ok by us
|
||||||
|
p.drawRect(self.rect)
|
||||||
|
|
||||||
|
p.drawText(option.rect, self.text_flags, self.label_str)
|
||||||
|
|
||||||
|
def boundingRect(self): # noqa
|
||||||
|
return self.rect or QtCore.QRectF()
|
||||||
|
|
||||||
# uggggghhhh
|
# uggggghhhh
|
||||||
|
|
||||||
def tick_to_string(self, tick_pos):
|
def tick_to_string(self, tick_pos):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def boundingRect(self): # noqa
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def update_label(self, evt_post, point_view):
|
def update_label(self, evt_post, point_view):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -160,6 +189,8 @@ class AxisLabel(pg.GraphicsObject):
|
||||||
|
|
||||||
class XAxisLabel(AxisLabel):
|
class XAxisLabel(AxisLabel):
|
||||||
|
|
||||||
|
_w_margin = 8
|
||||||
|
|
||||||
text_flags = (
|
text_flags = (
|
||||||
QtCore.Qt.TextDontClip
|
QtCore.Qt.TextDontClip
|
||||||
| QtCore.Qt.AlignCenter
|
| QtCore.Qt.AlignCenter
|
||||||
|
@ -168,12 +199,6 @@ class XAxisLabel(AxisLabel):
|
||||||
# | QtCore.Qt.AlignHCenter
|
# | QtCore.Qt.AlignHCenter
|
||||||
)
|
)
|
||||||
|
|
||||||
def boundingRect(self): # noqa
|
|
||||||
# TODO: we need to get the parent axe's dimensions transformed
|
|
||||||
# to abs coords to be 100% correct here:
|
|
||||||
# self.parent.boundingRect()
|
|
||||||
return QtCore.QRectF(0, 0, 40, 11)
|
|
||||||
|
|
||||||
def update_label(
|
def update_label(
|
||||||
self,
|
self,
|
||||||
abs_pos: QPointF, # scene coords
|
abs_pos: QPointF, # scene coords
|
||||||
|
@ -201,9 +226,6 @@ class YAxisLabel(AxisLabel):
|
||||||
# WTF IS THIS FORMAT?
|
# WTF IS THIS FORMAT?
|
||||||
return ('{: ,.%df}' % self.digits).format(tick_pos).replace(',', ' ')
|
return ('{: ,.%df}' % self.digits).format(tick_pos).replace(',', ' ')
|
||||||
|
|
||||||
def boundingRect(self): # noqa
|
|
||||||
return QtCore.QRectF(0, 0, 50, 10)
|
|
||||||
|
|
||||||
def update_label(
|
def update_label(
|
||||||
self,
|
self,
|
||||||
abs_pos: QPointF, # scene coords
|
abs_pos: QPointF, # scene coords
|
||||||
|
@ -225,15 +247,10 @@ class YSticky(YAxisLabel):
|
||||||
*args,
|
*args,
|
||||||
**kwargs
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self._chart = chart
|
|
||||||
|
|
||||||
# XXX: not sure why this wouldn't work with a proxy?
|
super().__init__(*args, **kwargs)
|
||||||
# pg.SignalProxy(
|
|
||||||
# delay=0,
|
self._chart = chart
|
||||||
# rateLimit=60,
|
|
||||||
# slot=last.update_on_resize,
|
|
||||||
# )
|
|
||||||
chart.sigRangeChanged.connect(self.update_on_resize)
|
chart.sigRangeChanged.connect(self.update_on_resize)
|
||||||
|
|
||||||
def update_on_resize(self, vr, r):
|
def update_on_resize(self, vr, r):
|
||||||
|
|
Loading…
Reference in New Issue