Use `Viz.draw_last()` inside `.update_graphics()`
In an effort to ensure uniform and uppx-optimized last datum graphics updates call this method directly instead of the equivalent graphics object thus ensuring we only update the last pixel column according with the appropriate max/min computed from the last uppx's worth of data. Fixes / improvements to enable `.draw_last()` usage include, - change `Viz._render_table` -> `._alt_r: tuple[Renderer, pg.GraphicsItem] | None` which holds an alternative (usually downsampled) render and graphics obj. - extend the `.draw_last()` signature to include: - `last_read` to allow passing in the already read data from `.update_graphics()`, if it isn't passed then a manual read is done internally. - `reset_cache: bool` which is passed through to the graphics obj. - use the new `Formatter.flat_index_ratio: float` when indexing into xy 1d data to compute the max/min for that px column. Other, - drop `bars_range` input from `maxmin()` since it's unused.multichartz
parent
b762cf0456
commit
65434e2e67
|
@ -132,9 +132,9 @@ def render_baritems(
|
|||
|
||||
# baseline "line" downsampled OHLC curve that should
|
||||
# kick on only when we reach a certain uppx threshold.
|
||||
self._render_table = (ds_curve_r, curve)
|
||||
self._alt_r = (ds_curve_r, curve)
|
||||
|
||||
ds_r, curve = self._render_table
|
||||
ds_r, curve = self._alt_r
|
||||
|
||||
# print(
|
||||
# f'r: {r.fmtr.xy_slice}\n'
|
||||
|
@ -270,11 +270,11 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
_index_step: float | None = None
|
||||
|
||||
# map from uppx -> (downsampled data, incremental graphics)
|
||||
_src_r: Optional[Renderer] = None
|
||||
_render_table: dict[
|
||||
Optional[int],
|
||||
tuple[Renderer, pg.GraphicsItem],
|
||||
] = (None, None)
|
||||
_src_r: Renderer | None = None
|
||||
_alt_r: tuple[
|
||||
Renderer,
|
||||
pg.GraphicsItem
|
||||
] | None = None
|
||||
|
||||
# cache of y-range values per x-range input.
|
||||
_mxmns: dict[
|
||||
|
@ -329,11 +329,6 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
def maxmin(
|
||||
self,
|
||||
|
||||
# TODO: drop this right?
|
||||
bars_range: Optional[tuple[
|
||||
int, int, int, int, int, int
|
||||
]] = None,
|
||||
|
||||
x_range: slice | tuple[int, int] | None = None,
|
||||
use_caching: bool = True,
|
||||
|
||||
|
@ -366,11 +361,7 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
rbar,
|
||||
_,
|
||||
r,
|
||||
) = (
|
||||
# TODO: drop this yah?
|
||||
bars_range
|
||||
or self.datums_range()
|
||||
)
|
||||
) = self.datums_range()
|
||||
|
||||
profiler(f'{self.name} got bars range')
|
||||
x_range = lbar, rbar
|
||||
|
@ -816,18 +807,29 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
with graphics.reset_cache():
|
||||
graphics.path = r.path
|
||||
graphics.fast_path = r.fast_path
|
||||
|
||||
self.draw_last(
|
||||
array_key=array_key,
|
||||
last_read=read,
|
||||
reset_cache=reset_cache,
|
||||
)
|
||||
else:
|
||||
# assign output paths to graphicis obj
|
||||
graphics.path = r.path
|
||||
graphics.fast_path = r.fast_path
|
||||
|
||||
graphics.draw_last_datum(
|
||||
path,
|
||||
src_array,
|
||||
reset_cache,
|
||||
array_key,
|
||||
index_field=self.index_field,
|
||||
)
|
||||
self.draw_last(
|
||||
array_key=array_key,
|
||||
last_read=read,
|
||||
reset_cache=reset_cache,
|
||||
)
|
||||
# graphics.draw_last_datum(
|
||||
# path,
|
||||
# src_array,
|
||||
# reset_cache,
|
||||
# array_key,
|
||||
# index_field=self.index_field,
|
||||
# )
|
||||
graphics.update()
|
||||
profiler('.update()')
|
||||
|
||||
|
@ -845,7 +847,9 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
|
||||
def draw_last(
|
||||
self,
|
||||
array_key: Optional[str] = None,
|
||||
array_key: str | None = None,
|
||||
last_read: tuple | None = None,
|
||||
reset_cache: bool = False,
|
||||
only_last_uppx: bool = False,
|
||||
|
||||
) -> None:
|
||||
|
@ -854,17 +858,11 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
(
|
||||
xfirst, xlast, src_array,
|
||||
ivl, ivr, in_view,
|
||||
) = self.read()
|
||||
) = last_read or self.read()
|
||||
|
||||
g = self.graphics
|
||||
array_key = array_key or self.name
|
||||
x, y = g.draw_last_datum(
|
||||
g.path,
|
||||
src_array,
|
||||
False, # never reset path
|
||||
array_key,
|
||||
self.index_field,
|
||||
)
|
||||
|
||||
gfx = self.graphics
|
||||
|
||||
# the renderer is downsampling we choose
|
||||
# to always try and update a single (interpolating)
|
||||
|
@ -874,19 +872,28 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
# worth of data since that's all the screen
|
||||
# can represent on the last column where
|
||||
# the most recent datum is being drawn.
|
||||
uppx = ceil(self._last_uppx)
|
||||
if (
|
||||
self._in_ds
|
||||
or only_last_uppx
|
||||
(self._in_ds or only_last_uppx)
|
||||
and uppx > 0
|
||||
):
|
||||
dsg = self.ds_graphics or self.graphics
|
||||
alt_renderer = self._alt_r
|
||||
if alt_renderer:
|
||||
renderer, gfx = alt_renderer
|
||||
fmtr = renderer.fmtr
|
||||
x = fmtr.x_1d
|
||||
y = fmtr.y_1d
|
||||
else:
|
||||
renderer = self._src_r
|
||||
fmtr = renderer.fmtr
|
||||
x = fmtr.x_1d
|
||||
y = fmtr.y_1d
|
||||
|
||||
if alt_renderer:
|
||||
uppx *= fmtr.flat_index_ratio
|
||||
|
||||
# XXX: pretty sure we don't need this?
|
||||
# if isinstance(g, Curve):
|
||||
# with dsg.reset_cache():
|
||||
uppx = round(self._last_uppx)
|
||||
y = y[-uppx:]
|
||||
ymn, ymx = y.min(), y.max()
|
||||
# print(f'drawing uppx={uppx} mxmn line: {ymn}, {ymx}')
|
||||
try:
|
||||
iuppx = x[-uppx]
|
||||
except IndexError:
|
||||
|
@ -894,16 +901,32 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
# datum index.
|
||||
iuppx = x[0]
|
||||
|
||||
dsg._last_line = QLineF(
|
||||
gfx._last_line = QLineF(
|
||||
iuppx, ymn,
|
||||
x[-1], ymx,
|
||||
)
|
||||
# print(f'updating DS curve {self.name}')
|
||||
dsg.update()
|
||||
# if self.is_ohlc:
|
||||
# times = self.shm.array['time']
|
||||
# time_step = times[-1] - times[-2]
|
||||
# # if 'hist' in self.shm.token['shm_name']
|
||||
# # if self.index_step() == 1:
|
||||
# # breakpoint()
|
||||
# print(
|
||||
# f'updating DS curve {self.name}@{time_step}s\n'
|
||||
# f'drawing uppx={uppx} mxmn line: {ymn}, {ymx}'
|
||||
# )
|
||||
|
||||
else:
|
||||
x, y = gfx.draw_last_datum(
|
||||
gfx.path,
|
||||
src_array,
|
||||
reset_cache, # never reset path
|
||||
array_key,
|
||||
self.index_field,
|
||||
)
|
||||
# print(f'updating NOT DS curve {self.name}')
|
||||
g.update()
|
||||
|
||||
gfx.update()
|
||||
|
||||
def default_view(
|
||||
self,
|
||||
|
@ -1029,7 +1052,7 @@ class Viz(msgspec.Struct): # , frozen=True):
|
|||
)
|
||||
|
||||
if do_ds:
|
||||
# view.interaction_graphics_update_cycle()
|
||||
# view.interaction_graphics_cycle()
|
||||
view.maybe_downsample_graphics()
|
||||
view._set_yrange()
|
||||
|
||||
|
|
Loading…
Reference in New Issue