From 5da2f10ff08a77b9c0fe5557e457893f61303337 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Sat, 21 Jan 2023 22:19:33 -0500 Subject: [PATCH] Only set the major curve's range once (per render cycle) Turns out this is a limitation of the `ViewBox.setYRange()` api: you can't call it more then once and expect anything but the first call to be applied without letting a render cycle run. As such, we wait until the end of the log-linear scaling loop to finally apply the major curves y-mx/mn after all minor curves have been evaluated. This also drops all the debug prints (for now) to get a feel for latency in production mode. --- piker/ui/_interaction.py | 159 ++++++++++++++++++++++++++------------- 1 file changed, 106 insertions(+), 53 deletions(-) diff --git a/piker/ui/_interaction.py b/piker/ui/_interaction.py index ab5542c3..cbec5759 100644 --- a/piker/ui/_interaction.py +++ b/piker/ui/_interaction.py @@ -827,11 +827,11 @@ class ChartView(ViewBox): # to get different view modes to operate # correctly! - profiler( - f'set limits {self.name}:\n' - f'ylow: {ylow}\n' - f'yhigh: {yhigh}\n' - ) + # print( + # f'set limits {self.name}:\n' + # f'ylow: {ylow}\n' + # f'yhigh: {yhigh}\n' + # ) self.setYRange( ylow, yhigh, @@ -841,6 +841,7 @@ class ChartView(ViewBox): yMin=ylow, yMax=yhigh, ) + self.update() # LOL: yet anothercucking pg buggg.. # can't use `msg=f'setYRange({ylow}, {yhigh}')` @@ -993,7 +994,9 @@ class ChartView(ViewBox): profiler(f'<{chart_name}>.interact_graphics_cycle({name})') # if no overlays, set lone chart's yrange and short circuit - if len(mxmn_groups) < 2: + if ( + len(mxmn_groups) < 2 + ): viz.plot.vb._set_yrange( yrange=yrange, ) @@ -1024,6 +1027,7 @@ class ChartView(ViewBox): ] = {} max_istart: float = 0 major_viz: Viz = None + # major_in_view: np.ndarray = None for viz_name, out in mxmn_groups.items(): ( @@ -1072,6 +1076,7 @@ class ChartView(ViewBox): mx_disp = disp major_mn = ymn major_mx = ymx + # major_in_view = in_view # compute directional (up/down) y-range % swing/dispersion y_ref = y_med @@ -1081,18 +1086,18 @@ class ChartView(ViewBox): mx_up_rng = max(mx_up_rng, up_rng) mn_down_rng = min(mn_down_rng, down_rng) - print( - f'{viz.name}@{chart_name} group mxmn calc\n' - '--------------------\n' - f'y_start: {y_start}\n' - f'ymn: {ymn}\n' - f'ymx: {ymx}\n' - f'mx_disp: {mx_disp}\n' - f'up %: {up_rng * 100}\n' - f'down %: {down_rng * 100}\n' - f'mx up %: {mx_up_rng * 100}\n' - f'mn down %: {mn_down_rng * 100}\n' - ) + # print( + # f'{viz.name}@{chart_name} group mxmn calc\n' + # '--------------------\n' + # f'y_start: {y_start}\n' + # f'ymn: {ymn}\n' + # f'ymx: {ymx}\n' + # f'mx_disp: {mx_disp}\n' + # f'up %: {up_rng * 100}\n' + # f'down %: {down_rng * 100}\n' + # f'mx up %: {mx_up_rng * 100}\n' + # f'mn down %: {mn_down_rng * 100}\n' + # ) for ( view, @@ -1113,6 +1118,14 @@ class ChartView(ViewBox): if viz is major_viz: ymn = y_min ymx = y_max + # print( + # f'{view.name} MAJOR mxmn\n' + # '--------------------\n' + # f'scaled ymn: {ymn}\n' + # f'scaled ymx: {ymx}\n' + # f'scaled mx_disp: {mx_disp}\n' + # ) + continue else: key = 'open' if viz.is_ohlc else viz.name @@ -1129,11 +1142,11 @@ class ChartView(ViewBox): # y-range based on the major curves y-range. # get intersection point y-values for both curves - # abs_i_start = max_istart - mshm = major_viz.shm + minor_i_start = minor_in_view[0]['index'] - major_i_start = mshm.array['index'][0], + major_i_start = mshm.array['index'][0] + abs_i_start = max( minor_i_start, major_i_start, @@ -1169,53 +1182,75 @@ class ChartView(ViewBox): # is side (up/down) specific. new_maj_mxmn: None | tuple[float, float] = None if y_max > ymx: + y_ref = y_minor_intersect r_up_minor = (y_max - y_ref) / y_ref - new_maj_ymx = y_maj_intersect * (1 + r_up_minor) + + # y_maj_ref = max( + # major_in_view[0][key], + # y_maj_intersect, + # ) + y_maj_ref = y_maj_intersect + new_maj_ymx = y_maj_ref * (1 + r_up_minor) new_maj_mxmn = (major_mn, new_maj_ymx) - print( - f'{view.name} OUT OF RANGE:\n' - '--------------------\n' - f'y_max:{y_max} > ymx:{ymx}\n' - f'RESCALE MAJOR {major_viz.name}:\n' - f'{new_maj_mxmn}\n' - ) + # print( + # f'{view.name} OUT OF RANGE:\n' + # '--------------------\n' + # f'y_max:{y_max} > ymx:{ymx}\n' + # ) ymx = y_max if y_min < ymn: + y_ref = y_minor_intersect r_down_minor = (y_min - y_ref) / y_ref - new_maj_ymn = y_maj_intersect * (1 + r_down_minor) + + # y_maj_ref = min( + # major_in_view[0][key], + # y_maj_intersect, + # ) + y_maj_ref = y_maj_intersect + new_maj_ymn = y_maj_ref * (1 + r_down_minor) new_maj_mxmn = ( new_maj_ymn, new_maj_mxmn[1] if new_maj_mxmn else major_mx ) - print( - f'{view.name} OUT OF RANGE:\n' - '--------------------\n' - f'y_min:{y_min} < ymn:{ymn}\n' - f'RESCALE MAJOR {major_viz.name}:\n' - f'{new_maj_mxmn}\n' - ) + # print( + # f'{view.name} OUT OF RANGE:\n' + # '--------------------\n' + # f'y_min:{y_min} < ymn:{ymn}\n' + # ) ymn = y_min - if new_maj_mxmn: - major_mx, major_mn = new_maj_mxmn - major_viz.plot.vb._set_yrange( - yrange=new_maj_mxmn, - # range_margin=None, - ) + # now scale opposite side to compensate + # y_ref = y_major_intersect + # r_down_minor = (major_ - y_ref) / y_ref - print( - f'{view.name} APPLY group mxmn\n' - '--------------------\n' - f'minor_y_start: {minor_y_start}\n' - f'mn_down_rng: {mn_down_rng * 100}\n' - f'mx_up_rng: {mx_up_rng * 100}\n' - f'scaled ymn: {ymn}\n' - f'scaled ymx: {ymx}\n' - f'scaled mx_disp: {mx_disp}\n' - ) + if new_maj_mxmn: + # print( + # f'RESCALE MAJOR {major_viz.name}:\n' + # f'previous: {(major_mn, major_mx)}\n' + # f'new: {new_maj_mxmn}\n' + # ) + # major_viz.plot.vb._set_yrange( + # yrange=new_maj_mxmn, + # # range_margin=None, + # ) + major_mn, major_mx = new_maj_mxmn + # vrs = major_viz.plot.vb.viewRange() + # if vrs[1][0] > new_maj_mxmn[0]: + # breakpoint() + + # print( + # f'{view.name} APPLY group mxmn\n' + # '--------------------\n' + # f'minor_y_start: {minor_y_start}\n' + # f'mn_down_rng: {mn_down_rng * 100}\n' + # f'mx_up_rng: {mx_up_rng * 100}\n' + # f'scaled ymn: {ymn}\n' + # f'scaled ymx: {ymx}\n' + # f'scaled mx_disp: {mx_disp}\n' + # ) if ( math.isinf(ymx) @@ -1227,4 +1262,22 @@ class ChartView(ViewBox): yrange=(ymn, ymx), ) + # NOTE XXX: we have to set the major curve's range once (and + # only once) here since we're doing this entire routine + # inside of a single render cycle (and apparently calling + # `ViewBox.setYRange()` multiple times within one only takes + # the first call as serious...) XD + # print( + # f'Scale MAJOR {major_viz.name}:\n' + # f'previous: {(major_mn, major_mx)}\n' + # f'new: {new_maj_mxmn}\n' + # ) + major_viz.plot.vb._set_yrange( + yrange=(major_mn, major_mx), + ) + # major_mx, major_mn = new_maj_mxmn + # vrs = major_viz.plot.vb.viewRange() + # if vrs[1][0] > major_mn: + # breakpoint() + profiler.finish()