Ejemplo n.º 1
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.set_line_width(10.0)
            cx.arc(self.layout.chart.x + self.layout.chart.w / 2,
                   self.layout.chart.y + self.layout.chart.h / 2,
                   min(self.layout.chart.w / 2, self.layout.chart.h / 2),
                   0, 2 * math.pi)
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 2
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            x, y, w, h = 0, 0, self.area.w, self.area.h
            w += self.options.padding.left + self.options.padding.right
            h += self.options.padding.top + self.options.padding.bottom
            cx.rectangle(x, y, w, h)
            cx.fill()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.rectangle(self.area.x, self.area.y, self.area.w, self.area.h)
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 3
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            surface_width, surface_height = self.getSurfaceSize()
            cx.rectangle(self.options.padding.left, self.options.padding.top,
                         surface_width - (self.options.padding.left
                                          + self.options.padding.right),
                         surface_height - (self.options.padding.top
                                           + self.options.padding.bottom))
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 4
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            surface_width, surface_height = self.getSurfaceSize()
            cx.rectangle(self.options.padding.left, self.options.padding.top,
                         surface_width - (self.options.padding.left
                                          + self.options.padding.right),
                         surface_height - (self.options.padding.top
                                           + self.options.padding.bottom))
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 5
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.set_line_width(10.0)
            cx.arc(self.layout.chart.x + self.layout.chart.w / 2,
                   self.layout.chart.y + self.layout.chart.h / 2,
                   min(self.layout.chart.w / 2,
                       self.layout.chart.h / 2), 0, 2 * math.pi)
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 6
0
        def drawBar(bar):
            stroke_width = self.options.stroke.width
            ux, uy = cx.device_to_user_distance(stroke_width, stroke_width)
            if ux < uy:
                ux = uy
            cx.set_line_width(ux)

            # gather bar proportions
            x = self.layout.chart.x + self.layout.chart.w * bar.x
            y = self.layout.chart.y + self.layout.chart.h * bar.y
            w = self.layout.chart.w * bar.w
            h = self.layout.chart.h * bar.h

            if (w < 1 or h < 1) and self.options.yvals.skipSmallValues:
                return # don't draw when the bar is too small

            if self.options.stroke.shadow:
                cx.set_source_rgba(0, 0, 0, 0.15)
                rectangle = self._getShadowRectangle(x, y, w, h)
                cx.rectangle(*rectangle)
                cx.fill()

            if self.options.shouldFill or (not self.options.stroke.hide):

                if self.options.shouldFill:
                    cx.set_source_rgb(*self.colorScheme[bar.name])
                    cx.rectangle(x, y, w, h)
                    cx.fill()

                if not self.options.stroke.hide:
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.rectangle(x, y, w, h)
                    cx.stroke()

            if bar.yerr:
                self._renderError(cx, x, y, w, h, bar.yval, bar.yerr)

            # render yvals above/beside bars
            if self.options.yvals.show:
                cx.save()
                cx.set_font_size(self.options.yvals.fontSize)
                cx.set_source_rgb(*hex2rgb(self.options.yvals.fontColor))

                if isinstance(self.options.yvals.renderer, collections.Callable):
                    label = safe_unicode(self.options.yvals.renderer(bar),
                                         self.options.encoding)
                else:
                    label = safe_unicode(bar.yval, self.options.encoding)
                extents = cx.text_extents(label)
                labelW = extents[2]
                labelH = extents[3]

                self._renderYVal(cx, label, labelW, labelH, x, y, w, h)

                cx.restore()
Ejemplo n.º 7
0
        def drawBar(bar):
            stroke_width = self.options.stroke.width
            ux, uy = cx.device_to_user_distance(stroke_width, stroke_width)
            if ux < uy:
                ux = uy
            cx.set_line_width(ux)

            # gather bar proportions
            x = self.layout.chart.x + self.layout.chart.w * bar.x
            y = self.layout.chart.y + self.layout.chart.h * bar.y
            w = self.layout.chart.w * bar.w
            h = self.layout.chart.h * bar.h

            if (w < 1 or h < 1) and self.options.yvals.skipSmallValues:
                return  # don't draw when the bar is too small

            if self.options.stroke.shadow:
                cx.set_source_rgba(0, 0, 0, 0.15)
                rectangle = self._getShadowRectangle(x, y, w, h)
                cx.rectangle(*rectangle)
                cx.fill()

            if self.options.shouldFill or (not self.options.stroke.hide):

                if self.options.shouldFill:
                    cx.set_source_rgb(*self.colorScheme[bar.name])
                    cx.rectangle(x, y, w, h)
                    cx.fill()

                if not self.options.stroke.hide:
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.rectangle(x, y, w, h)
                    cx.stroke()

            if bar.yerr:
                self._renderError(cx, x, y, w, h, bar.yval, bar.yerr)

            # render yvals above/beside bars
            if self.options.yvals.show:
                cx.save()
                cx.set_font_size(self.options.yvals.fontSize)
                cx.set_source_rgb(*hex2rgb(self.options.yvals.fontColor))

                if callable(self.options.yvals.renderer):
                    label = safe_unicode(self.options.yvals.renderer(bar),
                                         self.options.encoding)
                else:
                    label = safe_unicode(bar.yval, self.options.encoding)
                extents = cx.text_extents(label)
                labelW = extents[2]
                labelH = extents[3]

                self._renderYVal(cx, label, labelW, labelH, x, y, w, h)

                cx.restore()
