Esempio n. 1
0
def _errorBarsDiamondFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter,
                            s, painter, clip):
    """Draw diamond filled region inside error bars."""
    if None not in (xmin, xmax, ymin, ymax):
        if not s.FillBelow.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip, xmin, yplotter, xplotter,
                                        ymin, xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillBelow, path, ignorehide=True)

        if not s.FillAbove.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip, xmin, yplotter, xplotter,
                                        ymax, xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillAbove, path, ignorehide=True)
Esempio n. 2
0
 def setClip(self, painter, bounds):
     '''Set clipping for graph.'''
     p = qt4.QPainterPath()
     p.addEllipse(
         qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                    qt4.QPointF(bounds[2], bounds[3])))
     painter.setClipPath(p)
Esempio n. 3
0
    def draw(self, parentposn, painthelper, outerbounds=None):
        '''Update the margins before drawing.'''

        s = self.settings

        margins = (s.get('leftMargin').convert(painthelper),
                   s.get('topMargin').convert(painthelper),
                   s.get('rightMargin').convert(painthelper),
                   s.get('bottomMargin').convert(painthelper))

        bounds = self.computeBounds(parentposn, painthelper, margins=margins)
        maxbounds = self.computeBounds(parentposn, painthelper)

        # controls for adjusting graph margins
        painter = painthelper.painter(self, bounds)
        painthelper.setControlGraph(self, [
            controlgraph.ControlMarginBox(self, bounds, maxbounds, painthelper)
        ])

        # do no painting if hidden
        if s.hide:
            return bounds

        # set graph rectangle attributes
        path = qt4.QPainterPath()
        path.addRect(
            qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                       qt4.QPointF(bounds[2], bounds[3])))
        utils.brushExtFillPath(painter,
                               s.Background,
                               path,
                               stroke=s.Border.makeQPenWHide(painter))

        # do normal drawing of children
        # iterate over children in reverse order
        for c in reversed(self.children):
            c.draw(bounds, painthelper, outerbounds=outerbounds)

        # now need to find axes which aren't children, and draw those again
        axestodraw = set()
        childrennames = set()
        for c in self.children:
            childrennames.add(c.name)
            try:
                for axis in c.getAxesNames():
                    axestodraw.add(axis)
            except AttributeError:
                pass

        axestodraw = axestodraw - childrennames
        if axestodraw:
            # now redraw all these axes if they aren't children of us
            axeswidgets = self.getAxes(axestodraw)
            for w in axeswidgets:
                if w is not None:
                    w.draw(bounds, painthelper, outerbounds=outerbounds)

        return bounds
Esempio n. 4
0
    def drawShape(self, painter, rect):
        s = self.settings
        path = qt4.QPainterPath()
        if s.rounding == 0:
            path.addRect(rect)
        else:
            path.addRoundedRect(rect, s.rounding, s.rounding)

        utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Esempio n. 5
0
    def areaDrawStacked(self, painter, posns, maxwidth, dsvals, axes,
                        widgetposn, clip):
        """Draw a stacked area plot"""

        s = self.settings

        # get axis which values are plotted along
        ishorz = s.direction == 'horizontal'
        vaxis = axes[not ishorz]

        # compute stacked coordinates
        stackedvals, stackedcoords = self.calcStackedPoints(
            dsvals, vaxis, widgetposn)
        # coordinates of origin
        zerocoords = vaxis.dataToPlotterCoords(widgetposn,
                                               N.zeros(posns.shape))

        # draw areas (reverse order, so edges are plotted correctly)
        for dsnum, coords in izip(xrange(len(stackedcoords) - 1, -1, -1),
                                  stackedcoords[::-1]):

            # add points at end to make polygon
            p1 = N.hstack([[zerocoords[0]], coords, [zerocoords[-1]]])
            p2 = N.hstack([[posns[0]], posns, [posns[-1]]])

            # construct polygon on path, clipped
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, p1, p2)
            else:
                utils.addNumpyToPolygonF(poly, p2, p1)
            clippoly = qt4.QPolygonF()
            utils.polygonClip(poly, clip, clippoly)
            path = qt4.QPainterPath()
            path.addPolygon(clippoly)
            path.closeSubpath()

            # actually draw polygon
            brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
            utils.brushExtFillPath(painter, brush, path)

            # now draw lines
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, coords, posns)
            else:
                utils.addNumpyToPolygonF(poly, posns, coords)

            pen = s.BarLine.get('lines').makePen(painter, dsnum)
            painter.setPen(pen)
            utils.plotClippedPolyline(painter, clip, poly)

        # draw error bars
        barwidth = maxwidth * s.barfill
        for barval, dsval in izip(stackedvals, dsvals):
            self.drawErrorBars(painter, posns, barwidth, barval, dsval, axes,
                               widgetposn)
