Use new cached median method in overlay scaling

Massively speeds up scaling transform cycles (duh).

Also includes a draft for an "overlay transform" type/api; obviously
still a WIP 🏄..
multichartz_backup
Tyler Goodlet 2023-01-23 20:25:16 -05:00
parent 0480b5e08a
commit c41bc5dfd4
1 changed files with 52 additions and 7 deletions

View File

@ -42,6 +42,7 @@ import trio
from ..log import get_logger from ..log import get_logger
from .._profile import Profiler from .._profile import Profiler
from .._profile import pg_profile_enabled, ms_slower_then from .._profile import pg_profile_enabled, ms_slower_then
from ..data.types import Struct
# from ._style import _min_points_to_show # from ._style import _min_points_to_show
from ._editors import SelectRect from ._editors import SelectRect
from . import _event from . import _event
@ -343,6 +344,49 @@ async def handle_viewmode_mouse(
view.order_mode.submit_order() view.order_mode.submit_order()
class OverlayT(Struct):
'''
An overlay co-domain range transformer.
Used to translate and apply a range from one y-range
to another based on a returns logarithm:
R(ymn, ymx, yref) = (ymx - yref)/yref
which gives the log-scale multiplier, and
ymx_t = yref * (1 + R)
which gives the inverse to translate to the same value
in the target co-domain.
'''
viz: Viz # viz with largest measured dispersion
mx: float = 0
mn: float = float('inf')
up_swing: float = 0
down_swing: float = 0
disp: float = 0
def loglin_from_range(
self,
y_ref: float, # reference value for dispersion metric
mn: float, # min y in target log-lin range
mx: float, # max y in target log-lin range
offset: float, # y-offset to start log-scaling from
) -> tuple[float, float]:
r_up = (mx - y_ref) / y_ref
r_down = (mn - y_ref) / y_ref
ymn = offset * (1 + r_down)
ymx = offset * (1 + r_up)
return ymn, ymx
class ChartView(ViewBox): class ChartView(ViewBox):
''' '''
Price chart view box with interaction behaviors you'd expect from Price chart view box with interaction behaviors you'd expect from
@ -1034,19 +1078,20 @@ class ChartView(ViewBox):
row_start = arr[read_slc.start - 1] row_start = arr[read_slc.start - 1]
if viz.is_ohlc: if viz.is_ohlc:
y_med = np.median(in_view['close']) y_med = viz.median_from_range(
read_slc.start,
read_slc.stop,
)
y_start = row_start['open'] y_start = row_start['open']
else: else:
y_med = np.median(in_view[viz.name]) y_med = viz.median_from_range(
read_slc.start,
read_slc.stop,
)
y_start = row_start[viz.name] y_start = row_start[viz.name]
profiler(f'{viz.name}@{chart_name} MINOR curve median') profiler(f'{viz.name}@{chart_name} MINOR curve median')
# x_start = ixrng[0]
# print(
# f'{viz.name} ->\n'
# f'(x_start: {x_start}, y_start: {y_start}\n'
# )
start_datums[viz.plot.vb] = ( start_datums[viz.plot.vb] = (
viz, viz,
y_start, y_start,