Ejemplo n.º 8
0
        def drawBar(bar):
            stroke_width = self.options.stroke.width
            ux, uy = cx.device_to_user_distance(stroke_width, stroke_width)
            if ux < uy:
                ux = uy
            cx.set_line_width(ux)

            # gather bar proportions
            x = self.area.x + self.area.w * bar.x
            y = self.area.y + self.area.h * bar.y
            w = self.area.w * bar.w
            h = self.area.h * bar.h

            if w < 1 or h < 1:
                return # do not draw when the bar is too small

            if self.options.stroke.shadow:
                cx.set_source_rgba(0, 0, 0, 0.15)
                rectangle = self._getShadowRectangle(x, y, w, h)
                cx.rectangle(*rectangle)
                cx.fill()

            if self.options.shouldFill or (not self.options.stroke.hide):

                if self.options.shouldFill:
                    cx.set_source_rgb(*self.colorScheme[bar.name])
                    cx.rectangle(x, y, w, h)
                    cx.fill()

                if not self.options.stroke.hide:
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.rectangle(x, y, w, h)
                    cx.stroke()

            # render yvals above/beside bars
            if self.options.yvals.show:
                cx.save()
                cx.set_font_size(self.options.yvals.fontSize)
                cx.set_source_rgb(*hex2rgb(self.options.yvals.fontColor))

                label = unicode(bar.yval)
                extents = cx.text_extents(label)
                labelW = extents[2]
                labelH = extents[3]

                self._renderYVal(cx, label, labelW, labelH, x, y, w, h)

                cx.restore()
Ejemplo n.º 9
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            x, y, w, h = self.layout.ticks[i]

            xb, yb, width, height, xa, ya = cx.text_extents(label)

            # draw label with text tick[1]
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            self.xlabels.append(label)
Ejemplo n.º 10
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        radius = self.layout.radius
        radius_inc = radius / (self.nrings + 1)
        current_radius = self.centery + radius_inc + radius_inc / 2

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            cx.move_to(self.centerx, current_radius)
            cx.show_text(label)
            current_radius += radius_inc
Ejemplo n.º 11
0
Archivo: pie.py Proyecto: calston/tums
    def _renderChart(self, cx):
        """Renders a pie chart"""
        cx.set_line_join(cairo.LINE_JOIN_ROUND)

        if self.options.stroke.shadow:
            cx.save()
            cx.set_source_rgba(0, 0, 0, 0.15)

            cx.new_path()
            cx.move_to(self.centerx, self.centery)
            cx.arc(self.centerx + 1, self.centery + 2, self.radius + 1, 0,
                   math.pi * 2)
            cx.line_to(self.centerx, self.centery)
            cx.close_path()
            cx.fill()
            cx.restore()

        cx.save()
        for slice in self.slices:
            if slice.isBigEnough():
                cx.set_source_rgb(*self.options.colorScheme[slice.name])
                if self.options.shouldFill:
                    slice.draw(cx, self.centerx, self.centery, self.radius)
                    cx.fill()

                if not self.options.stroke.hide:
                    slice.draw(cx, self.centerx, self.centery, self.radius)
                    cx.set_line_width(self.options.stroke.width)
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.stroke()

        cx.restore()
Ejemplo n.º 12
0
    def _renderLegend(self, cx):
        """This function adds a legend to the chart"""
        if self.options.legend.hide:
            return

        surface_width, surface_height = self.getSurfaceSize()

        # Compute legend dimensions
        padding = 4
        bullet = 15
        width = 0
        height = padding
        keys = self._getDatasetsKeys()
        for key in keys:
            extents = cx.text_extents(key)
            width = max(extents[2], width)
            height += max(extents[3], bullet) + padding
        width = padding + bullet + padding + width + padding

        # Compute legend position
        legend = self.options.legend
        if legend.position.right is not None:
            legend.position.left = (surface_width
                                    - legend.position.right
                                    - width)
        if legend.position.bottom is not None:
            legend.position.top = (surface_height
                                   - legend.position.bottom
                                   - height)

        # Draw the legend
        cx.save()
        cx.rectangle(self.options.legend.position.left,
                     self.options.legend.position.top,
                     width, height)
        cx.set_source_rgba(1, 1, 1, self.options.legend.opacity)
        cx.fill_preserve()
        cx.set_line_width(self.options.stroke.width)
        cx.set_source_rgb(*hex2rgb(self.options.legend.borderColor))
        cx.stroke()

        def drawKey(key, x, y, text_height):
            cx.rectangle(x, y, bullet, bullet)
            cx.set_source_rgb(*self.options.colorScheme[key])
            cx.fill_preserve()
            cx.set_source_rgb(0, 0, 0)
            cx.stroke()
            cx.move_to(x + bullet + padding,
                       y + bullet / 2.0 + text_height / 2.0)
            cx.show_text(key)

        cx.set_line_width(1)
        x = self.options.legend.position.left + padding
        y = self.options.legend.position.top + padding
        for key in keys:
            extents = cx.text_extents(key)
            drawKey(key, x, y, extents[3])
            y += max(extents[3], bullet) + padding

        cx.restore()
Ejemplo n.º 13
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        radius = self.layout.radius
        radius_inc = radius / (self.nrings + 1)
        current_radius = self.centery + radius_inc + radius_inc / 2

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            cx.move_to(self.centerx, current_radius)
            cx.show_text(label)
            current_radius += radius_inc