Esempio n. 6
0
def brushExtFillPolygon(painter,
                        extbrush,
                        cliprect,
                        polygon,
                        ignorehide=False):
    """Fill a polygon with an extended brush."""
    clipped = qt4.QPolygonF()
    polygonClip(polygon, cliprect, clipped)
    path = qt4.QPainterPath()
    path.addPolygon(clipped)
    brushExtFillPath(painter, extbrush, path, ignorehide=ignorehide)
Esempio n. 7
0
    def __init__(self, parent=None):
        path = qt4.QPainterPath()
        path.addRect(-4, -4, 8, 8)
        path.addRect(-5, -5, 10, 10)
        path.moveTo(-8, 0)
        path.lineTo(8, 0)
        path.moveTo(0, -8)
        path.lineTo(0, 8)

        qt4.QGraphicsPathItem.__init__(self, path, parent)
        self.setBrush(qt4.QBrush(qt4.Qt.black))
        self.setFlags(self.flags() | qt4.QGraphicsItem.ItemIsFocusable)
Esempio n. 8
0
    def drawTextItem(self, pt, textitem):
        """Convert text to a path and draw it.
        """
        # print "text", pt, textitem.text()
        path = qt4.QPainterPath()
        path.addText(pt, textitem.font(), textitem.text())

        fill = self.emf.CreateSolidBrush(self.pencolor)
        self.emf.SelectObject(fill)
        self._createPath(path)
        self.emf.FillPath()
        self.emf.SelectObject(self.brush)
        self.emf.DeleteObject(fill)
Esempio n. 9
0
    def _getBezierLine(self, poly):
        """Try to draw a bezier line connecting the points."""

        npts = qtloops.bezier_fit_cubic_multi(poly, 0.1, len(poly) + 1)
        i = 0
        path = qt4.QPainterPath()
        lastpt = qt4.QPointF(-999999, -999999)
        while i < len(npts):
            if lastpt != npts[i]:
                path.moveTo(npts[i])
            path.cubicTo(npts[i + 1], npts[i + 2], npts[i + 3])
            lastpt = npts[i + 3]
            i += 4
        return path
Esempio n. 10
0
    def _drawBezierLine(self, painter, xvals, yvals, posn, xdata, ydata):
        """Handle bezier lines and fills."""

        pts = self._getLinePoints(xvals, yvals, posn, xdata, ydata)
        if len(pts) < 2:
            return
        path = self._getBezierLine(pts)
        s = self.settings

        if not s.FillBelow.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[3])
            temppath.lineTo(pts[0].x(), posn[3])
            utils.brushExtFillPath(painter, s.FillBelow, temppath)

        if not s.FillAbove.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[1])
            temppath.lineTo(pts[0].x(), posn[1])
            utils.brushExtFillPath(painter, s.FillAbove, temppath)

        if not s.PlotLine.hide:
            painter.strokePath(path, s.PlotLine.makeQPen(painter))
Esempio n. 11
0
 def updateState(self, state):
     """Examine what has changed in state and call apropriate function."""
     ss = state.state()
     if ss & qt4.QPaintEngine.DirtyPen:
         self._updatePen(state.pen())
     if ss & qt4.QPaintEngine.DirtyBrush:
         self._updateBrush(state.brush())
     if ss & qt4.QPaintEngine.DirtyClipPath:
         self._updateClipPath(state.clipPath(), state.clipOperation())
     if ss & qt4.QPaintEngine.DirtyClipRegion:
         path = qt4.QPainterPath()
         path.addRegion(state.clipRegion())
         self._updateClipPath(path, state.clipOperation())
     if ss & qt4.QPaintEngine.DirtyTransform:
         self._updateTransform(state.matrix())
