Only update last datum graphic(s) on clear ticks

When a new tick comes in but no new time step / bar is yet needed (to be
appended) we can simply adjust **only** the last bar datum
lines-graphic(s) to avoid a redraw of the preceding `QPainterPath` on
every tick. Do this by calling `Viz.draw_last()` on the fast and slow
chart and adjusting the guards around calls to `Viz.update_graphics()`
(which *does* update paths) to only enter when there's a `do_px_step`
condition. We can stop calling `main_viz.plot.vb._set_yrange()` on view
treading cases since the range should have already been adjusted by the
clearing-tick processing mxmn updates.

Further this changes,
- the `chart_maxmin()` helper (which we should eventually just get rid
  of) to take bound in `Viz`s for the ohlc and vlm chart instead of the
  chart widget handles.
- extend the guard around hist viz yranging to only enter when not in
  "axis mode" - the same as for the fast viz.
multichartz
Tyler Goodlet 2023-01-17 17:01:00 -05:00
parent 84c48f17e2
commit 5ed4e5c945
1 changed files with 52 additions and 41 deletions

View File

@ -86,9 +86,9 @@ log = get_logger(__name__)
# https://arxiv.org/abs/cs/0610046 # https://arxiv.org/abs/cs/0610046
# https://github.com/lemire/pythonmaxmin # https://github.com/lemire/pythonmaxmin
def chart_maxmin( def chart_maxmin(
chart: ChartPlotWidget, fast_viz: Viz,
fqsn: str, fqsn: str,
vlm_chart: ChartPlotWidget | None = None, vlm_viz: Viz | None = None,
) -> tuple[ ) -> tuple[
@ -102,8 +102,7 @@ def chart_maxmin(
Compute max and min datums "in view" for range limits. Compute max and min datums "in view" for range limits.
''' '''
main_viz = chart.get_viz(chart.name) out = fast_viz.maxmin()
out = main_viz.maxmin()
if out is None: if out is None:
return (0, 0, 0) return (0, 0, 0)
@ -121,10 +120,15 @@ def chart_maxmin(
# TODO: we need to NOT call this to avoid a manual # TODO: we need to NOT call this to avoid a manual
# np.max/min trigger and especially on the vlm_chart # np.max/min trigger and especially on the vlm_chart
# vizs which aren't shown.. like vlm? # vizs which aren't shown.. like vlm?
if vlm_chart: if vlm_viz:
out = vlm_chart.maxmin() out = vlm_viz.maxmin()
if out: if out:
_, mx_vlm_in_view = out (
ixrng,
read_slc,
mxmn,
) = out
mx_vlm_in_view = mxmn[1]
return ( return (
mx, mx,
@ -308,11 +312,13 @@ async def graphics_update_loop(
) )
vlm_chart = vlm_charts[fqsn] vlm_chart = vlm_charts[fqsn]
vlm_viz = vlm_chart._vizs.get('volume') if vlm_chart else None
maxmin = partial( maxmin = partial(
chart_maxmin, chart_maxmin,
fast_chart, fast_viz,
fqsn, fqsn,
vlm_chart, vlm_viz,
) )
( (
last_mx, last_mx,
@ -375,7 +381,7 @@ async def graphics_update_loop(
}) })
if vlm_chart: if vlm_chart:
vlm_pi = vlm_chart._vizs['volume'].plot vlm_pi = vlm_viz.plot
vlm_sticky = vlm_pi.getAxis('right')._stickies['volume'] vlm_sticky = vlm_pi.getAxis('right')._stickies['volume']
ds.vlm_chart = vlm_chart ds.vlm_chart = vlm_chart
ds.vlm_sticky = vlm_sticky ds.vlm_sticky = vlm_sticky
@ -517,38 +523,28 @@ def graphics_update_cycle(
# update ohlc sampled price bars # update ohlc sampled price bars
if ( if (
do_rt_update # do_rt_update
or do_px_step # or do_px_step
(liv and do_px_step)
or trigger_all or trigger_all
): ):
main_viz.update_graphics(array_key=fqsn) main_viz.update_graphics(array_key=fqsn)
hist_viz.draw_last(array_key=fqsn)
else: # don't real-time "shift" the curve to the
main_viz.draw_last( # left unless we get one of the following:
array_key=fqsn, if (
# only_last_uppx=True,
)
# don't real-time "shift" the curve to the
# left unless we get one of the following:
if (
(
should_tread should_tread
and do_px_step or trigger_all
and liv ):
) chart.increment_view(datums=append_diff)
or trigger_all # main_viz.plot.vb._set_yrange(viz=main_viz)
):
chart.increment_view(datums=append_diff)
main_viz.plot.vb._set_yrange(viz=main_viz)
# NOTE: since vlm and ohlc charts are axis linked now we don't # NOTE: since vlm and ohlc charts are axis linked now we don't
# need the double increment request? # need the double increment request?
# if vlm_chart: # if vlm_chart:
# vlm_chart.increment_view(datums=append_diff) # vlm_chart.increment_view(datums=append_diff)
profiler('view incremented') profiler('view incremented')
# iterate frames of ticks-by-type such that we only update graphics # iterate frames of ticks-by-type such that we only update graphics
# using the last update per type where possible. # using the last update per type where possible.
@ -587,9 +583,14 @@ def graphics_update_cycle(
ds.last_price_sticky.update_from_data(*end_ic) ds.last_price_sticky.update_from_data(*end_ic)
ds.hist_last_price_sticky.update_from_data(*end_ic) ds.hist_last_price_sticky.update_from_data(*end_ic)
if wap_in_history: # update vwap overlay line
# update vwap overlay line # if wap_in_history:
chart.get_viz('bar_wap').update_graphics() # chart.get_viz('bar_wap').update_graphics()
# update OHLC chart last bars
# TODO: fix the only last uppx stuff....
main_viz.draw_last() # only_last_uppx=True)
hist_viz.draw_last() # only_last_uppx=True)
# L1 book label-line updates # L1 book label-line updates
if typ in ('last',): if typ in ('last',):
@ -659,7 +660,8 @@ def graphics_update_cycle(
liv liv
and not chart._static_yrange == 'axis' and not chart._static_yrange == 'axis'
): ):
main_vb = chart._vizs[fqsn].plot.vb main_vb = main_viz.plot.vb
if ( if (
main_vb._ic is None main_vb._ic is None
or not main_vb._ic.is_set() or not main_vb._ic.is_set()
@ -693,14 +695,23 @@ def graphics_update_cycle(
ds=ds, ds=ds,
is_1m=True, is_1m=True,
) )
if hist_liv: if (
hist_viz.plot.vb._set_yrange(viz=hist_viz) hist_liv
and not hist_chart._static_yrange == 'axis'
):
hist_viz.plot.vb._set_yrange(
viz=hist_viz,
# yrange=yr, # this is the rt range, not hist.. XD
)
# XXX: update this every draw cycle to ensure y-axis auto-ranging # XXX: update this every draw cycle to ensure y-axis auto-ranging
# only adjusts when the in-view data co-domain actually expands or # only adjusts when the in-view data co-domain actually expands or
# contracts. # contracts.
varz['last_mx'], varz['last_mn'] = mx, mn varz['last_mx'], varz['last_mn'] = mx, mn
# TODO: a similar, only-update-full-path-on-px-step approach for all
# fsp overlays and vlm stuff..
# run synchronous update on all `Viz` overlays # run synchronous update on all `Viz` overlays
for curve_name, viz in chart._vizs.items(): for curve_name, viz in chart._vizs.items():