Ejemplo n.º 14
0
    def _renderChart(self, cx):
        """Renders a pie chart"""
        cx.set_line_join(cairo.LINE_JOIN_ROUND)

        if self.options.stroke.shadow:
            cx.save()
            cx.set_source_rgba(0, 0, 0, 0.15)

            cx.new_path()
            cx.move_to(self.centerx, self.centery)
            cx.arc(self.centerx + 1, self.centery + 2, self.radius + 1, 0,
                   math.pi * 2)
            cx.line_to(self.centerx, self.centery)
            cx.close_path()
            cx.fill()
            cx.restore()

        cx.save()
        for slice in self.slices:
            if slice.isBigEnough():
                cx.set_source_rgb(*self.colorScheme[slice.name])
                if self.options.shouldFill:
                    slice.draw(cx, self.centerx, self.centery, self.radius)
                    cx.fill()

                if not self.options.stroke.hide:
                    slice.draw(cx, self.centerx, self.centery, self.radius)
                    cx.set_line_width(self.options.stroke.width)
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.stroke()

        cx.restore()
Ejemplo n.º 15
0
    def _renderAxisLabel(self, cx, label, x, y, vertical=False):
        cx.save()
        cx.select_font_face(self.options.axis.labelFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_BOLD)
        cx.set_font_size(self.options.axis.labelFontSize)
        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        xb, yb, width, height, xa, ya = cx.text_extents(label)

        if vertical:
            y = y + width / 2.0
            cx.move_to(x - xb, y - yb)
            cx.translate(x, y)
            cx.rotate(-math.radians(90))
            cx.move_to(-xb, -yb)
            cx.show_text(label)
            if self.debug:
                cx.rectangle(0, 0, width, height)
                cx.stroke()
        else:
            x = x - width / 2.0
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            if self.debug:
                cx.rectangle(x, y, width, height)
                cx.stroke()
        cx.restore()
Ejemplo n.º 16
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            x, y, w, h = self.layout.ticks[i]

            xb, yb, width, height, xa, ya = cx.text_extents(label)

            # draw label with text tick[1]
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            self.xlabels.append(label)
Ejemplo n.º 17
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        if not self.options.axis.y.hide:
            if self.yticks:
                for tick in self.yticks:
                    self._renderYTick(cx, tick)

            if self.options.axis.y.label:
                self._renderYAxisLabel(cx, self.options.axis.y.label)

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            if self.xticks:
                for tick in self.xticks:
                    self._renderXTick(cx, tick)

            if self.options.axis.x.label:
                self._renderXAxisLabel(cx, self.options.axis.x.label)

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 18
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        if not self.options.axis.y.hide:
            if self.yticks:
                for tick in self.yticks:
                    self._renderYTick(cx, tick)

            if self.options.axis.y.label:
                self._renderYAxisLabel(cx, self.options.axis.y.label)

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            if self.xticks:
                for tick in self.xticks:
                    self._renderXTick(cx, tick)

            if self.options.axis.x.label:
                self._renderXAxisLabel(cx, self.options.axis.x.label)

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 19
0
    def _renderAxisLabel(self, cx, label, x, y, vertical=False):
        cx.save()
        cx.select_font_face(self.options.axis.labelFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_BOLD)
        cx.set_font_size(self.options.axis.labelFontSize)
        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        xb, yb, width, height, xa, ya = cx.text_extents(label)

        if vertical:
            y = y + width / 2.0
            cx.move_to(x - xb, y - yb)
            cx.translate(x, y)
            cx.rotate(-math.radians(90))
            cx.move_to(-xb, -yb)
            cx.show_text(label)
            if self.debug:
                cx.rectangle(0, 0, width, height)
                cx.stroke()
        else:
            x = x - width / 2.0
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            if self.debug:
                cx.rectangle(x, y, width, height)
                cx.stroke()
        cx.restore()
Ejemplo n.º 20
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        if not self.options.axis.y.hide:
            if self.yticks:
                for tick in self.yticks:
                    self._renderYTick(cx, tick)

            if self.options.axis.y.label:
                cx.save()
                rotate = self.options.axis.y.rotate
                tickWidth, tickHeight = self._getTickSize(
                    cx, self.yticks, rotate)
                label = unicode(self.options.axis.y.label)
                x = self.area.x - tickWidth - 4.0
                y = self.area.y + 0.5 * self.area.h
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      True)
                cx.restore()

            # draws the vertical line representing the Y axis
            cx.new_path()
            cx.move_to(self.area.x, self.area.y)
            cx.line_to(self.area.x, self.area.y + self.area.h)
            cx.close_path()
            cx.stroke()

        if not self.options.axis.x.hide:
            fontAscent = cx.font_extents()[0]
            if self.xticks:
                for tick in self.xticks:
                    self._renderXTick(cx, tick, fontAscent)

            if self.options.axis.x.label:
                cx.save()
                rotate = self.options.axis.x.rotate
                tickWidth, tickHeight = self._getTickSize(
                    cx, self.xticks, rotate)
                label = unicode(self.options.axis.x.label)
                x = self.area.x + self.area.w / 2.0
                y = self.area.y + self.area.h + tickHeight + 4.0
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      False)
                cx.restore()

            # draws the horizontal line representing the X axis
            cx.new_path()
            cx.move_to(self.area.x, self.area.y + self.area.h)
            cx.line_to(self.area.x + self.area.w, self.area.y + self.area.h)
            cx.close_path()
            cx.stroke()

        cx.restore()
