Make `PlotItemOverlay` add items inwards->out
Before this axes were being stacked from the outside in (for `'right'` and 'bottom'` axes) which is somewhat non-intuitive for an `.append()` operation. As such this change makes a symbol list stack a set of `'right'` axes from left-to-right. Details: - rename `ComposeGridLayout.items` -> `.pitems` - return `(int, list[AxisItem])` pairs from `.insert/append_plotitem()` and the down stream `PlotItemOverlay.add_plotitem()`. - drop `PlotItemOverlay.overlays` and add it back as `@property` around the underlying `.layout.pitems`.pre_viz_calls
							parent
							
								
									9529dd00c6
								
							
						
					
					
						commit
						df9cc0db40
					
				| 
						 | 
					@ -92,11 +92,11 @@ class ComposedGridLayout:
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        item: PlotItem,
 | 
					        pi: PlotItem,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> None:
 | 
					    ) -> None:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.items: list[PlotItem] = []
 | 
					        self.pitems: list[PlotItem] = []
 | 
				
			||||||
        self._pi2axes: dict[  # TODO: use a ``bidict`` here?
 | 
					        self._pi2axes: dict[  # TODO: use a ``bidict`` here?
 | 
				
			||||||
            int,
 | 
					            int,
 | 
				
			||||||
            dict[str, AxisItem],
 | 
					            dict[str, AxisItem],
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,7 @@ class ComposedGridLayout:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            layout.setOrientation(orient)
 | 
					            layout.setOrientation(orient)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.insert_plotitem(0, item)
 | 
					        self.insert_plotitem(0, pi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # insert surrounding linear layouts into the parent pi's layout
 | 
					        # insert surrounding linear layouts into the parent pi's layout
 | 
				
			||||||
        # such that additional axes can be appended arbitrarily without
 | 
					        # such that additional axes can be appended arbitrarily without
 | 
				
			||||||
| 
						 | 
					@ -135,13 +135,14 @@ class ComposedGridLayout:
 | 
				
			||||||
            # TODO: do we need this?
 | 
					            # TODO: do we need this?
 | 
				
			||||||
            # axis should have been removed during insert above
 | 
					            # axis should have been removed during insert above
 | 
				
			||||||
            index = _axes_layout_indices[name]
 | 
					            index = _axes_layout_indices[name]
 | 
				
			||||||
            axis = item.layout.itemAt(*index)
 | 
					            axis = pi.layout.itemAt(*index)
 | 
				
			||||||
            if axis and axis.isVisible():
 | 
					            if axis and axis.isVisible():
 | 
				
			||||||
                assert linlayout.itemAt(0) is axis
 | 
					                assert linlayout.itemAt(0) is axis
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # item.layout.removeItem(axis)
 | 
					            # XXX: see comment in ``.insert_plotitem()``...
 | 
				
			||||||
            item.layout.addItem(linlayout, *index)
 | 
					            # pi.layout.removeItem(axis)
 | 
				
			||||||
            layout = item.layout.itemAt(*index)
 | 
					            pi.layout.addItem(linlayout, *index)
 | 
				
			||||||
 | 
					            layout = pi.layout.itemAt(*index)
 | 
				
			||||||
            assert layout is linlayout
 | 
					            assert layout is linlayout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _register_item(
 | 
					    def _register_item(
 | 
				
			||||||
| 
						 | 
					@ -157,14 +158,14 @@ class ComposedGridLayout:
 | 
				
			||||||
            self._pi2axes.setdefault(name, {})[index] = axis
 | 
					            self._pi2axes.setdefault(name, {})[index] = axis
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # enter plot into list for index tracking
 | 
					        # enter plot into list for index tracking
 | 
				
			||||||
        self.items.insert(index, plotitem)
 | 
					        self.pitems.insert(index, plotitem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def insert_plotitem(
 | 
					    def insert_plotitem(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        index: int,
 | 
					        index: int,
 | 
				
			||||||
        plotitem: PlotItem,
 | 
					        plotitem: PlotItem,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> (int, int):
 | 
					    ) -> tuple[int, list[AxisItem]]:
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        Place item at index by inserting all axes into the grid
 | 
					        Place item at index by inserting all axes into the grid
 | 
				
			||||||
        at list-order appropriate position.
 | 
					        at list-order appropriate position.
 | 
				
			||||||
| 
						 | 
					@ -175,11 +176,14 @@ class ComposedGridLayout:
 | 
				
			||||||
                '`.insert_plotitem()` only supports an index >= 0'
 | 
					                '`.insert_plotitem()` only supports an index >= 0'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inserted_axes: list[AxisItem] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # add plot's axes in sequence to the embedded linear layouts
 | 
					        # add plot's axes in sequence to the embedded linear layouts
 | 
				
			||||||
        # for each "side" thus avoiding graphics collisions.
 | 
					        # for each "side" thus avoiding graphics collisions.
 | 
				
			||||||
        for name, axis_info in plotitem.axes.copy().items():
 | 
					        for name, axis_info in plotitem.axes.copy().items():
 | 
				
			||||||
            linlayout, axes = self.sides[name]
 | 
					            linlayout, axes = self.sides[name]
 | 
				
			||||||
            axis = axis_info['item']
 | 
					            axis = axis_info['item']
 | 
				
			||||||
 | 
					            inserted_axes.append(axis)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if axis in axes:
 | 
					            if axis in axes:
 | 
				
			||||||
                # TODO: re-order using ``.pop()`` ?
 | 
					                # TODO: re-order using ``.pop()`` ?
 | 
				
			||||||
| 
						 | 
					@ -192,19 +196,20 @@ class ComposedGridLayout:
 | 
				
			||||||
            if (
 | 
					            if (
 | 
				
			||||||
                not axis.isVisible()
 | 
					                not axis.isVisible()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # XXX: we never skip moving the axes for the *first*
 | 
					                # XXX: we never skip moving the axes for the *root*
 | 
				
			||||||
                # plotitem inserted (even if not shown) since we need to
 | 
					                # plotitem inserted (even if not shown) since we need to
 | 
				
			||||||
                # move all the hidden axes into linear sub-layouts for
 | 
					                # move all the hidden axes into linear sub-layouts for
 | 
				
			||||||
                # that "central" plot in the overlay. Also if we don't
 | 
					                # that "central" plot in the overlay. Also if we don't
 | 
				
			||||||
                # do it there's weird geomoetry calc offsets that make
 | 
					                # do it there's weird geomoetry calc offsets that make
 | 
				
			||||||
                # view coords slightly off somehow .. smh
 | 
					                # view coords slightly off somehow .. smh
 | 
				
			||||||
                and not len(self.items) == 0
 | 
					                and not len(self.pitems) == 0
 | 
				
			||||||
            ):
 | 
					            ):
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # XXX: Remove old axis? No, turns out we don't need this?
 | 
					            # XXX: Remove old axis?
 | 
				
			||||||
            # DON'T unlink it since we the original ``ViewBox``
 | 
					            # No, turns out we don't need this?
 | 
				
			||||||
            # to still drive it B)
 | 
					            # DON'T UNLINK IT since we need the original ``ViewBox`` to
 | 
				
			||||||
 | 
					            # still drive it with events/handlers B)
 | 
				
			||||||
            # popped = plotitem.removeAxis(name, unlink=False)
 | 
					            # popped = plotitem.removeAxis(name, unlink=False)
 | 
				
			||||||
            # assert axis is popped
 | 
					            # assert axis is popped
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,7 +225,7 @@ class ComposedGridLayout:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._register_item(index, plotitem)
 | 
					        self._register_item(index, plotitem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return index
 | 
					        return (index, inserted_axes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def append_plotitem(
 | 
					    def append_plotitem(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
| 
						 | 
					@ -234,7 +239,7 @@ class ComposedGridLayout:
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        # for left and bottom axes we have to first remove
 | 
					        # for left and bottom axes we have to first remove
 | 
				
			||||||
        # items and re-insert to maintain a list-order.
 | 
					        # items and re-insert to maintain a list-order.
 | 
				
			||||||
        return self.insert_plotitem(len(self.items), item)
 | 
					        return self.insert_plotitem(len(self.pitems), item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_axis(
 | 
					    def get_axis(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
| 
						 | 
					@ -247,7 +252,7 @@ class ComposedGridLayout:
 | 
				
			||||||
        if axis for that name is not shown.
 | 
					        if axis for that name is not shown.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        index = self.items.index(plot)
 | 
					        index = self.pitems.index(plot)
 | 
				
			||||||
        named = self._pi2axes[name]
 | 
					        named = self._pi2axes[name]
 | 
				
			||||||
        return named.get(index)
 | 
					        return named.get(index)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -306,10 +311,13 @@ class PlotItemOverlay:
 | 
				
			||||||
        # events/signals.
 | 
					        # events/signals.
 | 
				
			||||||
        root_plotitem.vb.setZValue(10)
 | 
					        root_plotitem.vb.setZValue(10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.overlays: list[PlotItem] = []
 | 
					 | 
				
			||||||
        self.layout = ComposedGridLayout(root_plotitem)
 | 
					        self.layout = ComposedGridLayout(root_plotitem)
 | 
				
			||||||
        self._relays: dict[str, Signal] = {}
 | 
					        self._relays: dict[str, Signal] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def overlays(self) -> list[PlotItem]:
 | 
				
			||||||
 | 
					        return self.layout.pitems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_plotitem(
 | 
					    def add_plotitem(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        plotitem: PlotItem,
 | 
					        plotitem: PlotItem,
 | 
				
			||||||
| 
						 | 
					@ -324,11 +332,9 @@ class PlotItemOverlay:
 | 
				
			||||||
        # (0, 1),  # link both
 | 
					        # (0, 1),  # link both
 | 
				
			||||||
        link_axes: tuple[int] = (),
 | 
					        link_axes: tuple[int] = (),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> None:
 | 
					    ) -> tuple[int, list[AxisItem]]:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        index = index or len(self.overlays)
 | 
					 | 
				
			||||||
        root = self.root_plotitem
 | 
					        root = self.root_plotitem
 | 
				
			||||||
        self.overlays.insert(index, plotitem)
 | 
					 | 
				
			||||||
        vb: ViewBox = plotitem.vb
 | 
					        vb: ViewBox = plotitem.vb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: some sane way to allow menu event broadcast XD
 | 
					        # TODO: some sane way to allow menu event broadcast XD
 | 
				
			||||||
| 
						 | 
					@ -476,7 +482,10 @@ class PlotItemOverlay:
 | 
				
			||||||
        # ``PlotItem`` dynamically.
 | 
					        # ``PlotItem`` dynamically.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # append-compose into the layout all axes from this plot
 | 
					        # append-compose into the layout all axes from this plot
 | 
				
			||||||
        self.layout.insert_plotitem(index, plotitem)
 | 
					        if index is None:
 | 
				
			||||||
 | 
					            insert_index, axes = self.layout.append_plotitem(plotitem)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            insert_index, axes = self.layout.insert_plotitem(index, plotitem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        plotitem.setGeometry(root.vb.sceneBoundingRect())
 | 
					        plotitem.setGeometry(root.vb.sceneBoundingRect())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -496,6 +505,11 @@ class PlotItemOverlay:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vb.setZValue(100)
 | 
					        vb.setZValue(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            index,
 | 
				
			||||||
 | 
					            axes,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_axis(
 | 
					    def get_axis(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        plot: PlotItem,
 | 
					        plot: PlotItem,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue