Beispiel #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))
            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()
Beispiel #2
0
    def _renderAxis(self, cx):
        """Renders axis"""
        if self.options.axis.x.hide and self.options.axis.y.hide:
            return

        cx.save()
        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)

            cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
            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)

            cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
            self._renderXAxis(cx)

        cx.restore()
Beispiel #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))
            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()
Beispiel #4
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()
Beispiel #5
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)
Beispiel #6
0
    def _renderTick(self, cx, tick, x, y, x2, y2, rotate, text_position):
        """Aux method for _renderXTick and _renderYTick"""
        if callable(tick):
            return

        cx.new_path()
        cx.move_to(x, y)
        cx.line_to(x2, y2)
        cx.close_path()
        cx.stroke()
        cx.set_source_rgb(*hex2rgb('#000000'))
        cx.select_font_face(self.options.axis.tickFont,
                            cairo.FONT_SLANT_NORMAL,
                            cairo.FONT_WEIGHT_NORMAL)
        cx.set_font_size(self.options.axis.tickFontSize)

        label = safe_unicode(tick[1], self.options.encoding)
        xb, yb, width, height, xa, ya = cx.text_extents(label)

        x, y = text_position

        if rotate:
            cx.save()
            cx.translate(x, y)
            cx.rotate(math.radians(rotate))
            x = -width / 2.0
            y = -height / 2.0
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
            if self.debug:
                cx.rectangle(x, y, width, height)
                cx.stroke()
            cx.restore()
        else:
            x -= width / 2.0
            y -= height / 2.0
            cx.move_to(x - xb, y - yb)
            cx.show_text(label)
            cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor))
            if self.debug:
                cx.rectangle(x, y, width, height)
                cx.stroke()

        return label
Beispiel #7
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()
Beispiel #8
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()
Beispiel #9
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()
Beispiel #10
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()
Beispiel #11
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()
Beispiel #12
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] - 10

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

            cx.restore()
Beispiel #13
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()
Beispiel #14
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] - 10

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

            cx.restore()
Beispiel #15
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()
        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)
            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()
Beispiel #16
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()
        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)
            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()