Scale level label correctly to small(er) fonts

Not sure what fixed it exactly, and I guess we didn't need any relative
DPI scaling factor after all. Using the 3px margin on the level label
seems to make it look nice for any font size (i think) as well.

Gonna need some cleanup after this one.
bar_select
Tyler Goodlet 2020-11-02 15:27:48 -05:00
parent 96f700a762
commit 119196f2ff
4 changed files with 60 additions and 99 deletions

View File

@ -136,7 +136,9 @@ class AxisLabel(pg.GraphicsObject):
self._dpifont = DpiAwareFont() self._dpifont = DpiAwareFont()
self._dpifont.configure_to_dpi(_font._screen) self._dpifont.configure_to_dpi(_font._screen)
if font_size is not None: if font_size is not None:
# print(f"SETTING FONT TO: {font_size}")
self._dpifont._set_qfont_px_size(font_size) self._dpifont._set_qfont_px_size(font_size)
# self._font._fm = QtGui.QFontMetrics(self._font) # self._font._fm = QtGui.QFontMetrics(self._font)
@ -155,7 +157,7 @@ class AxisLabel(pg.GraphicsObject):
def paint(self, p, option, widget): def paint(self, p, option, widget):
# p.drawPicture(0, 0, self.pic) # p.drawPicture(0, 0, self.pic)
p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver) # p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
if self.label_str: if self.label_str:
@ -174,13 +176,13 @@ class AxisLabel(pg.GraphicsObject):
p.drawText(self.rect, self.text_flags, self.label_str) p.drawText(self.rect, self.text_flags, self.label_str)
def boundingRect(self): # noqa def boundingRect(self): # noqa
# if self.label_str: if self.label_str:
# self._size_br_from_str(self.label_str) self._size_br_from_str(self.label_str)
# return self.rect return self.rect
# return QtCore.QRectF() return QtCore.QRectF()
return self.rect or QtCore.QRectF() # return self.rect or QtCore.QRectF()
def _size_br_from_str(self, value: str) -> None: def _size_br_from_str(self, value: str) -> None:
"""Do our best to render the bounding rect to a set margin """Do our best to render the bounding rect to a set margin
@ -193,7 +195,7 @@ class AxisLabel(pg.GraphicsObject):
# px_per_char = self._font._fm.averageCharWidth() # px_per_char = self._font._fm.averageCharWidth()
# br = br * 1.88 # br = br * 1.88
txt_h, txt_w = br.height(), br.width() txt_h, txt_w = br.height(), br.width()
print(f'orig: {txt_h}') # print(f'orig: {txt_h}')
# txt_h = (br.topLeft() - br.bottomRight()).y() # txt_h = (br.topLeft() - br.bottomRight()).y()
# txt_w = len(value) * px_per_char # txt_w = len(value) * px_per_char
# txt_w *= 1.88 # txt_w *= 1.88
@ -220,9 +222,6 @@ class AxisLabel(pg.GraphicsObject):
class XAxisLabel(AxisLabel): class XAxisLabel(AxisLabel):
_w_margin = 0
_h_margin = 0
text_flags = ( text_flags = (
QtCore.Qt.TextDontClip QtCore.Qt.TextDontClip
| QtCore.Qt.AlignCenter | QtCore.Qt.AlignCenter
@ -246,14 +245,15 @@ class XAxisLabel(AxisLabel):
self.label_str = timestrs[0] self.label_str = timestrs[0]
width = self.boundingRect().width() w = self.boundingRect().width()
self.setPos(QPointF( self.setPos(QPointF(
abs_pos.x() - width / 2, # - offset, abs_pos.x() - w / 2 - offset,
0 0,
)) ))
class YAxisLabel(AxisLabel): class YAxisLabel(AxisLabel):
_h_margin = 3
text_flags = ( text_flags = (
# QtCore.Qt.AlignLeft # QtCore.Qt.AlignLeft
@ -280,7 +280,7 @@ class YAxisLabel(AxisLabel):
h = br.height() h = br.height()
self.setPos(QPointF( self.setPos(QPointF(
0, 0,
abs_pos.y() - h / 2 #- offset abs_pos.y() - h / 2 - offset
)) ))
@ -310,22 +310,6 @@ class YSticky(YAxisLabel):
last, last,
) )
# chart = self._chart
# a = chart._array
# fields = a.dtype.fields
# if fields and 'close' in fields:
# index, last = a[-1][['index', 'close']]
# else: # non-ohlc case
# index = len(a) - 1
# last = a[chart.name][-1]
# self.update_from_data(
# index,
# last,
# )
def update_from_data( def update_from_data(
self, self,
index: int, index: int,

View File

@ -18,11 +18,11 @@ from ._graphics import (
CrossHair, CrossHair,
ContentsLabel, ContentsLabel,
BarItems, BarItems,
h_line, level_line,
) )
from ._axes import YSticky from ._axes import YSticky
from ._style import ( from ._style import (
configure_font_to_dpi, _font,
hcolor, hcolor,
CHART_MARGINS, CHART_MARGINS,
_xaxis_at, _xaxis_at,
@ -660,7 +660,7 @@ async def _async_main(
chart_app = widgets['main'] chart_app = widgets['main']
# attempt to configure DPI aware font size # attempt to configure DPI aware font size
configure_font_to_dpi(current_screen()) _font.configure_to_dpi(current_screen())
# from ._exec import get_screen # from ._exec import get_screen
# screen = get_screen(chart_app.geometry().bottomRight()) # screen = get_screen(chart_app.geometry().bottomRight())
@ -898,8 +898,8 @@ async def chart_from_fsp(
# graphics.curve.setFillLevel(50) # graphics.curve.setFillLevel(50)
# add moveable over-[sold/bought] lines # add moveable over-[sold/bought] lines
chart.plotItem.addItem(h_line(30)) level_line(chart, 30)
chart.plotItem.addItem(h_line(70)) level_line(chart, 70)
chart._shm = shm chart._shm = shm
chart._set_yrange() chart._set_yrange()

View File

@ -644,6 +644,9 @@ class BarItems(pg.GraphicsObject):
class LevelLabel(YSticky): class LevelLabel(YSticky):
_w_margin = 3
_h_margin = 3
def update_label( def update_label(
self, self,
abs_pos: QPointF, # scene coords abs_pos: QPointF, # scene coords
@ -653,17 +656,18 @@ class LevelLabel(YSticky):
# this is read inside ``.paint()`` # this is read inside ``.paint()``
self.label_str = '{data: ,.{digits}f}'.format( self.label_str = '{data: ,.{digits}f}'.format(
digits=self.digits, data=data).replace(',', ' ') digits=self.digits,
data=data
).replace(',', ' ')
self._size_br_from_str(self.label_str) self._size_br_from_str(self.label_str)
br = self.boundingRect() br = self.boundingRect()
w, h = br.height(), br.width() h, w = br.height(), br.width()
self.setPos(QPointF( self.setPos(QPointF(
# *2 why? wat..? -w,
0 - w*2, abs_pos.y() - offset
abs_pos.y(), # - h / 2 - offset
)) ))
def size_hint(self) -> Tuple[None, None]: def size_hint(self) -> Tuple[None, None]:
@ -683,16 +687,12 @@ class LevelLine(pg.InfiniteLine):
def set_value(self, value: float) -> None: def set_value(self, value: float) -> None:
self.label.update_from_data(0, self.value()) self.label.update_from_data(0, self.value())
# def valueChanged(self) -> None:
# print('yooo')
# self.label.update_from_data(0, self.value())
def level_line( def level_line(
chart: 'ChartPlogWidget', # noqa chart: 'ChartPlogWidget', # noqa
level: float, level: float,
digits: int = 3, digits: int = 1,
# label_precision: int = 0, font_size: int = 4,
) -> LevelLine: ) -> LevelLine:
"""Convenience routine to add a styled horizontal line to a plot. """Convenience routine to add a styled horizontal line to a plot.
@ -703,11 +703,10 @@ def level_line(
# TODO: pass this from symbol data # TODO: pass this from symbol data
digits=digits, digits=digits,
opacity=1, opacity=1,
font_size=4, font_size=font_size,
bg_color='default', bg_color='default',
) )
label.update_from_data(0, level) label.update_from_data(0, level)
# label._size_br_from_str(
line = LevelLine( line = LevelLine(
label, label,
@ -719,7 +718,6 @@ def level_line(
# activate/draw label # activate/draw label
line.setValue(level) line.setValue(level)
# line.show()
chart.plotItem.addItem(line) chart.plotItem.addItem(line)
return line return line

View File

@ -9,28 +9,6 @@ from ..log import get_logger
log = get_logger(__name__) log = get_logger(__name__)
# def configure_font_to_dpi(screen: QtGui.QScreen):
# """Set an appropriately sized font size depending on the screen DPI.
# If we end up needing to generalize this more here there are resources
# listed in the script in ``snippets/qt_screen_info.py``.
# """
# dpi = screen.physicalDotsPerInch()
# font_size = round(_font_inches_we_like * dpi)
# log.info(
# f"\nscreen:{screen.name()} with DPI: {dpi}"
# f"\nbest font size is {font_size}\n"
# )
# global _font
# _font.setPixelSize(font_size)
# _font._fm = QtGui.QFontMetrics(_font)
# return _font
# chart-wide font # chart-wide font
# font size 6px / 53 dpi (3x scaled down on 4k hidpi) # font size 6px / 53 dpi (3x scaled down on 4k hidpi)
_font_inches_we_like = 6 / 53 # px / (px / inch) = inch _font_inches_we_like = 6 / 53 # px / (px / inch) = inch
@ -45,9 +23,9 @@ class DpiAwareFont:
self._qfont = QtGui.QFont(name) self._qfont = QtGui.QFont(name)
self._iwl = _font_inches_we_like self._iwl = _font_inches_we_like
self._qfm = QtGui.QFontMetrics(self._qfont) self._qfm = QtGui.QFontMetrics(self._qfont)
self._font_size = None
self._physical_dpi = None self._physical_dpi = None
self._screen = None self._screen = None
self._dpi_scalar = 1.
def _set_qfont_px_size(self, px_size: int) -> None: def _set_qfont_px_size(self, px_size: int) -> None:
# self._qfont = QtGui.Qfont(self.name) # self._qfont = QtGui.Qfont(self.name)
@ -62,9 +40,6 @@ class DpiAwareFont:
def px_size(self): def px_size(self):
return self._qfont.pixelSize() return self._qfont.pixelSize()
# def set_px_size(self, size: int) -> None:
# pass
def configure_to_dpi(self, screen: QtGui.QScreen): def configure_to_dpi(self, screen: QtGui.QScreen):
"""Set an appropriately sized font size depending on the screen DPI. """Set an appropriately sized font size depending on the screen DPI.
@ -79,11 +54,12 @@ class DpiAwareFont:
f"\nbest font size is {font_size}\n" f"\nbest font size is {font_size}\n"
) )
self._set_qfont_px_size(font_size) self._set_qfont_px_size(font_size)
self._font_size = font_size
self._physical_dpi = dpi self._physical_dpi = dpi
self._screen = screen self._screen = screen
def boundingRect(self, value: str) -> QtCore.QRectF: def boundingRect(self, value: str) -> QtCore.QRectF:
# print(f'boundingRect STRING: {value}')
screen = self._screen screen = self._screen
if screen is None: if screen is None:
raise RuntimeError("You must call .configure_to_dpi() first!") raise RuntimeError("You must call .configure_to_dpi() first!")
@ -93,23 +69,26 @@ class DpiAwareFont:
# XXX: for wtv absolutely fucked reason, the scaling only applies # XXX: for wtv absolutely fucked reason, the scaling only applies
# to everything when the current font size **is not** the size # to everything when the current font size **is not** the size
# needed to get the original desired text height... :mindblow: # needed to get the original desired text height... :mindblow:
if self._font_size != 6:
# scalar = self._qfm.fontDpi() / self._physical_dpi # if self.px_size != 6:
scalar = screen.logicalDotsPerInch() / screen.physicalDotsPerInch() # # scalar = self._qfm.fontDpi() / self._physical_dpi
# scalar = 100 / screen.physicalDotsPerInch() # # self._dpi_scalar = scalar = screen.logicalDotsPerInch() / screen.physicalDotsPerInch()
# assert 0 # # self._dpi_scalar = scalar = 96 / screen.physicalDotsPerInch()
print(f'SCALAR {scalar}') # # # assert 0
# # print(f'SCALAR {scalar}')
# # w = min(self._qfm.averageCharWidth() * len(value), unscaled_br.width())
return QtCore.QRectF( # return QtCore.QRectF(
# unscaled_br.x(), # # unscaled_br.x(),
# unscaled_br.y(), # # unscaled_br.y(),
0, # 0,
0, # 0,
unscaled_br.width() * scalar, # # w * scalar,
unscaled_br.height() * scalar, # unscaled_br.width(), # * scalar,
) # unscaled_br.height(),# * scalar,
else: # )
# else:
return QtCore.QRectF( return QtCore.QRectF(
# unscaled_br.x(), # unscaled_br.x(),
# unscaled_br.y(), # unscaled_br.y(),