Ejemplo n.º 21
0
        def preparePath(storeName):
            cx.new_path()
            firstPoint = True
            lastX = None
            if self.options.shouldFill:
                # Go to the (0,0) coordinate to start drawing the area
                # cx.move_to(self.layout.chart.x,
                #           self.layout.chart.y + self.layout.chart.h)
                offset = (1.0 - self.origin) * self.layout.chart.h
                cx.move_to(self.layout.chart.x, self.layout.chart.y + offset)

            for point in self.points:
                if point.name == storeName:
                    if not self.options.shouldFill and firstPoint:
                        # starts the first point of the line
                        cx.move_to(
                            point.x * self.layout.chart.w + self.layout.chart.x,
                            point.y * self.layout.chart.h + self.layout.chart.y,
                        )
                        firstPoint = False
                        continue
                    cx.line_to(
                        point.x * self.layout.chart.w + self.layout.chart.x,
                        point.y * self.layout.chart.h + self.layout.chart.y,
                    )
                    # # cx.show_text(str(point.yval))
                    # we remember the last X coordinate to close the area
                    # properly. See bug #4
                    lastX = point.x

            if self.options.shouldFill:
                # Close the path to the start point
                y = (1.0 - self.origin) * self.layout.chart.h + self.layout.chart.y
                cx.line_to(lastX * self.layout.chart.w + self.layout.chart.x, y)
                cx.line_to(self.layout.chart.x, y)
                cx.close_path()
            else:
                cx.set_source_rgb(*self.colorScheme[storeName])
                cx.stroke()

            # Draw yvals text, add by Zhang Kun
            if self.options.yvals and self.options.yvals.show:
                cx.save()
                cx.set_font_size(self.options.yvals.fontSize)
                cx.set_source_rgb(*hex2rgb(self.options.yvals.fontColor))

                for point in self.points:
                    if point.name == storeName:
                        val_str = safe_unicode(str(point.yval), self.options.encoding)
                        extents = cx.text_extents(val_str)

                        cx.move_to(
                            point.x * self.layout.chart.w + self.layout.chart.x,
                            point.y * self.layout.chart.h + self.layout.chart.y + extents[1] / 2,
                        )
                        cx.show_text(str(point.yval))
                cx.restore()
Ejemplo n.º 22
0
    def _renderLegend(self, cx):
        """This function adds a legend to the chart"""
        if self.options.legend.hide:
            return

        surface_width, surface_height = self.getSurfaceSize()

        # Compute legend dimensions
        padding = 4
        bullet = 15
        width = 0
        height = padding
        keys = self._getDatasetsKeys()
        for key in keys:
            extents = cx.text_extents(key)
            width = max(extents[2], width)
            height += max(extents[3], bullet) + padding
        width = padding + bullet + padding + width + padding

        # Compute legend position
        legend = self.options.legend
        if legend.position.right is not None:
            legend.position.left = (surface_width - legend.position.right -
                                    width)
        if legend.position.bottom is not None:
            legend.position.top = (surface_height - legend.position.bottom -
                                   height)

        # Draw the legend
        cx.save()
        cx.rectangle(self.options.legend.position.left,
                     self.options.legend.position.top, width, height)
        cx.set_source_rgba(1, 1, 1, self.options.legend.opacity)
        cx.fill_preserve()
        cx.set_line_width(self.options.stroke.width)
        cx.set_source_rgb(*hex2rgb(self.options.legend.borderColor))
        cx.stroke()

        def drawKey(key, x, y, text_height):
            cx.rectangle(x, y, bullet, bullet)
            cx.set_source_rgb(*self.colorScheme[key])
            cx.fill_preserve()
            cx.set_source_rgb(0, 0, 0)
            cx.stroke()
            cx.move_to(x + bullet + padding,
                       y + bullet / 2.0 + text_height / 2.0)
            cx.show_text(key)

        cx.set_line_width(1)
        x = self.options.legend.position.left + padding
        y = self.options.legend.position.top + padding
        for key in keys:
            extents = cx.text_extents(key)
            drawKey(key, x, y, extents[3])
            y += max(extents[3], bullet) + padding

        cx.restore()
