def colorBarRect(self, rect): """ Calculate the the rectangle for the color bar :param QRectF rect: Bounding rectangle for all components of the scale :return: Rectangle for the color bar """ cr = QRectF(rect) if self.__data.scaleDraw.orientation() == Qt.Horizontal: cr.setLeft(cr.left() + self.__data.borderDist[0]) cr.setWidth(cr.width() - self.__data.borderDist[1] + 1) else: cr.setTop(cr.top() + self.__data.borderDist[0]) cr.setHeight(cr.height() - self.__data.borderDist[1] + 1) sda = self.__data.scaleDraw.alignment() if sda == QwtScaleDraw.LeftScale: cr.setLeft(cr.right() - self.__data.margin - self.__data.colorBar.width) cr.setWidth(self.__data.colorBar.width) elif sda == QwtScaleDraw.RightScale: cr.setLeft(cr.left() + self.__data.margin) cr.setWidth(self.__data.colorBar.width) elif sda == QwtScaleDraw.BottomScale: cr.setTop(cr.top() + self.__data.margin) cr.setHeight(self.__data.colorBar.width) elif sda == QwtScaleDraw.TopScale: cr.setTop(cr.bottom() - self.__data.margin - self.__data.colorBar.width) cr.setHeight(self.__data.colorBar.width) return cr
def qwtDrawStar1Symbols(painter, points, numPoints, symbol): size = symbol.size() painter.setPen(symbol.pen()) sqrt1_2 = np.sqrt(0.5) r = QRectF(0, 0, size.width(), size.height()) for pos in points: r.moveCenter(pos.toPoint()) c = QPointF(r.center()) d1 = r.width() / 2.0 * (1.0 - sqrt1_2) painter.drawLine(r.left() + d1, r.top() + d1, r.right() - d1, r.bottom() - d1) painter.drawLine(r.left() + d1, r.bottom() - d1, r.right() - d1, r.top() + d1) painter.drawLine(c.x(), r.top(), c.x(), r.bottom()) painter.drawLine(r.left(), c.y(), r.right(), c.y())
class HLine(ChartItem): """ Simple horizontal line without horizontal bounds. :param parent: Parent item. """ def __init__(self, parent=None): super(HLine, self).__init__(parent) self.chartItemFlags = ChartItemFlags.FLAG_NO_AUTO_RANGE self._y = None self._label = None self._pen = QPen(QBrush(Qt.green), 1.0, Qt.SolidLine) self._pen.setCosmetic(True) self._brush = QBrush(QColor(255, 255, 255, 0)) finfo = np.finfo(np.float32) self.b_rect = QRectF(finfo.min / 2.0, 0, finfo.max, 0) @property def label(self): return self._label def setY(self, y, label=None, color=QColor(Qt.red)): """ Sets the Hline's y value :param y: Ordinate value :param label: :param color: """ self._y = y self.setPos(QPointF(0, self._y)) if label is not None: self._label = label self._color = color self._pen = QPen(QBrush(color), 1.0, Qt.SolidLine) self._pen.setCosmetic(True) self._brush = QBrush(QColor(255, 255, 255, 0)) def visibleRangeChanged(self, rect): b = min(rect.left(), rect.right()) self.b_rect = QRectF(b - 10, 0, rect.width() + 20, 0) self.prepareGeometryChange() def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None): # p.setRenderHint(QPainter.N) p.setPen(self._pen) p.setBrush(self._brush) p.drawLine( QLineF(QPointF(self.b_rect.left(), 0), QPointF(self.b_rect.right(), 0))) super(HLine, self).paint(p, o, widget) def __del__(self): _log.debug("Finalize HLine {}".format(self))
def qwtDrawSvgSymbols(painter, points, numPoints, renderer, symbol): if renderer is None or not renderer.isValid(): return viewBox = QRectF(renderer.viewBoxF()) if viewBox.isEmpty(): return sz = QSizeF(symbol.size()) if not sz.isValid(): sz = viewBox.size() sx = sz.width() / viewBox.width() sy = sz.height() / viewBox.height() pinPoint = QPointF(viewBox.center()) if symbol.isPinPointEnabled(): pinPoint = symbol.pinPoint() dx = sx * (pinPoint.x() - viewBox.left()) dy = sy * (pinPoint.y() - viewBox.top()) for pos in points: x = pos.x() - dx y = pos.y() - dy renderer.render(painter, QRectF(x, y, sz.width(), sz.height()))
def draw(self, painter): """ Draw the scale :param QPainter painter: Painter """ self.__data.scaleDraw.draw(painter, self.palette()) if (self.__data.colorBar.isEnabled and self.__data.colorBar.width > 0 and self.__data.colorBar.interval.isValid()): self.drawColorBar(painter, self.colorBarRect(self.contentsRect())) r = QRectF(self.contentsRect()) if self.__data.scaleDraw.orientation() == Qt.Horizontal: r.setLeft(r.left() + self.__data.borderDist[0]) r.setWidth(r.width() - self.__data.borderDist[1]) else: r.setTop(r.top() + self.__data.borderDist[0]) r.setHeight(r.height() - self.__data.borderDist[1]) if not self.__data.title.isEmpty(): self.drawTitle(painter, self.__data.scaleDraw.alignment(), r)
def setCornerRects(self, path): pos = QPointF(0.0, 0.0) for i in range(path.elementCount()): el = path.elementAt(i) if el.type in (QPainterPath.MoveToElement, QPainterPath.LineToElement): pos.setX(el.x) pos.setY(el.y) elif el.type == QPainterPath.CurveToElement: r = QRectF(pos, QPointF(el.x, el.y)) self.clipRects += [r.normalized()] pos.setX(el.x) pos.setY(el.y) elif el.type == QPainterPath.CurveToDataElement: if self.clipRects: r = self.clipRects[-1] r.setCoords( min([r.left(), el.x]), min([r.top(), el.y]), max([r.right(), el.x]), max([r.bottom(), el.y]), ) self.clipRects[-1] = r.normalized()
def boundingRect(self): """ Calculate the bounding rectangle for a symbol at position (0,0). :return: Bounding rectangle """ rect = QRectF() pinPointTranslation = False if self.__data.style in (QwtSymbol.Ellipse, QwtSymbol.Rect, QwtSymbol.Hexagon): pw = 0.0 if self.__data.pen.style() != Qt.NoPen: pw = max([self.__data.pen.widthF(), 1.0]) rect.setSize(self.__data.size + QSizeF(pw, pw)) rect.moveCenter(QPointF(0.0, 0.0)) elif self.__data.style in ( QwtSymbol.XCross, QwtSymbol.Diamond, QwtSymbol.Triangle, QwtSymbol.UTriangle, QwtSymbol.DTriangle, QwtSymbol.RTriangle, QwtSymbol.LTriangle, QwtSymbol.Star1, QwtSymbol.Star2, ): pw = 0.0 if self.__data.pen.style() != Qt.NoPen: pw = max([self.__data.pen.widthF(), 1.0]) rect.setSize(QSizeF(self.__data.size) + QSizeF(2 * pw, 2 * pw)) rect.moveCenter(QPointF(0.0, 0.0)) elif self.__data.style == QwtSymbol.Path: if self.__data.path.graphic.isNull(): self.__data.path.graphic = qwtPathGraphic( self.__data.path.path, self.__data.pen, self.__data.brush) rect = qwtScaleBoundingRect(self.__data.path.graphic, self.__data.size) pinPointTranslation = True elif self.__data.style == QwtSymbol.Pixmap: if self.__data.size.isEmpty(): rect.setSize(self.__data.pixmap.pixmap.size()) else: rect.setSize(self.__data.size) pinPointTranslation = True elif self.__data.style == QwtSymbol.Graphic: rect = qwtScaleBoundingRect(self.__data.graphic.graphic, self.__data.size) pinPointTranslation = True elif self.__data.style == QwtSymbol.SvgDocument: if self.__data.svg.renderer is not None: rect = self.__data.svg.renderer.viewBoxF() if self.__data.size.isValid() and not rect.isEmpty(): sz = QSizeF(rect.size()) sx = self.__data.size.width() / sz.width() sy = self.__data.size.height() / sz.height() transform = QTransform() transform.scale(sx, sy) rect = transform.mapRect(rect) pinPointTranslation = True else: rect.setSize(self.__data.size) rect.moveCenter(QPointF(0.0, 0.0)) if pinPointTranslation: pinPoint = QPointF(0.0, 0.0) if self.__data.isPinPointEnabled: pinPoint = rect.center() - self.__data.pinPoint rect.moveCenter(pinPoint) r = QRect() r.setLeft(np.floor(rect.left())) r.setTop(np.floor(rect.top())) r.setRight(np.floor(rect.right())) r.setBottom(np.floor(rect.bottom())) if self.__data.style != QwtSymbol.Pixmap: r.adjust(-1, -1, 1, 1) return r
def activate(self, plot, plotRect, options=0x00): """ Recalculate the geometry of all components. :param qwt.plot.QwtPlot plot: Plot to be layout :param QRectF plotRect: Rectangle where to place the components :param options: Layout options """ self.invalidate() rect = QRectF(plotRect) self.__data.layoutData.init(plot, rect) if (not (options & self.IgnoreLegend) and plot.legend() and not plot.legend().isEmpty()): self.__data.legendRect = self.layoutLegend(options, rect) region = QRegion(rect.toRect()) rect = region.subtracted(QRegion( self.__data.legendRect.toRect())).boundingRect() if self.__data.legendPos == QwtPlot.LeftLegend: rect.setLeft(rect.left() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.RightLegend: rect.setRight(rect.right() - self.__data.spacing) elif self.__data.legendPos == QwtPlot.TopLegend: rect.setTop(rect.top() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.BottomLegend: rect.setBottom(rect.bottom() - self.__data.spacing) # +---+-----------+---+ # | Title | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | Footer | # +---+-----------+---+ # title, footer and axes include text labels. The height of each # label depends on its line breaks, that depend on the width # for the label. A line break in a horizontal text will reduce # the available width for vertical texts and vice versa. # expandLineBreaks finds the height/width for title, footer and axes # including all line breaks. dimTitle, dimFooter, dimAxes = self.expandLineBreaks(options, rect) if dimTitle > 0: self.__data.titleRect.setRect(rect.left(), rect.top(), rect.width(), dimTitle) rect.setTop(self.__data.titleRect.bottom() + self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.titleRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.titleRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) if dimFooter > 0: self.__data.footerRect.setRect(rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter) rect.setBottom(self.__data.footerRect.top() - self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.footerRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.footerRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) self.__data.canvasRect.setRect( rect.x() + dimAxes[QwtPlot.yLeft], rect.y() + dimAxes[QwtPlot.xTop], rect.width() - dimAxes[QwtPlot.yRight] - dimAxes[QwtPlot.yLeft], rect.height() - dimAxes[QwtPlot.xBottom] - dimAxes[QwtPlot.xTop], ) for axis in QwtPlot.AXES: if dimAxes[axis]: dim = dimAxes[axis] scaleRect = self.__data.scaleRect[axis] scaleRect.setRect(*self.__data.canvasRect.getRect()) if axis == QwtPlot.yLeft: scaleRect.setX(self.__data.canvasRect.left() - dim) scaleRect.setWidth(dim) elif axis == QwtPlot.yRight: scaleRect.setX(self.__data.canvasRect.right()) scaleRect.setWidth(dim) elif axis == QwtPlot.xBottom: scaleRect.setY(self.__data.canvasRect.bottom()) scaleRect.setHeight(dim) elif axis == QwtPlot.xTop: scaleRect.setY(self.__data.canvasRect.top() - dim) scaleRect.setHeight(dim) scaleRect = scaleRect.normalized() # +---+-----------+---+ # | <- Axis -> | # +-^-+-----------+-^-+ # | | | | | | # | | | | # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # | | | | # | | | | | | # +-V-+-----------+-V-+ # | <- Axis -> | # +---+-----------+---+ # The ticks of the axes - not the labels above - should # be aligned to the canvas. So we try to use the empty # corners to extend the axes, so that the label texts # left/right of the min/max ticks are moved into them. self.alignScales(options, self.__data.canvasRect, self.__data.scaleRect) if not self.__data.legendRect.isEmpty(): self.__data.legendRect = self.alignLegend(self.__data.canvasRect, self.__data.legendRect)