class LegendItemSquare(ColorIndicator): """Legend square item. The legend square item is a small colored square image that can be plugged into the legend in front of the text object. This should only really be used in conjunction with ˙LegendItem˙. Parameters ---------- color : QColor The color of the square. parent : QGraphicsItem See Also -------- LegendItemCircle """ SIZE = QSizeF(12, 12) _size_hint = SIZE def __init__(self, color, parent): super().__init__(parent) height, width = self.SIZE.height(), self.SIZE.width() self.__square = QGraphicsRectItem(0, 0, height, width) self.__square.setBrush(QBrush(color)) self.__square.setPen(QPen(QColor(0, 0, 0, 0))) self.__square.setParentItem(self) self._size_hint = QSizeF(self.__square.boundingRect().size()) def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs): return self._size_hint
class LegendItemSquare(ColorIndicator): """Legend square item. The legend square item is a small colored square image that can be plugged into the legend in front of the text object. This should only really be used in conjunction with ˙LegendItem˙. Parameters ---------- color : QColor The color of the square. parent : QGraphicsItem See Also -------- LegendItemCircle """ SIZE = QSizeF(12, 12) _size_hint = SIZE def __init__(self, color, parent): super().__init__(parent) height, width = self.SIZE.height(), self.SIZE.width() self.__square = QGraphicsRectItem(0, 0, height, width) self.__square.setBrush(QBrush(color)) self.__square.setPen(QPen(QColor(0, 0, 0, 0))) self.__square.setParentItem(self) self._size_hint = QSizeF(self.__square.boundingRect().size()) def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs): return self._size_hint
class LegendGradient(QGraphicsWidget): """Gradient widget. A gradient square bar that can be used to display continuous values. Parameters ---------- palette : iterable[QColor] parent : QGraphicsWidget orientation : Qt.Orientation Notes ----- .. note:: While the gradient does support any number of colors, any more than 3 is not very readable. This should not be a problem, since Orange only implements 2 or 3 colors. """ # Default sizes (assume gradient is vertical by default) GRADIENT_WIDTH = 20 GRADIENT_HEIGHT = 150 _size_hint = QSizeF(GRADIENT_WIDTH, GRADIENT_HEIGHT) def __init__(self, palette, parent, orientation): super().__init__(parent) self.__gradient = QLinearGradient() num_colors = len(palette) for idx, stop in enumerate(palette): self.__gradient.setColorAt(idx * (1. / (num_colors - 1)), stop) # We need to tell the gradient where it's start and stop points are self.__gradient.setStart(QPointF(0, 0)) if orientation == Qt.Vertical: final_stop = QPointF(0, self.GRADIENT_HEIGHT) else: final_stop = QPointF(self.GRADIENT_HEIGHT, 0) self.__gradient.setFinalStop(final_stop) # Get the appropriate rectangle dimensions based on orientation if orientation == Qt.Vertical: width, height = self.GRADIENT_WIDTH, self.GRADIENT_HEIGHT elif orientation == Qt.Horizontal: width, height = self.GRADIENT_HEIGHT, self.GRADIENT_WIDTH self.__rect_item = QGraphicsRectItem(0, 0, width, height, self) self.__rect_item.setPen(QPen(QColor(0, 0, 0, 0))) self.__rect_item.setBrush(QBrush(self.__gradient)) self._size_hint = QSizeF(self.__rect_item.boundingRect().size()) def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs): return self._size_hint
class LegendGradient(QGraphicsWidget): """Gradient widget. A gradient square bar that can be used to display continuous values. Parameters ---------- palette : iterable[QColor] parent : QGraphicsWidget orientation : Qt.Orientation Notes ----- .. note:: While the gradient does support any number of colors, any more than 3 is not very readable. This should not be a problem, since Orange only implements 2 or 3 colors. """ # Default sizes (assume gradient is vertical by default) GRADIENT_WIDTH = 20 GRADIENT_HEIGHT = 150 _size_hint = QSizeF(GRADIENT_WIDTH, GRADIENT_HEIGHT) def __init__(self, palette, parent, orientation): super().__init__(parent) self.__gradient = QLinearGradient() num_colors = len(palette) for idx, stop in enumerate(palette): self.__gradient.setColorAt(idx * (1. / (num_colors - 1)), stop) # We need to tell the gradient where it's start and stop points are self.__gradient.setStart(QPointF(0, 0)) if orientation == Qt.Vertical: final_stop = QPointF(0, self.GRADIENT_HEIGHT) else: final_stop = QPointF(self.GRADIENT_HEIGHT, 0) self.__gradient.setFinalStop(final_stop) # Get the appropriate rectangle dimensions based on orientation if orientation == Qt.Vertical: width, height = self.GRADIENT_WIDTH, self.GRADIENT_HEIGHT elif orientation == Qt.Horizontal: width, height = self.GRADIENT_HEIGHT, self.GRADIENT_WIDTH self.__rect_item = QGraphicsRectItem(0, 0, width, height, self) self.__rect_item.setPen(QPen(QColor(0, 0, 0, 0))) self.__rect_item.setBrush(QBrush(self.__gradient)) self._size_hint = QSizeF(self.__rect_item.boundingRect().size()) def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs): return self._size_hint
class BarItem(QGraphicsWidget): """A single bar in a histogram representing one single target value.""" def __init__(self, width, height, color, parent=None): super().__init__(parent=parent) self.width = width self.height = height self.color = color if not isinstance(self.color, QColor): self.color = QColor(self.color) self.__rect = QGraphicsRectItem(0, 0, self.width, self.height, self) self.__rect.setPen(QPen(Qt.NoPen)) self.__rect.setBrush(QBrush(self.color)) def boundingRect(self): return self.__rect.boundingRect() def sizeHint(self, which, constraint): return self.boundingRect().size() def sizePolicy(self): return QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
class BarItem(QGraphicsWidget): """A single bar in a histogram representing one single target value.""" def __init__(self, width, height, color, parent=None): super().__init__(parent=parent) self.width = width self.height = height self.color = color if not isinstance(self.color, QColor): self.color = QColor(self.color) self.__rect = QGraphicsRectItem(0, 0, self.width, self.height, self) self.__rect.setPen(QPen(Qt.NoPen)) self.__rect.setBrush(QBrush(self.color)) def boundingRect(self): return self.__rect.boundingRect() def sizeHint(self, which, constraint): return self.boundingRect().size() def sizePolicy(self): return QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
class Legend(QGraphicsWidget): BAR_WIDTH = 7 BAR_HEIGHT = 150 FONT_SIZE = 11 def __init__(self, parent): super().__init__(parent) self.__offset = 2 self.__group = QGraphicsItemGroup(self) self._add_bar() self._add_high_label() self._add_low_label() self._add_feature_label() font = self.font() font.setPointSize(self.FONT_SIZE) self.set_font(font) def _add_bar(self): self._bar_item = QGraphicsRectItem() self._bar_item.setPen(QPen(Qt.NoPen)) self._set_bar(self.BAR_HEIGHT) self.__group.addToGroup(self._bar_item) def _add_high_label(self): self.__high_label = item = QGraphicsSimpleTextItem("High") item.setX(self.BAR_WIDTH + self.__offset) item.setY(0) self.__group.addToGroup(item) def _add_low_label(self): self.__low_label = item = QGraphicsSimpleTextItem("Low") item.setX(self.BAR_WIDTH + self.__offset) self.__group.addToGroup(item) def _add_feature_label(self): self.__feature_label = item = QGraphicsSimpleTextItem("Feature value") item.setRotation(-90) item.setX(self.BAR_WIDTH + self.__offset * 2) self.__group.addToGroup(item) def _set_font(self): for label in (self.__high_label, self.__low_label, self.__feature_label): label.setFont(self.font()) bar_height = self._bar_item.boundingRect().height() height = self.__low_label.boundingRect().height() self.__low_label.setY(bar_height - height) width = self.__feature_label.boundingRect().width() self.__feature_label.setY(bar_height / 2 + width / 2) def set_font(self, font: QFont): self.setFont(font) self._set_font() def _set_bar(self, height: int): self._bar_item.setRect(0, 0, self.BAR_WIDTH, height) gradient = QLinearGradient(0, 0, 0, height) gradient.setColorAt(0, QColor(*RGB_HIGH)) gradient.setColorAt(1, QColor(*RGB_LOW)) self._bar_item.setBrush(gradient) def set_bar(self, height: int): self._set_bar(height) self._set_font() def sizeHint(self, *_): width = self.__high_label.boundingRect().width() width += self._bar_item.boundingRect().width() + self.__offset return QSizeF(width, ViolinItem.HEIGHT)