Ejemplo n.º 23
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.set_line_width(10.0)
            cx.new_path()
            init = None
            count = len(self.xticks)
            for index, tick in enumerate(self.xticks):
                ang = math.pi / 2 - index * 2 * math.pi / count
                x = (self.layout.chart.x + self.layout.chart.w / 2
                     - math.cos(ang)
                     * min(self.layout.chart.w / 2, self.layout.chart.h / 2))
                y = (self.layout.chart.y + self.layout.chart.h / 2
                     - math.sin(ang)
                     * min(self.layout.chart.w / 2, self.layout.chart.h / 2))
                if init is None:
                    cx.move_to(x, y)
                    init = (x, y)
                else:
                    cx.line_to(x, y)
            cx.line_to(init[0], init[1])
            cx.close_path()
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 24
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.set_line_width(10.0)
            cx.new_path()
            init = None
            count = len(self.xticks)
            for index, tick in enumerate(self.xticks):
                ang = math.pi / 2 - index * 2 * math.pi / count
                x = (self.layout.chart.x + self.layout.chart.w / 2 -
                     math.cos(ang) *
                     min(self.layout.chart.w / 2, self.layout.chart.h / 2))
                y = (self.layout.chart.y + self.layout.chart.h / 2 -
                     math.sin(ang) *
                     min(self.layout.chart.w / 2, self.layout.chart.h / 2))
                if init is None:
                    cx.move_to(x, y)
                    init = (x, y)
                else:
                    cx.line_to(x, y)
            cx.line_to(init[0], init[1])
            cx.close_path()
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 25
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.rectangle(self.area.x, self.area.y, self.area.w, self.area.h)
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 26
0
    def _renderBackground(self, cx):
        """Renders the background area of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            cx.paint()

        if self.options.background.chartColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.chartColor))
            cx.rectangle(self.area.x, self.area.y, self.area.w, self.area.h)
            cx.fill()

        if self.options.background.lineColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))
            cx.set_line_width(self.options.axis.lineWidth)
            self._renderLines(cx)

        cx.restore()
Ejemplo n.º 27
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        if not self.options.axis.y.hide:
            if self.yticks:
                for tick in self.yticks:
                    self._renderYTick(cx, tick)

            if self.options.axis.y.label:
                cx.save()
                rotate = self.options.axis.y.rotate
                tickWidth, tickHeight = self._getTickSize(
                    cx, self.yticks, rotate)
                label = unicode(self.options.axis.y.label)
                x = self.area.x - tickWidth - 4.0
                y = self.area.y + 0.5 * self.area.h
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      True)
                cx.restore()

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            fontAscent = cx.font_extents()[0]
            if self.xticks:
                for tick in self.xticks:
                    self._renderXTick(cx, tick, fontAscent)

            if self.options.axis.x.label:
                cx.save()
                rotate = self.options.axis.x.rotate
                tickWidth, tickHeight = self._getTickSize(
                    cx, self.xticks, rotate)
                label = unicode(self.options.axis.x.label)
                x = self.area.x + self.area.w / 2.0
                y = self.area.y + self.area.h + tickHeight + 4.0
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      False)
                cx.restore()

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 28
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        if not self.options.axis.y.hide:
            if self.yticks:
                for tick in self.yticks:
                    self._renderYTick(cx, tick)

            if self.options.axis.y.label:
                cx.save()
                rotate = self.options.axis.y.rotate
                tickWidth, tickHeight = self._getTickSize(cx, self.yticks,
                                                          rotate)
                label = unicode(self.options.axis.y.label)
                x = self.area.x - tickWidth - 4.0
                y = self.area.y + 0.5 * self.area.h
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      True)
                cx.restore()

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            fontAscent = cx.font_extents()[0]
            if self.xticks:
                for tick in self.xticks:
                    self._renderXTick(cx, tick, fontAscent)

            if self.options.axis.x.label:
                cx.save()
                rotate = self.options.axis.x.rotate
                tickWidth, tickHeight = self._getTickSize(cx, self.xticks,
                                                          rotate)
                label = unicode(self.options.axis.x.label)
                x = self.area.x + self.area.w / 2.0
                y = self.area.y + self.area.h + tickHeight + 4.0
                self._renderAxisLabel(cx, tickWidth, tickHeight, label, x, y,
                                      False)
                cx.restore()

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 29
0
    def _renderChart(self, cx):
        """Renders a pie chart"""
        self.centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        self.centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cx.set_line_join(cairo.LINE_JOIN_ROUND)

        if self.options.stroke.shadow and False:
            cx.save()
            cx.set_source_rgba(0, 0, 0, 0.15)

            cx.new_path()
            cx.move_to(self.centerx, self.centery)
            cx.arc(self.centerx + 1, self.centery + 2,
                   self.layout.radius + 1, 0, math.pi * 2)
            cx.line_to(self.centerx, self.centery)
            cx.close_path()
            cx.fill()
            cx.restore()

        cx.save()
        for slice in self.slices:
            if slice.isBigEnough():
                cx.set_source_rgb(*self.colorScheme[slice.name])
                if self.options.shouldFill:
                    slice.draw(cx, self.centerx, self.centery,
                               self.layout.radius)
                    cx.fill()

                if not self.options.stroke.hide:
                    slice.draw(cx, self.centerx, self.centery,
                               self.layout.radius)
                    cx.set_line_width(self.options.stroke.width)
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.stroke()

        cx.restore()

        if self.debug:
            cx.set_source_rgba(1, 0, 0, 0.5)
            px = max(cx.device_to_user_distance(1, 1))
            for x, y in self.layout._lines:
                cx.arc(x, y, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.new_path()
                cx.move_to(self.centerx, self.centery)
                cx.line_to(x, y)
                cx.stroke()
Ejemplo n.º 30
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []
        lookup = dict([(slice.xval, slice) for slice in self.slices])


        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for tick in self.xticks:
            slice = lookup[tick[0]]

            normalisedAngle = slice.getNormalisedAngle()

            big_radius = self.radius + 10
            labelx = self.centerx + math.sin(normalisedAngle) * big_radius
            labely = self.centery - math.cos(normalisedAngle) * big_radius

            label = tick[1]
            extents = cx.text_extents(label)
            labelWidth = extents[2]
            labelHeight = extents[3]
            x = y = 0

            if normalisedAngle <= math.pi * 0.5:
                x = labelx
                y = labely - labelHeight
            elif math.pi * 0.5 < normalisedAngle <= math.pi:
                x = labelx
                y = labely
            elif math.pi < normalisedAngle <= math.pi * 1.5:
                x = labelx - labelWidth
                y = labely
            else:
                x = labelx - labelWidth
                y = labely - labelHeight

            # draw label with text tick[1]
            cx.move_to(x, y)
            cx.show_text(label)
            self.xlabels.append(label)
Ejemplo n.º 31
0
    def _renderChart(self, cx):
        """Renders a pie chart"""
        self.centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        self.centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cx.set_line_join(cairo.LINE_JOIN_ROUND)

        if self.options.stroke.shadow and False:
            cx.save()
            cx.set_source_rgba(0, 0, 0, 0.15)

            cx.new_path()
            cx.move_to(self.centerx, self.centery)
            cx.arc(self.centerx + 1, self.centery + 2,
                   self.layout.radius + 1, 0, math.pi * 2)
            cx.line_to(self.centerx, self.centery)
            cx.close_path()
            cx.fill()
            cx.restore()

        cx.save()
        for slice in self.slices:
            if slice.isBigEnough():
                cx.set_source_rgb(*self.colorScheme[slice.name])
                if self.options.shouldFill:
                    slice.draw(cx, self.centerx, self.centery,
                               self.layout.radius)
                    cx.fill()

                if not self.options.stroke.hide:
                    slice.draw(cx, self.centerx, self.centery,
                               self.layout.radius)
                    cx.set_line_width(self.options.stroke.width)
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    cx.stroke()

        cx.restore()

        if self.debug:
            cx.set_source_rgba(1, 0, 0, 0.5)
            px = max(cx.device_to_user_distance(1, 1))
            for x, y in self.layout._lines:
                cx.arc(x, y, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.new_path()
                cx.move_to(self.centerx, self.centery)
                cx.line_to(x, y)
                cx.stroke()
Ejemplo n.º 32
0
    def _renderLines(self, cx):
        """Aux function for _renderBackground"""
        centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cx.set_line_width(self.options.background.lineWidth)
        cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))

        for angle in self.layout.angles:
            car = math.cos(angle) * self.layout.radius
            sar = math.sin(angle) * self.layout.radius

            cx.move_to(centerx, centery)
            cx.line_to(centerx + car, centery + sar)

        cx.stroke()
Ejemplo n.º 33
0
    def _renderLines(self, cx):
        """Aux function for _renderBackground"""
        centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cx.set_line_width(self.options.background.lineWidth)
        cx.set_source_rgb(*hex2rgb(self.options.background.lineColor))

        for angle in self.layout.angles:
            car = math.cos(angle) * self.layout.radius
            sar = math.sin(angle) * self.layout.radius

            cx.move_to(centerx, centery)
            cx.line_to(centerx + car, centery + sar)

        cx.stroke()
Ejemplo n.º 34
0
Archivo: pie.py Proyecto: calston/tums
    def _renderBackground(self, cx):
        """Renders the background of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            x, y, w, h = 0, 0, self.area.w, self.area.h
            w += self.options.padding.left + self.options.padding.right
            h += self.options.padding.top + self.options.padding.bottom
            cx.rectangle(x, y, w, h)
            cx.fill()

        cx.restore()