Esempio n. 12
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings

        xw, yw = bounds[2]-bounds[0], bounds[3]-bounds[1]

        d60 = 60./180.*math.pi
        ang = math.atan2(yw, xw/2.)
        if ang > d60:
            # taller than wider
            widthh = xw/2
            height = math.tan(d60) * widthh
        else:
            # wider than taller
            height = yw
            widthh = height / math.tan(d60)

        # box for equilateral triangle
        self._box = ( (bounds[2]+bounds[0])/2 - widthh,
                      (bounds[1]+bounds[3])/2 - height/2,
                      (bounds[2]+bounds[0])/2 + widthh,
                      (bounds[1]+bounds[3])/2 + height/2 )
        self._width = widthh*2
        self._height = height

        # triangle shaped polygon for graph
        self._tripoly = p = qt4.QPolygonF()
        p.append( qt4.QPointF(self._box[0], self._box[3]) )
        p.append( qt4.QPointF(self._box[0]+widthh, self._box[1]) )
        p.append( qt4.QPointF(self._box[2], self._box[3]) )

        path = qt4.QPainterPath()
        path.addPolygon(p)
        path.closeSubpath()
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))

        # work out origins and size
        self._size = max(min(s.fracsize, 1.), 0.)

        # make sure we don't go past the ends of the allowed range
        # value of origin of left axis at top
        self._orgleft = min(s.originleft, 1.-self._size)
        # value of origin of bottom axis at left
        self._orgbot = min(s.originbottom, 1.-self._size)
        # origin of right axis at bottom
        self._orgright = 1. - self._orgleft - (self._orgbot + self._size)
Esempio n. 13
0
def _errorBarsDiamond(style, xmin, xmax, ymin, ymax, xplotter, yplotter, s,
                      painter, clip):
    """Draw diamond around error region."""
    if None not in (xmin, xmax, ymin, ymax):

        # expand clip by pen width (urgh)
        pw = painter.pen().widthF() * 2
        clip = qt4.QRectF(qt4.QPointF(clip.left() - pw,
                                      clip.top() - pw),
                          qt4.QPointF(clip.right() + pw,
                                      clip.bottom() + pw))

        path = qt4.QPainterPath()
        utils.addNumpyPolygonToPath(path, clip, xmin, yplotter, xplotter, ymax,
                                    xmax, yplotter, xplotter, ymin)
        painter.setBrush(qt4.QBrush())
        painter.drawPath(path)
Esempio n. 14
0
    def drawFillPts(self, painter, extfill, cliprect, ptsx, ptsy):
        '''Draw points for plotting a fill.'''
        pts = qt4.QPolygonF()
        utils.addNumpyToPolygonF(pts, ptsx, ptsy)

        filltype = extfill.filltype
        if filltype == 'center':
            pts.append(qt4.QPointF(self._xc, self._yc))
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
        elif filltype == 'outside':
            pp = qt4.QPainterPath()
            pp.moveTo(self._xc, self._yc)
            pp.arcTo(cliprect, 0, 360)
            pp.addPolygon(pts)
            utils.brushExtFillPath(painter, extfill, pp)
        elif filltype == 'polygon':
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
Esempio n. 15
0
    def updateState(self, state):
        """Examine what has changed in state and call apropriate function."""
        ss = state.state()

        # state is a list of transform, stroke/fill and clip states
        statevec = list(self.oldstate)
        if ss & qt4.QPaintEngine.DirtyTransform:
            self.matrix = state.matrix()
            statevec[0] = self.transformState()
        if ss & qt4.QPaintEngine.DirtyPen:
            self.pen = state.pen()
            statevec[1] = self.strokeFillState()
        if ss & qt4.QPaintEngine.DirtyBrush:
            self.brush = state.brush()
            statevec[1] = self.strokeFillState()
        if ss & qt4.QPaintEngine.DirtyClipPath:
            self._updateClipPath(state.clipPath(), state.clipOperation())
            statevec[2] = self.clipState()
        if ss & qt4.QPaintEngine.DirtyClipRegion:
            path = qt4.QPainterPath()
            path.addRegion(state.clipRegion())
            self._updateClipPath(path, state.clipOperation())
            statevec[2] = self.clipState()

        # work out which state differs first
        pop = 0
        for i in xrange(2, -1, -1):
            if statevec[i] != self.oldstate[i]:
                pop = i + 1
                break

        # go back up the tree the required number of times
        for i in xrange(pop):
            if self.oldstate[i]:
                self.celement = self.celement.parent

        # create new elements for changed states
        for i in xrange(pop - 1, -1, -1):
            if statevec[i]:
                self.celement = SVGElement(self.celement, 'g',
                                           ' '.join(statevec[i]))

        self.oldstate = statevec
