Facepalm: display state must be linked charts specific
parent
f365e4a465
commit
b81e8dc39c
|
@ -346,6 +346,11 @@ class LinkedSplits(QWidget):
|
||||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||||
self.layout.addWidget(self.splitter)
|
self.layout.addWidget(self.splitter)
|
||||||
|
|
||||||
|
# chart-local graphics state that can be passed to
|
||||||
|
# a ``graphic_update_cycle()`` call by any task wishing to
|
||||||
|
# update the UI for a given "chart instance".
|
||||||
|
self.display_state: dict[str, dict] = {}
|
||||||
|
|
||||||
self._symbol: Symbol = None
|
self._symbol: Symbol = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -109,12 +109,6 @@ def chart_maxmin(
|
||||||
return last_bars_range, mx, max(mn, 0), mx_vlm_in_view
|
return last_bars_range, mx, max(mn, 0), mx_vlm_in_view
|
||||||
|
|
||||||
|
|
||||||
# actor-local graphics state that can be passed
|
|
||||||
# to a ``graphic_update_cycle()`` call by any task
|
|
||||||
# wishing to update the UI.
|
|
||||||
_ux_state: dict[str, Any] = {}
|
|
||||||
|
|
||||||
|
|
||||||
async def graphics_update_loop(
|
async def graphics_update_loop(
|
||||||
|
|
||||||
linked: LinkedSplits,
|
linked: LinkedSplits,
|
||||||
|
@ -153,7 +147,6 @@ async def graphics_update_loop(
|
||||||
|
|
||||||
if vlm_chart:
|
if vlm_chart:
|
||||||
vlm_sticky = vlm_chart._ysticks['volume']
|
vlm_sticky = vlm_chart._ysticks['volume']
|
||||||
# vlm_view = vlm_chart.view
|
|
||||||
|
|
||||||
maxmin = partial(chart_maxmin, chart, vlm_chart)
|
maxmin = partial(chart_maxmin, chart, vlm_chart)
|
||||||
chart.default_view()
|
chart.default_view()
|
||||||
|
@ -216,26 +209,30 @@ async def graphics_update_loop(
|
||||||
|
|
||||||
# async for quotes in iter_drain_quotes():
|
# async for quotes in iter_drain_quotes():
|
||||||
|
|
||||||
_ux_state.update({
|
ds = linked.display_state = {
|
||||||
'quotes': {},
|
'quotes': {},
|
||||||
'linked': linked,
|
'linked': linked,
|
||||||
'maxmin': maxmin,
|
'maxmin': maxmin,
|
||||||
'tick_margin': tick_margin,
|
|
||||||
'ohlcv': ohlcv,
|
'ohlcv': ohlcv,
|
||||||
'chart': chart,
|
'chart': chart,
|
||||||
'last_price_sticky': last_price_sticky,
|
'last_price_sticky': last_price_sticky,
|
||||||
'vlm_chart': vlm_chart,
|
'vlm_chart': vlm_chart,
|
||||||
'i_last': i_last,
|
|
||||||
'last_mx_vlm': last_mx_vlm,
|
|
||||||
'vlm_sticky': vlm_sticky,
|
'vlm_sticky': vlm_sticky,
|
||||||
'l1': l1,
|
'l1': l1,
|
||||||
'last_mx': last_mx,
|
|
||||||
'last_mn': last_mn,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
'vars': {
|
||||||
|
'tick_margin': tick_margin,
|
||||||
|
'i_last': i_last,
|
||||||
|
'last_mx_vlm': last_mx_vlm,
|
||||||
|
'last_mx': last_mx,
|
||||||
|
'last_mn': last_mn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# main loop
|
||||||
async for quotes in stream:
|
async for quotes in stream:
|
||||||
|
|
||||||
_ux_state['quotes'] = quotes
|
ds['quotes'] = quotes
|
||||||
|
|
||||||
quote_period = time.time() - last_quote
|
quote_period = time.time() - last_quote
|
||||||
quote_rate = round(
|
quote_rate = round(
|
||||||
|
@ -258,42 +255,28 @@ async def graphics_update_loop(
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# sync call to update all graphics/UX components.
|
# sync call to update all graphics/UX components.
|
||||||
graphics_update_cycle(**_ux_state)
|
graphics_update_cycle(**ds)
|
||||||
|
|
||||||
|
|
||||||
def trigger_update() -> None:
|
|
||||||
'''
|
|
||||||
Manually trigger a graphics update from global state.
|
|
||||||
|
|
||||||
Generally used from remote actors who wish to trigger a UI refresh.
|
|
||||||
|
|
||||||
'''
|
|
||||||
assert _ux_state is not None, 'graphics engine not initialized?'
|
|
||||||
graphics_update_cycle(**_ux_state)
|
|
||||||
|
|
||||||
|
|
||||||
def graphics_update_cycle(
|
def graphics_update_cycle(
|
||||||
quotes,
|
quotes,
|
||||||
linked,
|
linked,
|
||||||
maxmin,
|
maxmin,
|
||||||
tick_margin,
|
|
||||||
ohlcv,
|
ohlcv,
|
||||||
chart,
|
chart,
|
||||||
last_price_sticky,
|
last_price_sticky,
|
||||||
vlm_chart,
|
vlm_chart,
|
||||||
i_last,
|
|
||||||
last_mx_vlm,
|
|
||||||
vlm_sticky,
|
vlm_sticky,
|
||||||
l1,
|
l1,
|
||||||
|
|
||||||
last_mx,
|
vars: dict[str, Any],
|
||||||
last_mn,
|
|
||||||
|
|
||||||
wap_in_history: bool = False,
|
wap_in_history: bool = False,
|
||||||
# vlm_view,
|
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
tick_margin = vars['tick_margin']
|
||||||
|
|
||||||
for sym, quote in quotes.items():
|
for sym, quote in quotes.items():
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -321,26 +304,26 @@ def graphics_update_cycle(
|
||||||
|
|
||||||
# increment the view position by the sample offset.
|
# increment the view position by the sample offset.
|
||||||
i_step = ohlcv.index
|
i_step = ohlcv.index
|
||||||
i_diff = i_step - i_last
|
i_diff = i_step - vars['i_last']
|
||||||
if i_diff > 0:
|
if i_diff > 0:
|
||||||
chart.increment_view(
|
chart.increment_view(
|
||||||
steps=i_diff,
|
steps=i_diff,
|
||||||
)
|
)
|
||||||
i_last = i_step
|
vars['i_last'] = i_step
|
||||||
|
|
||||||
if vlm_chart:
|
if vlm_chart:
|
||||||
vlm_chart.update_curve_from_array('volume', array)
|
vlm_chart.update_curve_from_array('volume', array)
|
||||||
vlm_sticky.update_from_data(*array[-1][['index', 'volume']])
|
vlm_sticky.update_from_data(*array[-1][['index', 'volume']])
|
||||||
|
|
||||||
if (
|
if (
|
||||||
mx_vlm_in_view != last_mx_vlm or
|
mx_vlm_in_view != vars['last_mx_vlm'] or
|
||||||
mx_vlm_in_view > last_mx_vlm
|
mx_vlm_in_view > vars['last_mx_vlm']
|
||||||
):
|
):
|
||||||
# print(f'mx vlm: {last_mx_vlm} -> {mx_vlm_in_view}')
|
# print(f'mx vlm: {last_mx_vlm} -> {mx_vlm_in_view}')
|
||||||
vlm_chart.view._set_yrange(
|
vlm_chart.view._set_yrange(
|
||||||
yrange=(0, mx_vlm_in_view * 1.375)
|
yrange=(0, mx_vlm_in_view * 1.375)
|
||||||
)
|
)
|
||||||
last_mx_vlm = mx_vlm_in_view
|
vars['last_mx_vlm'] = mx_vlm_in_view
|
||||||
|
|
||||||
for curve_name, flow in vlm_chart._flows.items():
|
for curve_name, flow in vlm_chart._flows.items():
|
||||||
update_fsp_chart(
|
update_fsp_chart(
|
||||||
|
@ -469,7 +452,7 @@ def graphics_update_cycle(
|
||||||
|
|
||||||
# check for y-range re-size
|
# check for y-range re-size
|
||||||
if (
|
if (
|
||||||
(mx > last_mx) or (mn < last_mn)
|
(mx > vars['last_mx']) or (mn < vars['last_mn'])
|
||||||
and not chart._static_yrange == 'axis'
|
and not chart._static_yrange == 'axis'
|
||||||
):
|
):
|
||||||
# print(f'new y range: {(mn, mx)}')
|
# print(f'new y range: {(mn, mx)}')
|
||||||
|
@ -483,7 +466,7 @@ def graphics_update_cycle(
|
||||||
# range_margin=0.1,
|
# range_margin=0.1,
|
||||||
)
|
)
|
||||||
|
|
||||||
last_mx, last_mn = mx, mn
|
vars['last_mx'], vars['last_mn'] = mx, mn
|
||||||
|
|
||||||
# run synchronous update on all derived fsp subplots
|
# run synchronous update on all derived fsp subplots
|
||||||
for name, subchart in linked.subplots.items():
|
for name, subchart in linked.subplots.items():
|
||||||
|
@ -507,9 +490,19 @@ def graphics_update_cycle(
|
||||||
curve_name,
|
curve_name,
|
||||||
array_key=curve_name,
|
array_key=curve_name,
|
||||||
)
|
)
|
||||||
# chart.view._set_yrange()
|
|
||||||
|
|
||||||
# loop end
|
|
||||||
|
def trigger_update(
|
||||||
|
linked: LinkedSplits,
|
||||||
|
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
Manually trigger a graphics update from global state.
|
||||||
|
|
||||||
|
Generally used from remote actors who wish to trigger a UI refresh.
|
||||||
|
|
||||||
|
'''
|
||||||
|
graphics_update_cycle(**linked.display_state)
|
||||||
|
|
||||||
|
|
||||||
async def display_symbol_data(
|
async def display_symbol_data(
|
||||||
|
|
Loading…
Reference in New Issue