Factor all per graphic `.draw_last()` methods into closures
parent
8f1faf97ee
commit
57acc3bd29
|
@ -160,23 +160,6 @@ class FastAppendCurve(pg.GraphicsObject):
|
|||
QLineF(lbar, 0, rbar, 0)
|
||||
).length()
|
||||
|
||||
def draw_last(
|
||||
self,
|
||||
x: np.ndarray,
|
||||
y: np.ndarray,
|
||||
|
||||
) -> None:
|
||||
x_last = x[-1]
|
||||
y_last = y[-1]
|
||||
|
||||
# draw the "current" step graphic segment so it lines up with
|
||||
# the "middle" of the current (OHLC) sample.
|
||||
self._last_line = QLineF(
|
||||
x[-2], y[-2],
|
||||
x_last, y_last
|
||||
)
|
||||
# self._last_w = x_last - x[-2]
|
||||
|
||||
# XXX: lol brutal, the internals of `CurvePoint` (inherited by
|
||||
# our `LineDot`) required ``.getData()`` to work..
|
||||
def getData(self):
|
||||
|
|
|
@ -23,7 +23,6 @@ incremental update.
|
|||
|
||||
'''
|
||||
from __future__ import annotations
|
||||
from functools import partial
|
||||
from typing import (
|
||||
Optional,
|
||||
Callable,
|
||||
|
@ -58,6 +57,7 @@ from ._pathops import (
|
|||
)
|
||||
from ._ohlc import (
|
||||
BarItems,
|
||||
bar_from_ohlc_row,
|
||||
)
|
||||
from ._curve import (
|
||||
FastAppendCurve,
|
||||
|
@ -245,19 +245,74 @@ def render_baritems(
|
|||
bars.update()
|
||||
|
||||
draw_last = False
|
||||
lasts = self.shm.array[-2:]
|
||||
last = lasts[-1]
|
||||
|
||||
if should_line:
|
||||
def draw_last():
|
||||
|
||||
def draw_last_flattened_ohlc_line(
|
||||
graphics: pg.GraphicsObject,
|
||||
path: QPainterPath,
|
||||
src_data: np.ndarray,
|
||||
render_data: np.ndarray,
|
||||
reset: bool,
|
||||
) -> None:
|
||||
lasts = src_data[-2:]
|
||||
x, y = lasts['index'], lasts['close']
|
||||
curve.draw_last(x, y)
|
||||
else:
|
||||
draw_last = partial(
|
||||
bars.draw_last,
|
||||
last,
|
||||
|
||||
# draw the "current" step graphic segment so it
|
||||
# lines up with the "middle" of the current
|
||||
# (OHLC) sample.
|
||||
graphics._last_line = QLineF(
|
||||
x[-2], y[-2],
|
||||
x[-1], y[-1]
|
||||
)
|
||||
|
||||
draw_last = draw_last_flattened_ohlc_line
|
||||
|
||||
else:
|
||||
def draw_last_ohlc_bar(
|
||||
graphics: pg.GraphicsObject,
|
||||
path: QPainterPath,
|
||||
src_data: np.ndarray,
|
||||
render_data: np.ndarray,
|
||||
reset: bool,
|
||||
) -> None:
|
||||
last = src_data[-1]
|
||||
# generate new lines objects for updatable "current bar"
|
||||
graphics._last_bar_lines = bar_from_ohlc_row(last, graphics.w)
|
||||
|
||||
# last bar update
|
||||
i, o, h, l, last, v = last[
|
||||
['index', 'open', 'high', 'low', 'close', 'volume']
|
||||
]
|
||||
# assert i == graphics.start_index - 1
|
||||
# assert i == last_index
|
||||
body, larm, rarm = graphics._last_bar_lines
|
||||
|
||||
# XXX: is there a faster way to modify this?
|
||||
rarm.setLine(rarm.x1(), last, rarm.x2(), last)
|
||||
|
||||
# writer is responsible for changing open on "first" volume of bar
|
||||
larm.setLine(larm.x1(), o, larm.x2(), o)
|
||||
|
||||
if l != h: # noqa
|
||||
|
||||
if body is None:
|
||||
body = graphics._last_bar_lines[0] = QLineF(i, l, i, h)
|
||||
else:
|
||||
# update body
|
||||
body.setLine(i, l, i, h)
|
||||
|
||||
# XXX: pretty sure this is causing an issue where the
|
||||
# bar has a large upward move right before the next
|
||||
# sample and the body is getting set to None since the
|
||||
# next bar is flat but the shm array index update wasn't
|
||||
# read by the time this code runs. Iow we're doing this
|
||||
# removal of the body for a bar index that is now out of
|
||||
# date / from some previous sample. It's weird though
|
||||
# because i've seen it do this to bars i - 3 back?
|
||||
|
||||
draw_last = draw_last_ohlc_bar
|
||||
|
||||
return (
|
||||
graphics,
|
||||
r,
|
||||
|
@ -355,6 +410,12 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
graphics: pg.GraphicsObject
|
||||
_shm: ShmArray
|
||||
|
||||
draw_last_datum: Optional[
|
||||
Callable[
|
||||
[np.ndarray, str],
|
||||
tuple[np.ndarray]
|
||||
]
|
||||
] = None
|
||||
is_ohlc: bool = False
|
||||
render: bool = True # toggle for display loop
|
||||
|
||||
|
@ -543,7 +604,7 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
)
|
||||
# shm read and slice to view
|
||||
read = (
|
||||
xfirst, xlast, array,
|
||||
xfirst, xlast, src_array,
|
||||
ivl, ivr, in_view,
|
||||
) = self.read()
|
||||
|
||||
|
@ -618,14 +679,6 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
# corrent yet for step curves.. remove this to see it.
|
||||
should_redraw = True
|
||||
|
||||
# TODO: remove this and instead place all step curve
|
||||
# updating into pre-path data render callbacks.
|
||||
# full input data
|
||||
x = array['index']
|
||||
y = array[array_key]
|
||||
x_last = x[-1]
|
||||
y_last = y[-1]
|
||||
|
||||
draw_last = True
|
||||
|
||||
# downsampling incremental state checking
|
||||
|
@ -698,15 +751,53 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
graphics.fast_path = r.fast_path
|
||||
|
||||
if draw_last and not bars:
|
||||
# default line draw last call
|
||||
|
||||
if not step_mode:
|
||||
|
||||
def draw_last_line(
|
||||
graphics: pg.GraphicsObject,
|
||||
path: QPainterPath,
|
||||
src_data: np.ndarray,
|
||||
render_data: np.ndarray,
|
||||
reset: bool,
|
||||
|
||||
) -> None:
|
||||
# default line draw last call
|
||||
with graphics.reset_cache():
|
||||
x = data['index']
|
||||
y = data[array_key]
|
||||
graphics.draw_last(x, y)
|
||||
x = render_data['index']
|
||||
y = render_data[array_key]
|
||||
x_last = x[-1]
|
||||
y_last = y[-1]
|
||||
|
||||
# draw the "current" step graphic segment so it
|
||||
# lines up with the "middle" of the current
|
||||
# (OHLC) sample.
|
||||
graphics._last_line = QLineF(
|
||||
x[-2], y[-2],
|
||||
x_last, y_last
|
||||
)
|
||||
|
||||
draw_last_line(graphics, path, src_array, data, reset)
|
||||
|
||||
else:
|
||||
|
||||
def draw_last_step(
|
||||
graphics: pg.GraphicsObject,
|
||||
path: QPainterPath,
|
||||
src_data: np.ndarray,
|
||||
render_data: np.ndarray,
|
||||
reset: bool,
|
||||
|
||||
) -> None:
|
||||
w = 0.5
|
||||
# TODO: remove this and instead place all step curve
|
||||
# updating into pre-path data render callbacks.
|
||||
# full input data
|
||||
x = src_array['index']
|
||||
y = src_array[array_key]
|
||||
x_last = x[-1]
|
||||
y_last = y[-1]
|
||||
|
||||
# lol, commenting this makes step curves
|
||||
# all "black" for me :eyeroll:..
|
||||
graphics._last_line = QLineF(
|
||||
|
@ -718,6 +809,8 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
x_last + w, y_last,
|
||||
)
|
||||
|
||||
draw_last_step(graphics, path, src_array, data, reset)
|
||||
|
||||
# TODO: does this actuallly help us in any way (prolly should
|
||||
# look at the source / ask ogi). I think it avoid artifacts on
|
||||
# wheel-scroll downsampling curve updates?
|
||||
|
@ -725,7 +818,7 @@ class Flow(msgspec.Struct): # , frozen=True):
|
|||
profiler('.prepareGeometryChange()')
|
||||
|
||||
elif bars and draw_last:
|
||||
draw_last()
|
||||
draw_last(graphics, path, src_array, data, reset)
|
||||
graphics.update()
|
||||
profiler('.update()')
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ from .._profile import pg_profile_enabled, ms_slower_then
|
|||
from ._style import hcolor
|
||||
from ..log import get_logger
|
||||
from ._curve import FastAppendCurve
|
||||
from ._compression import ohlc_flatten
|
||||
from ._pathops import gen_ohlc_qpath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._chart import LinkedSplits
|
||||
|
@ -148,44 +146,6 @@ class BarItems(pg.GraphicsObject):
|
|||
else:
|
||||
return 0
|
||||
|
||||
def draw_last(
|
||||
self,
|
||||
last: np.ndarray,
|
||||
|
||||
) -> None:
|
||||
# generate new lines objects for updatable "current bar"
|
||||
self._last_bar_lines = bar_from_ohlc_row(last, self.w)
|
||||
|
||||
# last bar update
|
||||
i, o, h, l, last, v = last[
|
||||
['index', 'open', 'high', 'low', 'close', 'volume']
|
||||
]
|
||||
# assert i == self.start_index - 1
|
||||
# assert i == last_index
|
||||
body, larm, rarm = self._last_bar_lines
|
||||
|
||||
# XXX: is there a faster way to modify this?
|
||||
rarm.setLine(rarm.x1(), last, rarm.x2(), last)
|
||||
|
||||
# writer is responsible for changing open on "first" volume of bar
|
||||
larm.setLine(larm.x1(), o, larm.x2(), o)
|
||||
|
||||
if l != h: # noqa
|
||||
|
||||
if body is None:
|
||||
body = self._last_bar_lines[0] = QLineF(i, l, i, h)
|
||||
else:
|
||||
# update body
|
||||
body.setLine(i, l, i, h)
|
||||
|
||||
# XXX: pretty sure this is causing an issue where the bar has
|
||||
# a large upward move right before the next sample and the body
|
||||
# is getting set to None since the next bar is flat but the shm
|
||||
# array index update wasn't read by the time this code runs. Iow
|
||||
# we're doing this removal of the body for a bar index that is
|
||||
# now out of date / from some previous sample. It's weird
|
||||
# though because i've seen it do this to bars i - 3 back?
|
||||
|
||||
def boundingRect(self):
|
||||
# Qt docs: https://doc.qt.io/qt-5/qgraphicsitem.html#boundingRect
|
||||
|
||||
|
|
Loading…
Reference in New Issue