Add first-draft `PlotItemOverlay.group_maxmin()`
Computes the maxmin values for each underlying plot's in-view range as well as the max up/down swing (in percentage terms) from the plot with most dispersion and returns a all these values plus a `dict` of plots to their ranges as part of output.storage_cli
							parent
							
								
									4c838474be
								
							
						
					
					
						commit
						5ce4337d42
					
				| 
						 | 
					@ -22,7 +22,6 @@ from collections import defaultdict
 | 
				
			||||||
from functools import partial
 | 
					from functools import partial
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
    Callable,
 | 
					    Callable,
 | 
				
			||||||
    Optional,
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyqtgraph.graphicsItems.AxisItem import AxisItem
 | 
					from pyqtgraph.graphicsItems.AxisItem import AxisItem
 | 
				
			||||||
| 
						 | 
					@ -246,7 +245,7 @@ class ComposedGridLayout:
 | 
				
			||||||
        plot: PlotItem,
 | 
					        plot: PlotItem,
 | 
				
			||||||
        name: str,
 | 
					        name: str,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> Optional[AxisItem]:
 | 
					    ) -> AxisItem | None:
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        Retrieve the named axis for overlayed ``plot`` or ``None``
 | 
					        Retrieve the named axis for overlayed ``plot`` or ``None``
 | 
				
			||||||
        if axis for that name is not shown.
 | 
					        if axis for that name is not shown.
 | 
				
			||||||
| 
						 | 
					@ -321,7 +320,7 @@ class PlotItemOverlay:
 | 
				
			||||||
    def add_plotitem(
 | 
					    def add_plotitem(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        plotitem: PlotItem,
 | 
					        plotitem: PlotItem,
 | 
				
			||||||
        index: Optional[int] = None,
 | 
					        index: int | None = None,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # event/signal names which will be broadcasted to all added
 | 
					        # event/signal names which will be broadcasted to all added
 | 
				
			||||||
        # (relayee) ``PlotItem``s (eg. ``ViewBox.mouseDragEvent``).
 | 
					        # (relayee) ``PlotItem``s (eg. ``ViewBox.mouseDragEvent``).
 | 
				
			||||||
| 
						 | 
					@ -376,7 +375,7 @@ class PlotItemOverlay:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        # TODO: drop this viewbox specific input and
 | 
					                        # TODO: drop this viewbox specific input and
 | 
				
			||||||
                        # allow a predicate to be passed in by user.
 | 
					                        # allow a predicate to be passed in by user.
 | 
				
			||||||
                        axis: 'Optional[int]' = None,
 | 
					                        axis: int | None = None,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        *,
 | 
					                        *,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -578,3 +577,93 @@ class PlotItemOverlay:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #     '''
 | 
					    #     '''
 | 
				
			||||||
    #     ...
 | 
					    #     ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def group_maxmin(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        focus_around: str | None = None,
 | 
				
			||||||
 | 
					        force_min: float | None = None,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ) -> tuple[
 | 
				
			||||||
 | 
					        float,  # mn
 | 
				
			||||||
 | 
					        float,  # mx
 | 
				
			||||||
 | 
					        float,  # max range in % terms of highest sigma plot's y-range
 | 
				
			||||||
 | 
					        PlotItem,  # front/selected plot
 | 
				
			||||||
 | 
					    ]:
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        Overlay "group" maxmin sorting.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Assumes all named flows are in the same co-domain and thus can
 | 
				
			||||||
 | 
					        be sorted as one set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Iterates all the named flows and calls the chart api to find
 | 
				
			||||||
 | 
					        their range values and return.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TODO: really we should probably have a more built-in API for
 | 
				
			||||||
 | 
					        this?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        # TODO:
 | 
				
			||||||
 | 
					        # - use this in the ``.ui._fsp`` mutli-maxmin stuff
 | 
				
			||||||
 | 
					        # -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # force 0 to always be in view
 | 
				
			||||||
 | 
					        group_mx: float = 0
 | 
				
			||||||
 | 
					        group_mn: float = 0
 | 
				
			||||||
 | 
					        mx_up_rng: float = 0
 | 
				
			||||||
 | 
					        mn_down_rng: float = 0
 | 
				
			||||||
 | 
					        pis2ranges: dict[
 | 
				
			||||||
 | 
					            PlotItem,
 | 
				
			||||||
 | 
					            tuple[float, float],
 | 
				
			||||||
 | 
					        ] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for pi in self.overlays:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # TODO: can we remove this from the widget
 | 
				
			||||||
 | 
					            # and place somewhere more related to UX/Viz?
 | 
				
			||||||
 | 
					            # name = pi.name
 | 
				
			||||||
 | 
					            # chartw = pi.chart_widget
 | 
				
			||||||
 | 
					            viz = pi.viz
 | 
				
			||||||
 | 
					            # viz = chartw._vizs[name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            out = viz.maxmin()
 | 
				
			||||||
 | 
					            if out is None:
 | 
				
			||||||
 | 
					                return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                (x_start, x_stop),
 | 
				
			||||||
 | 
					                read_slc,
 | 
				
			||||||
 | 
					                (ymn, ymx),
 | 
				
			||||||
 | 
					            ) = out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            arr = viz.shm.array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            y_start = arr[read_slc.start - 1]
 | 
				
			||||||
 | 
					            y_stop = arr[read_slc.stop - 1]
 | 
				
			||||||
 | 
					            if viz.is_ohlc:
 | 
				
			||||||
 | 
					                y_start = y_start['open']
 | 
				
			||||||
 | 
					                y_stop = y_stop['close']
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                y_start = y_start[viz.name]
 | 
				
			||||||
 | 
					                y_stop = y_stop[viz.name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # update max for group
 | 
				
			||||||
 | 
					            up_rng = (ymx - y_start) / y_start
 | 
				
			||||||
 | 
					            down_rng = (y_stop - ymn) / y_stop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # compute directional (up/down) y-range % swing/dispersion
 | 
				
			||||||
 | 
					            mx_up_rng = max(mx_up_rng, up_rng)
 | 
				
			||||||
 | 
					            mn_down_rng = min(mn_down_rng, down_rng)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            pis2ranges[pi] = (ymn, ymx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            group_mx = max(group_mx, ymx)
 | 
				
			||||||
 | 
					            if force_min is None:
 | 
				
			||||||
 | 
					                group_mn = min(group_mn, ymn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					           group_mn if force_min is None else force_min,
 | 
				
			||||||
 | 
					           group_mx,
 | 
				
			||||||
 | 
					           mn_down_rng,
 | 
				
			||||||
 | 
					           mx_up_rng,
 | 
				
			||||||
 | 
					           pis2ranges,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue