Пример #1
0
 def plot(self, tree, vis):
     add_tag(tree,
             'rect',
             attributes={
                 'x': '0',
                 'y': '0',
                 'width': str(vis.style.width),
                 'height': str(vis.style.height),
                 'fill': vis.style.background_colour
             })
Пример #2
0
    def plot(self):
        tree = root_tag(self.style.width, self.style.height)
        add_tag(tree, 'style', text=self.style.css)

        for element in self.chart.elements:
            element.plot(tree, self)

        self.chart.plot(tree, self)

        for element in self.elements:
            element.plot(tree, self)

        return to_string(tree)
Пример #3
0
    def plot(self, tree, vis):
        if len(vis.data) == 0:
            return tree

        margins = calculate_margins(vis)
        size = calculate_chart_size(vis, margins)

        y_scale = calculate_y_scale(vis.data, vis.style.y_axis_tick_number)

        inner_tree = add_tag(tree, 'svg', attributes={
            'viewBox': f'0 0 {size[0]}, {size[1]}',
            'x': str(margins[0]),
            'y': str(margins[1]),
            'width': str(size[0]),
            'height': str(size[1])
        })

        if isinstance(vis.data, DataSet):
            for i, data in enumerate(vis.data):
                self._plot_line(vis, data, y_scale[-1], size[0], size[1], vis.style.data_colours[i%len(data)], inner_tree)
        elif isinstance(vis.data, Data):
            self._plot_line(vis, vis.data, y_scale[-1], size[0], size[1], vis.style.data_colour, inner_tree)
        else:
            raise Exception
        
        if vis.data.labels:
            for i, label in enumerate(vis.data.labels):
                if not i % vis.style.x_axis_interval:
                    width_per_node = size[0] / (len(vis.data)-1)
                    x = margins[0] + i * width_per_node

                    label_y = margins[1] + size[1] + vis.style.text_styles["x_axis"].size/2
                    add_text(tree, (x, label_y), str(label), vis.style.text_styles['x_axis'])

        return tree
Пример #4
0
    def plot(self, tree, vis):
        if len(vis.data) == 0:
            return tree

        margins = calculate_margins(vis)
        size = calculate_chart_size(vis, margins)

        y_scale = calculate_y_scale(vis.data, vis.style.y_axis_tick_number)

        inner_tree = add_tag(tree, 'svg', attributes={
            'viewBox': f'0 0 {size[0]}, {size[1]}',
            'x': str(margins[0]),
            'y': str(margins[1]),
            'width': str(size[0]),
            'height': str(size[1])
        })

        width_per_bar = size[0] / len(vis.data)
        bar_width = width_per_bar * vis.style.bar_width

        for i, item in enumerate(vis.data):
            height = (item / y_scale[-1]) * size[1]
            centre_x = i * width_per_bar + width_per_bar/2

            add_tag(inner_tree, 'rect', attributes={
                'width': str(bar_width),
                'height': str(height),
                'x': str(centre_x - bar_width/2),
                'y': str(size[1] - height),
                'class': 'data_colour'
            })

            if vis.style.show_values == 'all' or (vis.style.show_values == 'limits' and
                    (item == vis.data.max or item == vis.data.min)):
                label_y = size[1] - height - vis.style.text_styles["value"].size/2
                add_text(tree, (margins[0] + centre_x, margins[1] + label_y), str(item), vis.style.text_styles['value'])

            if vis.data.labels:
                if not i % vis.style.x_axis_interval:
                    label_y = size[1] + vis.style.text_styles["x_axis"].size/2
                    add_text(tree, (margins[0] + centre_x, margins[1] + label_y), str(vis.data.labels[i]), vis.style.text_styles['x_axis'])

        return tree
Пример #5
0
    def plot(self, tree, vis):
        margins = calculate_margins(vis)
        size = calculate_chart_size(vis, margins)
        size = (size[0] + 1, size[1] + 1)

        y_scale = calculate_y_scale(vis.data, vis.style.y_axis_tick_number)

        inner_tree = add_tag(tree,
                             'svg',
                             attributes={
                                 'viewBox': f'0 0 {size[0]}, {size[1]}',
                                 'x': str(margins[0] - 1),
                                 'y': str(margins[1]),
                                 'width': str(size[0]),
                                 'height': str(size[1])
                             })

        for i in range(1, len(y_scale)):
            y_pos = size[1] - i * size[1] / (len(y_scale) - 1)
            if vis.style.show_grid_lines:
                add_tag(inner_tree,
                        'line',
                        attributes={
                            'x1': '0',
                            'x2': str(size[0]),
                            'y1': str(y_pos),
                            'y2': str(y_pos),
                            'class': 'grid_lines'
                        })

        # Axes

        add_tag(inner_tree,
                'line',
                attributes={
                    'x1': str(0),
                    'x2': str(0),
                    'y1': str(size[1]),
                    'y2': str(0),
                    'class': 'axis'
                })

        add_tag(inner_tree,
                'line',
                attributes={
                    'x1': str(0),
                    'x2': str(size[0]),
                    'y1': str(size[1]),
                    'y2': str(size[1]),
                    'class': 'axis'
                })

        for i, label in enumerate(y_scale):
            y_pos = margins[0] + size[1] - i * size[1] / (len(y_scale) - 1)
            add_text(tree, (margins[0] - 5, y_pos), str(label),
                     vis.style.text_styles['y_axis'])
Пример #6
0
    def _plot_line(self, vis, data, max_value, plot_width, plot_height, colour, tree):
        width_per_node = plot_width / (len(data)-1)
        points = []

        for i, item in enumerate(data):
            x = i * width_per_node
            y = plot_height - (item / max_value) * plot_height
            points.append((x, y))

            if vis.style.show_values == 'all' or (vis.style.show_values == 'limits' and
                    (item == data.max or item == data.min)):
                label_y = y - vis.style.text_styles["value"].size/2

                add_text(tree, (x, label_y), str(item), vis.style.text_styles['value'])

        add_tag(tree, 'polyline', attributes={
            'points': ' '.join([f'{str(point[0])}, {str(point[1])}' for point in points]),
            'fill': 'none',
            'stroke': colour,
            'class': 'line_chart_data_line'
        })
Пример #7
0
    def plot(self, tree, vis):
        if len(vis.data) == 0:
            return tree

        # Left, Right
        plot_x = (vis.style.width * vis.style.margin[0],
                  vis.style.width * vis.style.margin[2])
        # Up, Down
        plot_y = (vis.style.height * vis.style.margin[1],
                  vis.style.height * vis.style.margin[3])

        plot_width = vis.style.width - plot_x[0] - plot_x[1]
        plot_height = vis.style.height - plot_y[0] - plot_y[1]

        # Plot pie

        angles = self._calculate_angles(vis.data)
        centre = (plot_x[0] + plot_width / 2, plot_y[0] + plot_height / 2)
        radius = min(plot_width, plot_height) / 2 * 0.9
        value_radius = radius * vis.style.pie_value_radius

        # SVG paths can't draw full circle. Backtrack to a circle if we
        # get too close
        if len(vis.data) == 1 or max(angles) > 1.99 * math.pi:
            add_tag(tree,
                    'circle',
                    attributes={
                        'cx': str(centre[0]),
                        'cy': str(centre[1]),
                        'r': str(radius),
                        'fill': vis.style.data_colours[0]
                    })
        else:
            x = centre[0]
            y = centre[1] - radius
            angle = 0

            for i, item in enumerate(vis.data):
                (old_x, old_y) = (x, y)
                angle += angles[i]
                x = centre[0] + radius * math.sin(angle)
                y = centre[1] + -(radius * math.cos(angle))
                big = 1 if angles[i] > math.pi else 0

                add_tag(
                    tree,
                    'path',
                    attributes={
                        'd':
                        f'M{centre[0]},{centre[1]} L{old_x},{old_y} A{radius},{radius} 0 {big},1 {x},{y} Z',
                        'fill':
                        vis.style.data_colours[(i % len(vis.data)) %
                                               len(vis.style.data_colours)]
                    },
                    text=str((angles[i], angle)))

            angle = 0
            for i, item in enumerate(vis.data):
                angle += angles[i] / 2
                x = centre[0] + value_radius * math.sin(angle)
                y = centre[1] + -(value_radius * math.cos(angle))

                css_class = '_'
                if angle < math.pi / 2 or angle > math.pi * 6 / 4:
                    css_class += 'upper'
                else:
                    css_class += 'lower'
                if angle < math.pi:
                    css_class += '_left'
                else:
                    css_class += '_right'

                add_text(tree, (x, y), str(item),
                         vis.style.text_styles['circle_value'], css_class)

                angle += angles[i] / 2

        add_tag(tree,
                'circle',
                attributes={
                    'cx': str(centre[0]),
                    'cy': str(centre[1]),
                    'r': str(radius * vis.style.pie_inner_radius),
                    'fill': vis.style.background_colour
                })

        return tree