Ejemplo n.º 35
0
    def _renderBackground(self, cx):
        """Renders the background of the chart"""
        if self.options.background.hide:
            return

        cx.save()

        if self.options.background.baseColor:
            cx.set_source_rgb(*hex2rgb(self.options.background.baseColor))
            x, y, w, h = 0, 0, self.area.w, self.area.h
            w += self.options.padding.left + self.options.padding.right
            h += self.options.padding.top + self.options.padding.bottom
            cx.rectangle(x, y, w, h)
            cx.fill()

        cx.restore()
Ejemplo n.º 36
0
    def _renderAxis(self, cx):
        """Renders the axis for pie charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []
        lookup = dict([(slice.xval, slice) for slice in self.slices])

        cx.select_font_face(self.options.axis.tickFont,
            cairo.FONT_SLANT_NORMAL,
            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for tick in self.xticks:
            slice = lookup[tick[0]]

            normalisedAngle = slice.getNormalisedAngle()

            big_radius = self.radius + 10
            labelx = self.centerx + math.sin(normalisedAngle) * big_radius
            labely = self.centery - math.cos(normalisedAngle) * big_radius

            label = tick[1]
            extents = cx.text_extents(label)
            labelWidth = extents[2]
            labelHeight = extents[3]
            x = y = 0

            if normalisedAngle <= math.pi * 0.5:
                x = labelx
                y = labely - labelHeight
            elif math.pi * 0.5 < normalisedAngle <= math.pi:
                x = labelx
                y = labely
            elif math.pi < normalisedAngle <= math.pi * 1.5:
                x = labelx - labelWidth
                y = labely
            else:
                x = labelx - labelWidth
                y = labely - labelHeight

            # draw label with text tick[1]
            cx.move_to(x, y)
            cx.show_text(label)
            self.xlabels.append(label)
Ejemplo n.º 37
0
            def drawLine(storeName):
                if self.options.stroke.shadow:
                    # draw shadow
                    cx.save()
                    cx.set_source_rgba(0, 0, 0, 0.15)
                    cx.translate(2, -2)
                    preparePath(storeName)
                    cx.fill()
                    cx.restore()

                # fill the line
                cx.set_source_rgb(*self.colorScheme.colors[storeName])
                preparePath(storeName)
                cx.fill()

                if not self.options.stroke.hide:
                    # draw stroke
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    preparePath(storeName)
                    cx.stroke()
Ejemplo n.º 38
0
            def drawLine(storeName):
                if self.options.stroke.shadow:
                    # draw shadow
                    cx.save()
                    cx.set_source_rgba(0, 0, 0, 0.15)
                    cx.translate(2, -2)
                    preparePath(storeName)
                    cx.fill()
                    cx.restore()

                # fill the line
                cx.set_source_rgb(*self.colorScheme[storeName])
                preparePath(storeName)
                cx.fill()

                if not self.options.stroke.hide:
                    # draw stroke
                    cx.set_source_rgb(*hex2rgb(self.options.stroke.color))
                    preparePath(storeName)
                    cx.stroke()
Ejemplo n.º 39
0
    def _renderTitle(self, cx):
        if self.options.title:
            cx.save()
            cx.select_font_face(self.options.titleFont,
                                cairo.FONT_SLANT_NORMAL,
                                cairo.FONT_WEIGHT_BOLD)
            cx.set_font_size(self.options.titleFontSize)
            cx.set_source_rgb(*hex2rgb(self.options.titleColor))

            title = safe_unicode(self.options.title, self.options.encoding)
            extents = cx.text_extents(title)
            title_width = extents[2]

            x = (self.layout.title.x + self.layout.title.w / 2.0 - title_width / 2.0)
            y = self.layout.title.y - extents[1]

            cx.move_to(x, y)
            cx.show_text(title)

            cx.restore()
Ejemplo n.º 40
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        centerx = self.layout.chart.x + self.layout.chart.w / 2
        centery = self.layout.chart.y + self.layout.chart.h / 2

        if not self.options.axis.y.hide:
            if self.yticks:

                count = len(self.yticks)

                for i in range(0, count):
                    self._renderYTick(cx, i, (centerx, centery))

            if self.options.axis.y.label:
                self._renderYAxisLabel(cx, self.options.axis.y.label)

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            fontAscent = cx.font_extents()[0]
            if self.xticks:

                count = len(self.xticks)

                for i in range(0, count):
                    self._renderXTick(cx, i, fontAscent, (centerx, centery))

            if self.options.axis.x.label:
                self._renderXAxisLabel(cx, self.options.axis.x.label)

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 41
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
        cx.set_line_width(self.options.axis.lineWidth)

        centerx = self.layout.chart.x + self.layout.chart.w / 2
        centery = self.layout.chart.y + self.layout.chart.h / 2

        if not self.options.axis.y.hide:
            if self.yticks:

                count = len(self.yticks)

                for i in range(0, count):
                    self._renderYTick(cx, i, (centerx, centery))

            if self.options.axis.y.label:
                self._renderYAxisLabel(cx, self.options.axis.y.label)

            self._renderYAxis(cx)

        if not self.options.axis.x.hide:
            fontAscent = cx.font_extents()[0]
            if self.xticks:

                count = len(self.xticks)

                for i in range(0, count):
                    self._renderXTick(cx, i, fontAscent, (centerx, centery))

            if self.options.axis.x.label:
                self._renderXAxisLabel(cx, self.options.axis.x.label)

            self._renderXAxis(cx)

        cx.restore()
Ejemplo n.º 42
0
    def _renderTitle(self, cx):
        if self.options.title:
            cx.save()
            cx.select_font_face(self.options.titleFont,
                                cairo.FONT_SLANT_NORMAL,
                                cairo.FONT_WEIGHT_BOLD)
            cx.set_font_size(self.options.titleFontSize)
            cx.set_source_rgb(*hex2rgb(self.options.titleColor))

            title = safe_unicode(self.options.title, self.options.encoding)
            extents = cx.text_extents(title)
            title_width = extents[2]

            x = (self.layout.title.x
                 + self.layout.title.w / 2.0
                 - title_width / 2.0)
            y = self.layout.title.y - extents[1]

            cx.move_to(x, y)
            cx.show_text(title)

            cx.restore()
Ejemplo n.º 43
0
    def _renderLegend(self, cx):
        """This function adds a legend to the chart"""
        if self.options.legend.hide:
            return

        surface_width, surface_height = self.getSurfaceSize()

        # Compute legend dimensions
        padding = 4
        bullet = 15
        width = 0
        height = padding
        keys = sorted(self._getDatasetsKeys())
        cx.select_font_face(self.options.legend.legendFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.legend.legendFontSize)
        for key in keys:
            key = safe_unicode(key, self.options.encoding)
            extents = cx.text_extents(key)
            width = max(extents[2], width)
            height += max(extents[3], bullet) + padding
        width = padding + bullet + padding + width + padding

        # Compute legend position
        legend = self.options.legend
        if legend.position.right is not None:
            legend.position.left = (surface_width
                                    - legend.position.right
                                    - width)
        if legend.position.bottom is not None:
            legend.position.top = (surface_height
                                   - legend.position.bottom
                                   - height)

        # Draw the legend
        cx.save()
        cx.rectangle(self.options.legend.position.left,
                     self.options.legend.position.top,
                     width, height)
        cx.set_source_rgba(1, 1, 1, self.options.legend.opacity)
        cx.fill_preserve()
        cx.set_line_width(self.options.legend.borderWidth)
        cx.set_source_rgb(*hex2rgb(self.options.legend.borderColor))
        cx.stroke()

        def drawKey(key, x, y, text_height):
            cx.rectangle(x, y, bullet, bullet)
            try:
                cx.set_source_rgb(*self.colorScheme[key])
            #TODO: cleaner handling of alpha channel
            except TypeError:
                cx.set_source_rgba(*self.colorScheme[key])
            cx.fill_preserve()
            cx.set_source_rgb(0, 0, 0)
            cx.stroke()
            cx.move_to(x + bullet + padding,
                       y + bullet / 2.0 + text_height / 2.0)
            cx.show_text(key)

        cx.set_line_width(1)
        x = self.options.legend.position.left + padding
        y = self.options.legend.position.top + padding
        for key in keys:
            extents = cx.text_extents(key)
            drawKey(key, x, y, extents[3])
            y += max(extents[3], bullet) + padding

        cx.restore()
Ejemplo n.º 44
0
        def preparePath(storeName):
            cx.new_path()
            firstPoint = True
            lastX = None
            if self.options.shouldFill:
                # Go to the (0,0) coordinate to start drawing the area
                #cx.move_to(self.layout.chart.x,
                #           self.layout.chart.y + self.layout.chart.h)
                offset = (1.0 - self.origin) * self.layout.chart.h
                cx.move_to(self.layout.chart.x, self.layout.chart.y + offset)

            for point in self.points:
                if point.name == storeName:
                    if not self.options.shouldFill and firstPoint:
                        # starts the first point of the line
                        cx.move_to(
                            point.x * self.layout.chart.w +
                            self.layout.chart.x,
                            point.y * self.layout.chart.h +
                            self.layout.chart.y)
                        firstPoint = False
                        continue
                    cx.line_to(
                        point.x * self.layout.chart.w + self.layout.chart.x,
                        point.y * self.layout.chart.h + self.layout.chart.y)
                    # # cx.show_text(str(point.yval))
                    # we remember the last X coordinate to close the area
                    # properly. See bug #4
                    lastX = point.x

            if self.options.shouldFill:
                # Close the path to the start point
                y = ((1.0 - self.origin) * self.layout.chart.h +
                     self.layout.chart.y)
                cx.line_to(lastX * self.layout.chart.w + self.layout.chart.x,
                           y)
                cx.line_to(self.layout.chart.x, y)
                cx.close_path()
            else:
                cx.set_source_rgb(*self.colorScheme[storeName])
                cx.stroke()

            # Draw yvals text, add by Zhang Kun
            if self.options.yvals and self.options.yvals.show:
                cx.save()
                cx.set_font_size(self.options.yvals.fontSize)
                cx.set_source_rgb(*hex2rgb(self.options.yvals.fontColor))

                for point in self.points:
                    if point.name == storeName:
                        val_str = safe_unicode(str(point.yval),
                                               self.options.encoding)
                        extents = cx.text_extents(val_str)

                        cx.move_to(
                            point.x * self.layout.chart.w +
                            self.layout.chart.x,
                            point.y * self.layout.chart.h +
                            self.layout.chart.y + extents[1] / 2)
                        cx.show_text(str(point.yval))
                cx.restore()
Ejemplo n.º 45
0
    def _renderAxis(self, cx):
        """Renders the axis for radar charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.labelFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.labelFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            x, y, w, h = self.layout.ticks[i]

            xb, yb, width, height, xa, ya = cx.text_extents(label)

            # draw label with text tick[1]
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            self.xlabels.append(label)
            
        # Draw y-axis

        centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cr = self.layout.radius / float(self.slice)
        
        cx.set_line_width(self.options.axis.lineWidth)
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))

        if self.frame == 'circle':
            for i in xrange(self.slice):
                cx.move_to(centerx, centery)
                cx.arc(centerx, centery, (i+1) * cr, 0, 2*math.pi)
        else:
            for i in xrange(self.slice):
                for j, angle in enumerate(self.layout.angles):
                    x = centerx + math.cos(angle) * (i+1) * cr
                    y = centery + math.sin(angle) * (i+1) * cr

                    if j:
                        cx.line_to(x, y)
                    else:
                        cx.move_to(x, y)

                cx.close_path()

        cx.stroke()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)
        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i in xrange(self.slice):
            yval = "%.1f" % (self.maxyval / self.slice * (i+1))
            tw, th = get_text_extents(cx, yval, self.options.axis.tickFont, self.options.axis.tickFontSize, self.options.encoding)
            tx = centerx + (i+1) * cr - tw

            cx.move_to(tx, centery+th)
            cx.show_text(yval)
