From 6a5390ce8d0baf3df032b7d4a032f1efd1d7d516 Mon Sep 17 00:00:00 2001 From: Ales Erjavec Date: Mon, 8 Jul 2019 21:35:46 +0200 Subject: [PATCH] owsilhouetteplot: Use sticky header/footer scales --- Orange/widgets/visualize/owsilhouetteplot.py | 39 ++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Orange/widgets/visualize/owsilhouetteplot.py b/Orange/widgets/visualize/owsilhouetteplot.py index 06423c2ecca..c6e55b5682d 100644 --- a/Orange/widgets/visualize/owsilhouetteplot.py +++ b/Orange/widgets/visualize/owsilhouetteplot.py @@ -10,7 +10,7 @@ import sklearn.metrics from AnyQt.QtWidgets import ( - QGraphicsScene, QGraphicsView, QGraphicsWidget, QGraphicsGridLayout, + QGraphicsScene, QGraphicsWidget, QGraphicsGridLayout, QGraphicsItemGroup, QGraphicsSimpleTextItem, QGraphicsRectItem, QSizePolicy, QStyleOptionGraphicsItem, QWidget, QWIDGETSIZE_MAX, ) @@ -24,6 +24,7 @@ import Orange.distance from Orange.widgets import widget, gui, settings +from Orange.widgets.utils.stickygraphicsview import StickyGraphicsView from Orange.widgets.utils import itemmodels from Orange.widgets.utils.annotated_data import (create_annotated_table, ANNOTATED_DATA_SIGNAL_NAME) @@ -159,7 +160,7 @@ def __init__(self): self.controlArea.layout().addWidget(self.buttonsArea) self.scene = QGraphicsScene() - self.view = QGraphicsView(self.scene) + self.view = StickyGraphicsView(self.scene) self.view.setRenderHint(QPainter.Antialiasing, True) self.view.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.mainArea.layout().addWidget(self.view) @@ -374,7 +375,25 @@ def _update_annotations(self): self._silplot.setRowNames(None) def _update_scene_rect(self): - self.scene.setSceneRect(self._silplot.geometry()) + geom = self._silplot.geometry() + self.scene.setSceneRect(geom) + self.view.setSceneRect(geom) + + header = self._silplot.topScaleItem() + footer = self._silplot.bottomScaleItem() + + def extend_horizontal(rect): + # type: (QRectF) -> QRectF + rect = QRectF(rect) + rect.setLeft(geom.left()) + rect.setRight(geom.right()) + return rect + if header is not None: + self.view.setHeaderSceneRect( + extend_horizontal(header.geometry().adjusted(0, 0, 0, 1))) + if footer is not None: + self.view.setFooterSceneRect( + extend_horizontal(footer.geometry().adjusted(0, -1, 0, 0))) def commit(self): """ @@ -466,6 +485,8 @@ def __init__(self, parent=None, **kwargs): self.__pen = QPen(Qt.NoPen) self.__layout = QGraphicsGridLayout() self.__hoveredItem = None + self.__topScale = None # type: Optional[pg.AxisItem] + self.__bottomScale = None # type: Optional[pg.AxisItem] self.setLayout(self.__layout) self.layout().setColumnSpacing(0, 1.) self.setFocusPolicy(Qt.StrongFocus) @@ -592,6 +613,8 @@ def clear(self): child.setParentItem(None) scene.removeItem(child) self.__groups = [] + self.__topScale = None + self.__bottomScale = None def __setup(self): # Setup the subwidgets/groups/layout @@ -613,6 +636,7 @@ def __setup(self): ax = pg.AxisItem(parent=self, orientation="top", maxTickLength=7, pen=axispen) ax.setRange(smin, smax) + self.__topScale = ax self.layout().addItem(ax, 0, 2) for i, group in enumerate(self.__groups): @@ -649,8 +673,17 @@ def __setup(self): ax = pg.AxisItem(parent=self, orientation="bottom", maxTickLength=7, pen=axispen) ax.setRange(smin, smax) + self.__bottomScale = ax self.layout().addItem(ax, len(self.__groups) + 1, 2) + def topScaleItem(self): + # type: () -> Optional[QGraphicsWidget] + return self.__topScale + + def bottomScaleItem(self): + # type: () -> Optional[QGraphicsWidget] + return self.__bottomScale + def __updateTextSizeConstraint(self): # set/update fixed height constraint on the text annotation items so # it matches the silhouette's height