Beispiel #1
0
    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
Beispiel #2
0
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())
Beispiel #3
0
    def _check_area(self):
        """
        Check if the current layout added areas cover the entire rectangle.

        Rectangle given by the extreme points for the added areas.
        """
        self._area_rects = []
        height = self._rows + 1
        area_float_rects = []
        delta = 0.0001
        for index, area in enumerate(self._areas):
            # These areas are used with a small delta to ensure if they are
            # next to each other they will not overlap.
            rectf = QRectF()
            rectf.setLeft(area["column"] + delta)
            rectf.setRight(area["column"] + area["col_span"] - delta)
            rectf.setTop(height - area["row"] - delta)
            rectf.setBottom(height - area["row"] - area["row_span"] + delta)
            rectf.index = index
            rectf.plugin_ids = area["plugin_ids"]
            area_float_rects.append(rectf)

            # These areas are used to calculate the actual total area
            rect = QRectF()
            rect.setLeft(area["column"])
            rect.setRight(area["column"] + area["col_span"])
            rect.setTop(height - area["row"])
            rect.setBottom(height - area["row"] - area["row_span"])
            rect.index = index
            rect.plugin_ids = area["plugin_ids"]

            self._area_rects.append(rect)

        # Check if areas are overlapping!
        for rect_1 in area_float_rects:
            for rect_2 in area_float_rects:
                if rect_1.index != rect_2.index:
                    if rect_1.intersects(rect_2):
                        raise SpyderAPIError(
                            "Area with plugins {0} is overlapping area "
                            "with plugins {1}".format(rect_1.plugin_ids,
                                                      rect_2.plugin_ids))

        # Check the total area (using corner points) versus the sum of areas
        total_area = 0
        tops = []
        rights = []
        for index, rect in enumerate(self._area_rects):
            tops.append(rect.top())
            rights.append(rect.right())
            area = abs(rect.width() * rect.height())
            total_area += area
            self._areas[index]["area"] = area

        if total_area != max(rights)*max(tops):
            raise SpyderAPIError(
                "Areas are not covering the entire section!\n"
                "Either an area is missing or col_span/row_span are "
                "not correctly set!"
            )
Beispiel #4
0
class VLine(ChartItem):
    """ Simple vertical line without vertical bounds.

    :param parent: Parent item.
    """
    def __init__(self, parent=None):
        super(VLine, self).__init__(parent)
        self.chartItemFlags = ChartItemFlags.FLAG_NO_AUTO_RANGE

        self._x = 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(0, finfo.min / 2.0, 0, finfo.max)

    @property
    def label(self):
        return self._label

    def setX(self, x, label=None, color=QColor(Qt.red)):
        """ Sets the Vline's x value.

        :param x: abscissa value.
        :param label:
        :param color:
        """
        self._x = x
        self.setPos(QPointF(self._x, 0))

        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.bottom(), rect.top())
        self.b_rect = QRectF(0, b - 10, 0, rect.height() + 20)
        self.prepareGeometryChange()

    def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None):
        # p.setRenderHint(QPainter.Antialiasing)
        p.setPen(self._pen)
        p.setBrush(self._brush)

        p.drawLine(
            QLineF(QPointF(0, self.b_rect.bottom()),
                   QPointF(0, self.b_rect.top())))

        super(VLine, self).paint(p, o, widget)

    def __del__(self):
        _log.debug("Finalize VLine {}".format(self))
Beispiel #5
0
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()))
Beispiel #6
0
    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)
Beispiel #7
0
 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()
Beispiel #8
0
class InteractiveVerticalLine(ChartWidgetItem):
    """ Vertical Line which can be moved by mouse interaction. Usefull for timelines. """

    positionChange = Signal(object)

    def __init__(self, parent=None):
        super(InteractiveVerticalLine, self).__init__(parent)
        self.setFlags(
            QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemSendsGeometryChanges
        )
        self.chartItemFlags = ChartItemFlags.FLAG_NO_AUTO_RANGE
        self.setZValue(1e6)

        self.setAcceptHoverEvents(True)

        self._x = 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))

    @property
    def label(self):
        return self._label

    def setX(self, x, label=None, color=None):
        """ Sets the line's x value.

        :param x: abscissa value.
        :param label:
        :param color:
        """
        if label is not None:
            self._label = label

        if color is not None:
            self._color = color
            self._pen = QPen(QBrush(color), 1.0, Qt.SolidLine)
            self._pen.setCosmetic(True)
        # self._brush = QBrush(QColor(255, 255, 255, 0))

        if self._x != x:
            self._x = x
            self.setPos(QPointF(self._x, 0))

    def visibleRangeChanged(self, rect):
        t = self.parentItem().transform()
        bb = 4 / t.m11()
        _log.debug("{}, {} -> {}".format(rect.bottom(), rect.height(), bb))

        b = min(rect.bottom(), rect.top())
        self.b_rect = QRectF(-bb, b, 2 * bb, rect.height())
        self.prepareGeometryChange()

    def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None):
        # p.setRenderHint(QPainter.Antialiasing)
        p.setPen(self._pen)
        p.setBrush(self._brush)

        p.drawLine(
            QLineF(QPointF(0, self.b_rect.bottom()), QPointF(0, self.b_rect.top()))
        )

        p.setPen(Qt.transparent)
        p.drawRect(self.b_rect)

        if CONFIG.debug:
            p.setPen(Qt.yellow)
            p.drawRect(self.b_rect)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange:
            old_pos = self.pos()
            # value = value #.toPointF()

            e = InteractiveChangeEvent()
            e.position = value
            self.positionChange.emit(e)

            return QPointF(value.x(), old_pos.y())

        return super(InteractiveVerticalLine, self).itemChange(change, value)

    def hoverEnterEvent(self, e):
        super(InteractiveVerticalLine, self).hoverEnterEvent(e)
        self._brush = QBrush(QColor(255, 255, 255, 40))
        self.update()

    def hoverLeaveEvent(self, e):
        super(InteractiveVerticalLine, self).hoverLeaveEvent(e)
        self._brush = QBrush(QColor(255, 255, 255, 0))
        self.update()

    def __del__(self):
        _log.debug("Finalize Interactive vLine {}".format(self))
Beispiel #9
0
    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
Beispiel #10
0
    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)