Ejemplo n.º 46
0
    def _renderAxis(self, cx):
        """Renders the axis for radar charts"""
        if self.options.axis.x.hide or not self.xticks:
            return

        self.xlabels = []

        if self.debug:
            px = max(cx.device_to_user_distance(1, 1))
            cx.set_source_rgba(0, 0, 1, 0.5)
            for x, y, w, h in self.layout.ticks:
                cx.rectangle(x, y, w, h)
                cx.stroke()
                cx.arc(x + w / 2.0, y + h / 2.0, 5 * px, 0, 2 * math.pi)
                cx.fill()
                cx.arc(x, y, 2 * px, 0, 2 * math.pi)
                cx.fill()

        cx.select_font_face(self.options.axis.labelFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.labelFontSize)

        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i, tick in enumerate(self.xticks):
            label = tick[1]
            x, y, w, h = self.layout.ticks[i]

            xb, yb, width, height, xa, ya = cx.text_extents(label)

            # draw label with text tick[1]
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            self.xlabels.append(label)
            
        # Draw y-axis

        centerx = self.layout.chart.x + self.layout.chart.w * 0.5
        centery = self.layout.chart.y + self.layout.chart.h * 0.5

        cr = self.layout.radius / float(self.slice)
        
        cx.set_line_width(self.options.axis.lineWidth)
        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))

        if self.frame == 'circle':
            for i in range(self.slice):
                cx.move_to(centerx, centery)
                cx.arc(centerx, centery, (i+1) * cr, 0, 2*math.pi)
        else:
            for i in range(self.slice):
                for j, angle in enumerate(self.layout.angles):
                    x = centerx + math.cos(angle) * (i+1) * cr
                    y = centery + math.sin(angle) * (i+1) * cr

                    if j:
                        cx.line_to(x, y)
                    else:
                        cx.move_to(x, y)

                cx.close_path()

        cx.stroke()

        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)
        cx.set_source_rgb(*hex2rgb(self.options.axis.labelColor))

        for i in range(self.slice):
            yval = "%.1f" % (self.maxyval / self.slice * (i+1))
            tw, th = get_text_extents(cx, yval, self.options.axis.tickFont, self.options.axis.tickFontSize, self.options.encoding)
            tx = centerx + (i+1) * cr - tw

            cx.move_to(tx, centery+th)
            cx.show_text(yval)