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.log_linearized_curve_overlays
							parent
							
								
									c2dd255e8a
								
							
						
					
					
						commit
						fc6ccc306c
					
				|  | @ -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() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue