Fix line -> bars on 6x UPPX

Read the `Viz.index_step()` directly to avoid always reading 1 on the
slow chart; this was completely broken before and resulting in not
rendering the bars graphic on the slow chart until at a true uppx of
1 which obviously doesn't work for 60 width bars XD

Further cleanups to `._render` module:
- drop `array` output from `Renderer.render()`, `read_from_key` input
  and fix type annot.
- drop `should_line`, `changed_to_line` and `render_kwargs` from
  `render_baritems()` outputs and instead calc `should_redraw` logic
  inside the func body and return as output.
multichartz
Tyler Goodlet 2022-12-14 09:49:43 -05:00
parent be9f1a1aef
commit c09f5cbbff
1 changed files with 39 additions and 45 deletions

View File

@ -95,13 +95,13 @@ def render_baritems(
''' '''
bars = graphics bars = graphics
# if no source data renderer exists create one. self = viz # TODO: make this a ``Viz`` method?
self = viz
show_bars: bool = False
r = self._src_r r = self._src_r
first_render: bool = False
# if no source data renderer exists create one.
if not r: if not r:
show_bars = True first_render = True
# OHLC bars path renderer # OHLC bars path renderer
r = self._src_r = Renderer( r = self._src_r = Renderer(
@ -143,10 +143,11 @@ def render_baritems(
# - if we're **not** downsampling then we simply want to # - if we're **not** downsampling then we simply want to
# render the bars graphics curve and update.. # render the bars graphics curve and update..
# - if instead we are in a downsamplig state then we to # - if instead we are in a downsamplig state then we to
x_gt = 6 * (r.fmtr.index_step_size or 1) x_gt = 6 * (self.index_step() or 1)
uppx = curve.x_uppx() uppx = curve.x_uppx()
# print(f'BARS UPPX: {uppx}') # print(f'BARS UPPX: {uppx}')
in_line = should_line = curve.isVisible() in_line = should_line = curve.isVisible()
if ( if (
in_line in_line
and uppx < x_gt and uppx < x_gt
@ -174,7 +175,7 @@ def render_baritems(
else: else:
graphics = bars graphics = bars
if show_bars: if first_render:
bars.show() bars.show()
changed_to_line = False changed_to_line = False
@ -191,20 +192,30 @@ def render_baritems(
curve.update() curve.update()
changed_to_line = True changed_to_line = True
elif in_line and not should_line: elif (
in_line
and not should_line
):
# change to bars graphic # change to bars graphic
log.info(f'showing bars graphic {self.name}') log.info(
f'showing bars graphic {self.name}\n'
f'first bars render?: {first_render}'
)
curve.hide() curve.hide()
bars.show() bars.show()
bars.update() bars.update()
# breakpoint()
# XXX: is this required?
viz._in_ds = should_line
should_redraw = (
changed_to_line
or not should_line
)
return ( return (
graphics, graphics,
r, r,
{'read_from_key': False}, should_redraw,
should_line,
changed_to_line,
) )
@ -485,8 +496,6 @@ class Viz(msgspec.Struct): # , frozen=True):
index_field=index_field, index_field=index_field,
array=array, array=array,
) )
# if rbar < lbar:
# breakpoint()
if profiler: if profiler:
profiler('self.datums_range()') profiler('self.datums_range()')
@ -555,9 +564,9 @@ class Viz(msgspec.Struct): # , frozen=True):
self, self,
use_vr: bool = True, use_vr: bool = True,
render: bool = True, render: bool = True,
array_key: Optional[str] = None, array_key: str | None = None,
profiler: Optional[Profiler] = None, profiler: Profiler | None = None,
do_append: bool = True, do_append: bool = True,
**kwargs, **kwargs,
@ -592,8 +601,6 @@ class Viz(msgspec.Struct): # , frozen=True):
return graphics return graphics
should_redraw: bool = False should_redraw: bool = False
should_line: bool = False
rkwargs = {}
# TODO: probably specialize ``Renderer`` types instead of # TODO: probably specialize ``Renderer`` types instead of
# these logic checks? # these logic checks?
@ -606,9 +613,7 @@ class Viz(msgspec.Struct): # , frozen=True):
( (
graphics, graphics,
r, r,
rkwargs, should_redraw,
should_line,
changed_to_line,
) = render_baritems( ) = render_baritems(
self, self,
graphics, graphics,
@ -616,8 +621,6 @@ class Viz(msgspec.Struct): # , frozen=True):
profiler, profiler,
**kwargs, **kwargs,
) )
should_redraw = changed_to_line or not should_line
self._in_ds = should_line
elif not r: elif not r:
if isinstance(graphics, StepCurve): if isinstance(graphics, StepCurve):
@ -630,10 +633,6 @@ class Viz(msgspec.Struct): # , frozen=True):
), ),
) )
# TODO: append logic inside ``.render()`` isn't
# correct yet for step curves.. remove this to see it.
should_redraw = True
else: else:
r = self._src_r r = self._src_r
if not r: if not r:
@ -684,7 +683,6 @@ class Viz(msgspec.Struct): # , frozen=True):
new_sample_rate = True new_sample_rate = True
should_ds = False should_ds = False
should_redraw = True should_redraw = True
showing_src_data = True showing_src_data = True
# MAIN RENDER LOGIC: # MAIN RENDER LOGIC:
@ -708,15 +706,13 @@ class Viz(msgspec.Struct): # , frozen=True):
showing_src_data=showing_src_data, showing_src_data=showing_src_data,
do_append=do_append, do_append=do_append,
**rkwargs,
) )
if not out: if not out:
log.warning(f'{self.name} failed to render!?') log.warning(f'{self.name} failed to render!?')
return graphics return graphics
path, data, reset = out path, reset = out
# XXX: SUPER UGGGHHH... without this we get stale cache # XXX: SUPER UGGGHHH... without this we get stale cache
# graphics that don't update until you downsampler again.. # graphics that don't update until you downsampler again..
@ -732,6 +728,7 @@ class Viz(msgspec.Struct): # , frozen=True):
# src_array, # src_array,
# reset, # reset,
# array_key, # array_key,
# index_field=self.index_field,
# ) # )
# graphics.update() # graphics.update()
# profiler('.update()') # profiler('.update()')
@ -786,14 +783,17 @@ class Viz(msgspec.Struct): # , frozen=True):
) )
# the renderer is downsampling we choose # the renderer is downsampling we choose
# to always try and updadte a single (interpolating) # to always try and update a single (interpolating)
# line segment that spans and tries to display # line segment that spans and tries to display
# the las uppx's worth of datums. # the last uppx's worth of datums.
# we only care about the last pixel's # we only care about the last pixel's
# worth of data since that's all the screen # worth of data since that's all the screen
# can represent on the last column where # can represent on the last column where
# the most recent datum is being drawn. # the most recent datum is being drawn.
if self._in_ds or only_last_uppx: if (
self._in_ds
or only_last_uppx
):
dsg = self.ds_graphics or self.graphics dsg = self.ds_graphics or self.graphics
# XXX: pretty sure we don't need this? # XXX: pretty sure we don't need this?
@ -821,12 +821,10 @@ class Viz(msgspec.Struct): # , frozen=True):
# print(f'updating NOT DS curve {self.name}') # print(f'updating NOT DS curve {self.name}')
g.update() g.update()
def curve_width_pxs( def curve_width_pxs(self) -> float:
self,
) -> float:
''' '''
Return the width of the current datums in view in pixel units. Return the width of the current datums in view in pixel units.
''' '''
_, lbar, rbar, _ = self.bars_range() _, lbar, rbar, _ = self.bars_range()
return self.view.mapViewToDevice( return self.view.mapViewToDevice(
@ -1006,8 +1004,6 @@ class Renderer(msgspec.Struct):
if self.fast_path: if self.fast_path:
self.fast_path.clear() self.fast_path.clear()
# profiler('cleared paths due to `should_redraw=True`')
path = pg.functions.arrayToQPath( path = pg.functions.arrayToQPath(
x, x,
y, y,
@ -1051,9 +1047,8 @@ class Renderer(msgspec.Struct):
# only render datums "in view" of the ``ChartView`` # only render datums "in view" of the ``ChartView``
use_vr: bool = True, use_vr: bool = True,
read_from_key: bool = True,
) -> list[QPainterPath]: ) -> tuple[QPainterPath, bool]:
''' '''
Render the current graphics path(s) Render the current graphics path(s)
@ -1086,7 +1081,6 @@ class Renderer(msgspec.Struct):
array_key, array_key,
profiler, profiler,
read_src_from_key=read_from_key,
slice_to_inview=use_vr, slice_to_inview=use_vr,
) )
@ -1244,4 +1238,4 @@ class Renderer(msgspec.Struct):
self.path = path self.path = path
self.fast_path = fast_path self.fast_path = fast_path
return self.path, array, reset return self.path, reset