Esempio n. 16
0
    def plotBars(self, painter, s, dsnum, clip, corners):
        """Plot a set of boxes."""
        # get style
        brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
        pen = s.BarLine.get('lines').makePen(painter, dsnum)
        lw = pen.widthF() * 2

        # make clip box bigger to avoid lines showing
        extclip = qt4.QRectF(
            qt4.QPointF(clip.left() - lw,
                        clip.top() - lw),
            qt4.QPointF(clip.right() + lw,
                        clip.bottom() + lw))

        # plot bars
        path = qt4.QPainterPath()
        utils.addNumpyPolygonToPath(path, extclip, corners[0], corners[1],
                                    corners[2], corners[1], corners[2],
                                    corners[3], corners[0], corners[3])
        utils.brushExtFillPath(painter, brush, path, stroke=pen)
Esempio n. 17
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings
        if s.maxradius == 'Auto':
            self._maxradius = datarange[1]
        else:
            self._maxradius = s.maxradius

        self._xscale = (bounds[2] - bounds[0]) * 0.5
        self._yscale = (bounds[3] - bounds[1]) * 0.5
        self._xc = 0.5 * (bounds[0] + bounds[2])
        self._yc = 0.5 * (bounds[3] + bounds[1])

        path = qt4.QPainterPath()
        path.addEllipse(
            qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                       qt4.QPointF(bounds[2], bounds[3])))
        utils.brushExtFillPath(painter,
                               s.Background,
                               path,
                               stroke=s.Border.makeQPenWHide(painter))
Esempio n. 18
0
    def drawTextItem(self, pt, textitem):
        """Convert text to a path and draw it.
        """

        if self.writetextastext:
            # size
            f = textitem.font()
            if f.pixelSize() > 0:
                size = f.pixelSize() * scale
            else:
                size = f.pointSizeF() * scale * dpi / inch_pt

            attrb = [
                'x="%s"' % fltStr(pt.x() * scale),
                'y="%s"' % fltStr(pt.y() * scale),
                'textLength="%s"' % fltStr(textitem.width() * scale),
            ]

            grp = SVGElement(
                self.celement, 'g',
                'stroke="none" fill="%s" fill-opacity="%.3g" '
                'font-family="%s" font-size="%s"' %
                (self.pen.color().name(), self.pen.color().alphaF(),
                 escapeXML(textitem.font().family()), size))

            text = escapeXML(unicode(textitem.text()))

            # write as an SVG text element
            SVGElement(grp, 'text', ' '.join(attrb), text=text.encode('utf-8'))

        else:
            # convert to a path
            path = qt4.QPainterPath()
            path.addText(pt, textitem.font(), textitem.text())
            p = createPath(path)
            SVGElement(
                self.celement, 'path',
                'd="%s" fill="%s" stroke="none" fill-opacity="%.3g"' %
                (p, self.pen.color().name(), self.pen.color().alphaF()))
Esempio n. 19
0
    def _fillRegion(self, painter, pxpts, pypts, bounds, belowleft, clip,
                    brush):
        """Fill the region above/below or left/right of the points.

        belowleft fills below if the variable is 'x', or left if 'y'
        otherwise it fills above/right."""

        # find starting and ending points for the filled region
        x1, y1, x2, y2 = bounds

        pts = qt4.QPolygonF()
        if self.settings.variable == 'x':
            if belowleft:
                pts.append(qt4.QPointF(pxpts[0], y2))
                endpt = qt4.QPointF(pxpts[-1], y2)
            else:
                pts.append(qt4.QPointF(pxpts[0], y1))
                endpt = qt4.QPointF(pxpts[-1], y1)
        else:
            if belowleft:
                pts.append(qt4.QPointF(x1, pypts[0]))
                endpt = qt4.QPointF(x1, pypts[-1])
            else:
                pts.append(qt4.QPointF(x2, pypts[0]))
                endpt = qt4.QPointF(x2, pypts[-1])

        # add the points between
        utils.addNumpyToPolygonF(pts, pxpts, pypts)

        # stick on the ending point
        pts.append(endpt)

        # draw the clipped polygon
        clipped = qt4.QPolygonF()
        utils.polygonClip(pts, clip, clipped)
        path = qt4.QPainterPath()
        path.addPolygon(clipped)
        utils.brushExtFillPath(painter, brush, path)
Esempio n. 20
0
    def draw(self, posn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get points in plotter coordinates
        xp, yp = self._getPlotterCoords(posn)
        if xp is None or yp is None:
            # we can't calculate coordinates
            return

        x1, y1, x2, y2 = posn
        cliprect = qt4.QRectF(qt4.QPointF(x1, y1), qt4.QPointF(x2, y2))
        painter = phelper.painter(self, posn, clip=cliprect)

        pen = s.Line.makeQPenWHide(painter)
        pw = pen.widthF() * 2
        lineclip = qt4.QRectF(qt4.QPointF(x1 - pw, y1 - pw),
                              qt4.QPointF(x2 + pw, y2 + pw))

        # this is a hack as we generate temporary fake datasets
        path = qt4.QPainterPath()
        for xvals, yvals in document.generateValidDatasetParts(
                document.Dataset(xp), document.Dataset(yp)):

            poly = qt4.QPolygonF()
            utils.addNumpyToPolygonF(poly, xvals.data, yvals.data)
            clippedpoly = qt4.QPolygonF()
            utils.polygonClip(poly, lineclip, clippedpoly)
            path.addPolygon(clippedpoly)
            path.closeSubpath()

        utils.brushExtFillPath(painter, s.Fill, path, stroke=pen)
Esempio n. 21
0
    def plotBox(self, painter, axes, boxposn, posn, width, clip, stats):
        """Draw box for dataset."""

        if not N.isfinite(stats.median):
            # skip bad datapoints
            return

        s = self.settings
        horz = (s.direction == 'horizontal')

        # convert quartiles, top and bottom whiskers to plotter
        medplt, botplt, topplt, botwhisplt, topwhisplt = tuple(
            axes[not horz].dataToPlotterCoords(
                posn,
                N.array([
                    stats.median, stats.botquart, stats.topquart,
                    stats.botwhisker, stats.topwhisker
                ])))

        # draw whisker top to bottom
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn, topwhisplt, boxposn, botwhisplt, horz)
        # draw ends of whiskers
        endsize = width / 2
        swapline(painter, boxposn - endsize / 2, topwhisplt,
                 boxposn + endsize / 2, topwhisplt, horz)
        swapline(painter, boxposn - endsize / 2, botwhisplt,
                 boxposn + endsize / 2, botwhisplt, horz)

        # draw box fill
        boxpath = qt4.QPainterPath()
        boxpath.addRect(
            swapbox(painter, boxposn - width / 2, botplt, boxposn + width / 2,
                    topplt, horz))
        utils.brushExtFillPath(painter, s.Fill, boxpath)

        # draw line across box
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn - width / 2, medplt, boxposn + width / 2,
                 medplt, horz)

        # draw box
        painter.strokePath(boxpath, s.Border.makeQPenWHide(painter))

        # draw outliers
        painter.setPen(s.MarkersLine.makeQPenWHide(painter))
        painter.setBrush(s.MarkersFill.makeQBrushWHide())
        markersize = s.get('markerSize').convert(painter)
        if stats.outliers.shape[0] != 0:
            pltvals = axes[not horz].dataToPlotterCoords(posn, stats.outliers)
            otherpos = N.zeros(pltvals.shape) + boxposn
            if horz:
                x, y = pltvals, otherpos
            else:
                x, y = otherpos, pltvals

            utils.plotMarkers(painter,
                              x,
                              y,
                              s.outliersmarker,
                              markersize,
                              clip=clip)

        # draw mean
        meanplt = axes[not horz].dataToPlotterCoords(posn,
                                                     N.array([stats.mean]))[0]
        if horz:
            x, y = meanplt, boxposn
        else:
            x, y = boxposn, meanplt
        utils.plotMarker(painter, x, y, s.meanmarker, markersize)
Esempio n. 22
0
 def drawShape(self, painter, rect):
     s = self.settings
     path = qt4.QPainterPath()
     path.addEllipse(rect)
     utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Esempio n. 23
0
 def setClip(self, painter, bounds):
     '''Set clipping for graph.'''
     p = qt4.QPainterPath()
     p.addPolygon( self._tripoly )
     painter.setClipPath(p)
Esempio n. 24
0
    def draw(self, parentposn, phelper, outerbounds = None):
        """Plot the key on a plotter."""

        s = self.settings
        if s.hide:
            return

        painter = phelper.painter(self, parentposn)

        font = s.get('Text').makeQFont(painter)
        painter.setFont(font)
        height = utils.FontMetrics(font, painter.device()).height()
        margin = s.marginSize * height

        showtext = not s.Text.hide

        # maximum width of text required
        maxwidth = 1
        # total number of layout lines required
        totallines = 0

        # reserve space for the title
        titlewidth, titleheight = 0, 0
        if s.title != '':
            titlefont = qt4.QFont(font)
            titlefont.setPointSize(max(font.pointSize() * 1.2, font.pointSize() + 2))
            titlewidth, titleheight = utils.Renderer(painter, titlefont,
                                            0, 0, s.title).getDimensions()
            titleheight += 0.5*margin
            maxwidth = titlewidth

        entries = []
        # iterate over children and find widgets which are suitable
        for c in self.parent.children:
            try:
                num = c.getNumberKeys()
            except AttributeError:
                continue
            if not c.settings.hide:
                # add an entry for each key entry for each widget
                for i in xrange(num):
                    lines = 1
                    if showtext:
                        w, h = utils.Renderer(painter, font, 0, 0,
                                              c.getKeyText(i)).getDimensions()
                        maxwidth = max(maxwidth, w)
                        lines = max(1, math.ceil(float(h)/float(height)))
                    
                    totallines += lines
                    entries.append( (c, i, lines) )

        # layout the box
        layout, (numrows, numcols) = self._layout(entries, totallines)

        # total size of box
        symbolwidth = s.get('keyLength').convert(painter)
        totalwidth = ( (maxwidth + height + symbolwidth)*numcols +
                       height*(numcols-1) )
        totalheight = numrows * height + titleheight
        if not s.Border.hide:
            totalwidth += 2*margin
            totalheight += margin

        # work out horizontal position
        h = s.horzPosn
        if h == 'left':
            x = parentposn[0] + height
        elif h == 'right':
            x = parentposn[2] - height - totalwidth
        elif h == 'centre':
            x = ( parentposn[0] +
                  0.5*(parentposn[2] - parentposn[0] - totalwidth) )
        elif h == 'manual':
            x = parentposn[0] + (parentposn[2]-parentposn[0])*s.horzManual

        # work out vertical position
        v = s.vertPosn
        if v == 'top':
            y = parentposn[1] + height
        elif v == 'bottom':
            y = parentposn[3] - totalheight - height
        elif v == 'centre':
            y = ( parentposn[1] +
                  0.5*(parentposn[3] - parentposn[1] - totalheight) )
        elif v == 'manual':
            y = ( parentposn[3] -
                  (parentposn[3]-parentposn[1])*s.vertManual - totalheight )

        # for controlgraph
        boxposn = (x, y)
        boxdims = (totalwidth, totalheight)

        # draw surrounding box
        boxpath = qt4.QPainterPath()
        boxpath.addRect(qt4.QRectF(x, y, totalwidth, totalheight))
        if not s.Background.hide:
            utils.brushExtFillPath(painter, s.Background, boxpath)
        if not s.Border.hide:
            painter.strokePath(boxpath, s.get('Border').makeQPen(painter) )
            x += margin
            y += margin*0.5

        # center and draw the title
        if s.title:
            xpos = x + 0.5*(totalwidth - (0 if s.Border.hide else 2*margin) - titlewidth)
            utils.Renderer(painter, titlefont, xpos, y, s.title, alignvert=1).render()
            y += titleheight

        textpen = s.get('Text').makeQPen()

        # plot dataset entries
        for (plotter, num, xp, yp, lines) in layout:
            xpos = x + xp*(maxwidth+2*height+symbolwidth)
            ypos = y + yp*height

            # plot key symbol
            painter.save()
            keyoffset = 0
            if s.keyAlign == 'centre':
                keyoffset = (lines-1)*height/2.0
            elif s.keyAlign == 'bottom':
                keyoffset = (lines-1)*height
            
            plotter.drawKeySymbol(num, painter, xpos, ypos+keyoffset,
                                  symbolwidth, height)
            painter.restore()

            # write key text
            if showtext:
                painter.setPen(textpen)
                utils.Renderer(painter, font,
                               xpos + height + symbolwidth, ypos,
                               plotter.getKeyText(num),
                               -1, 1).render()

        phelper.setControlGraph(
            self, [ControlKey(self, parentposn, boxposn, boxdims, height)] )
Esempio n. 25
0
    def draw(self, parentposn, phelper, outerbounds=None,
             useexistingpainter=None):
        """Plot the axis on the painter.

        useexistingpainter is a hack so that a colorbar can reuse the
        drawing code here. If set to a painter, it will use this rather
        than opening a new one.
        """

        s = self.settings

        # recompute if document modified
        if self.docchangeset != self.document.changeset:
            self._computePlottedRange()

        posn = widget.Widget.draw(self, parentposn, phelper, outerbounds)
        self._updatePlotRange(posn)

        # get ready to draw
        if useexistingpainter is not None:
            painter = useexistingpainter
        else:
            painter = phelper.painter(self, posn)

        # make control item for axis
        phelper.setControlGraph(self, [ controlgraph.ControlAxisLine(
                    self, s.direction, self.coordParr1,
                    self.coordParr2, self.coordPerp, posn) ])

        # get tick vals
        coordticks = self._graphToPlotter(self.majortickscalc)
        coordminorticks = self._graphToPlotter(self.minortickscalc)

        # exit if axis is hidden
        if s.hide:
            return

        texttorender = []

        # multiplication factor if reflection on the axis is requested
        sign = 1
        if s.direction == 'vertical':
            sign *= -1
        if self.coordReflected:
            sign *= -1

        # plot gridlines
        if not s.MinorGridLines.hide:
            self._drawGridLines('MinorGridLines', painter, coordminorticks,
                                parentposn)
        if not s.GridLines.hide:
            self._drawGridLines('GridLines', painter, coordticks,
                                parentposn)

        # plot the line along the axis
        if not s.Line.hide:
            self._drawAxisLine(painter)

        # plot minor ticks
        if not s.MinorTicks.hide:
            self._drawMinorTicks(painter, coordminorticks)

        # keep track of distance from axis
        self._delta_axis = 0

        # plot major ticks
        if not s.MajorTicks.hide:
            self._drawMajorTicks(painter, coordticks)

        # plot tick labels
        suppresstext = self._suppressText(painter, parentposn, outerbounds)
        if not s.TickLabels.hide and not suppresstext:
            self._drawTickLabels(phelper, painter, coordticks, sign,
                                 outerbounds, texttorender)

        # draw an axis label
        if not s.Label.hide and not suppresstext:
            self._drawAxisLabel(painter, sign, outerbounds, texttorender)

        # mirror axis at other side of plot
        if s.autoMirror:
            self._autoMirrorDraw(posn, painter, coordticks, coordminorticks)

        # all the text is drawn at the end so that
        # we can check it doesn't overlap
        drawntext = qt4.QPainterPath()
        for r, pen in texttorender:
            bounds = r.getBounds()
            rect = qt4.QRectF(bounds[0], bounds[1], bounds[2]-bounds[0],
                              bounds[3]-bounds[1])

            if not drawntext.intersects(rect):
                painter.setPen(pen)
                r.render()
                drawntext.addRect(rect)