示例#1
0
    def create_chart(self):
        c = PieChart(self.layout_data['chart_object_size_x'],
                     self.layout_data['chart_object_size_y'],
                     FontManager.get_db_color(self.layout_data['background_color']),
                     FontManager.get_db_color(self.layout_data['border_color']),
                     0)

        # make pretty fonts
        c.setAntiAlias(True, AntiAlias)

        labels = self.chart_data['formatted_header']

        try:
            c.setData(self.chart_data['data'], labels)
        except TypeError:
            raise Exception("Chart %s misconfigured. Sector Values must contain numeric values." % self.report_data_set_chart_id)

        # colors for sectors for the pie chart
        if self.chart_data['colors']:
            c.setColors2(DataColor, self.chart_data['colors'])

        # set chart title
        if self.layout_data['include_title_ind'] == 'Y':
            c.addTitle(self.layout_data['name'],
                        FontManager.get_db_font(self.layout_data['title_font']),
                        self.layout_data['title_font_size'],
                        self.layout_data['title_font_color'])
        # define center coordinates
        if not self.layout_data['pie_chart_center_x_coord']:
            self.layout_data['pie_chart_center_x_coord'] = self.layout_data['chart_object_size_x'] // 2

        if not self.layout_data['pie_chart_center_y_coord']:
            self.layout_data['pie_chart_center_y_coord'] = self.layout_data['chart_object_size_y'] // 2

        # define radius
        if not self.layout_data['pie_chart_radius']:
            if self.layout_data['chart_object_size_y'] > self.layout_data['chart_object_size_x']:
                smallest_side = self.layout_data['chart_object_size_x']
            else:
                smallest_side = self.layout_data['chart_object_size_y']
            self.layout_data['pie_chart_radius'] = int(smallest_side // 2 * 0.7)
            # reduce radius for preview chart
            if self.settings['type'] == 'preview':
                #self.layout_data['pie_chart_radius'] = self.layout_data['pie_chart_radius'] * 0.9
                self.layout_data['pie_chart_radius'] *= 0.9

        # set pie position and radius
        c.setPieSize(self.layout_data['pie_chart_center_x_coord'], self.layout_data['pie_chart_center_y_coord'], self.layout_data['pie_chart_radius'])

        # 3D chart settings
        if self.layout_data['pie_chart_type'] == '3D':
            # if depth not specified use default
            if not self.layout_data['pie_chart_depth']:
                self.layout_data['pie_chart_depth'] = -1
            # if start angle not specified use default
            if not self.layout_data['pie_chart_display_angle']:
                self.layout_data['pie_chart_display_angle'] = -1
            c.set3D(self.layout_data['pie_chart_depth'], self.layout_data['pie_chart_display_angle'])

        # start angle
        if not self.layout_data['pie_chart_start_angle']:
            self.layout_data['pie_chart_start_angle'] = 0
        c.setStartAngle(self.layout_data['pie_chart_start_angle'])

        # set labels position formats
        if self.settings['type'] == 'preview':
            label_pos = 5
        else:
            label_pos = 15
        c.setLabelLayout(SideLayout, label_pos)

        # label font color
        if self.settings['type'] == 'thumbnail':
            self.layout_data['pie_chart_sector_label_font_color'] = Transparent
        else:
            if self.layout_data['pie_chart_sector_label_font_color']:
                # use specified color
                self.layout_data['pie_chart_sector_label_font_color'] = FontManager.get_db_color(self.layout_data['pie_chart_sector_label_font_color'])
            else:
                # same as sector color
                self.layout_data['pie_chart_sector_label_font_color'] = SameAsMainColor

        t = c.setLabelStyle(FontManager.get_db_font(self.layout_data['pie_chart_sector_label_font']),
                            self.layout_data['pie_chart_sector_label_font_size'],
                            self.layout_data['pie_chart_sector_label_font_color'])
        if self.settings['type'] == 'preview' or self.settings['type'] == 'large':
            max_label_width = (self.layout_data['chart_object_size_x'] - self.layout_data['pie_chart_radius'] * 2 - label_pos * 2) / 2
            t.setMaxWidth(max_label_width)

        if self.settings['type'] == 'thumbnail':
            fill_label_color = Transparent
            sector_label_border_color = Transparent
        else:
            if self.layout_data['use_sector_color_for_Label_fill_ind'] == 'Y':
                # same as sector color
                fill_label_color = SameAsMainColor
            else:
                # no background
                fill_label_color = Transparent
            if self.layout_data['sector_label_border_color']:
                # use specified color
                sector_label_border_color = FontManager.get_db_color(self.layout_data['sector_label_border_color'])
            else:
                # no border
                sector_label_border_color = Transparent
        # set label background and border color
        t.setBackground(fill_label_color, sector_label_border_color)

        # rounded corners of labels
        if self.layout_data['sector_label_corner_style'] == 'Rounded':
            t.setRoundedCorners()

        # join line format
        if self.settings['type'] == 'thumbnail':
            # do not draw line
            join_line_color = Transparent
        else:
            if self.layout_data['sector_label_join_line_color']:
                # use specified color
                join_line_color = FontManager.get_db_color(self.layout_data['sector_label_join_line_color'])
            else:
                # use sector color
                join_line_color = SameAsMainColor

        c.setJoinLine(join_line_color)

        # shading format
        if self.layout_data['pie_chart_shading'] == 'Rounded Edge':
            shading = RoundedEdgeShading
        elif self.layout_data['pie_chart_shading'] == 'Flat Gradient' and self.layout_data['pie_chart_type'] == '3D':
            shading = FlatShading
        else:
            shading = DefaultShading

        # explode sectors
        if self.layout_data['explode_all_pie_sectors'] == 'all' or \
             (self.layout_data['explode_all_pie_sectors'] == '2D' and self.layout_data['pie_chart_type'] == '2D') or \
              (self.layout_data['explode_all_pie_sectors'] == '3D' and self.layout_data['pie_chart_type'] == '3D'):
            if not self.layout_data['pie_sectors_explode_width']:
                self.layout_data['pie_sectors_explode_width'] = 0
            # reduce border width for small images
            if self.settings['type'] != 'large':
                #self.layout_data['pie_sectors_explode_width'] = self.layout_data['pie_sectors_explode_width'] / 2
                self.layout_data['pie_sectors_explode_width'] /= 2

            c.setExplode(-1, self.layout_data['pie_sectors_explode_width'])
            self.layout_data['pie_chart_sector_border_width'] = 0
            self.layout_data['sector_edge_line_color'] = ''

        # sector border(edge) color
        if self.layout_data['sector_edge_line_color']:
            # use specified color
            edge_line_color = FontManager.get_db_color(self.layout_data['sector_edge_line_color'])
        else:
            # use sector color
            edge_line_color = SameAsMainColor

        # sector border(edge) width
        if not self.layout_data['pie_chart_sector_border_width']:
            self.layout_data['pie_chart_sector_border_width'] = 0

        # reduce border with for small images
        if self.settings['type'] != 'large':
            #self.layout_data['pie_chart_sector_border_width'] = self.layout_data['pie_chart_sector_border_width'] / 2
            self.layout_data['pie_chart_sector_border_width'] /= 2

        c.setSectorStyle(shading, edge_line_color, self.layout_data['pie_chart_sector_border_width'])

        # number of digits after point for % value
        if not self.layout_data['sector_value_pct_precision_digits']:
            self.layout_data['sector_value_pct_precision_digits'] = 0

        # label color
        if self.layout_data['pie_chart_sector_value_font_color']:
            self.layout_data['pie_chart_sector_value_font_color'] = FontManager.get_db_color(self.layout_data['pie_chart_sector_value_font_color'])
        else:
            self.layout_data['pie_chart_sector_value_font_color'] = None

        # label format
        if self.layout_data['show_sector_value_ind'] == 'Y':
            # show label, percentage and value in label
            c.addExtraField(self.chart_data['formatted_data'])
            label_format = "<*block*><*font=%s,size=%s,color=%s*>{label}<*br*>{field0} ({percent|%s}%%)<*/*>"
        else:
            # show label and percentage in label
            label_format = "<*block*><*font=%s,size=%s,color=%s*>{label}<*br*>({percent|%s}%%)<*/*>"

        # sector value font size
        if not self.layout_data['pie_chart_sector_value_font_size'] or self.layout_data['pie_chart_sector_value_font_size'] < 3:
            self.layout_data['pie_chart_sector_value_font_size'] = 8

        #reduce label font size for preview images
        if self.settings['type'] == 'preview':
            self.layout_data['pie_chart_sector_value_font_size'] = 8

        if self.layout_data['pie_chart_sector_value_font_color'] is not None:
            # if label color is specified, use it for all labels
            c.setLabelFormat(label_format % (
                                    FontManager.get_db_font(self.layout_data['pie_chart_sector_value_font']),
                                    self.layout_data['pie_chart_sector_value_font_size'],
                                    self.layout_data['pie_chart_sector_value_font_color'],
                                    self.layout_data['sector_value_pct_precision_digits']))
        else:
            # if label color is not specified, use color of sector
            for i, color in enumerate(self.chart_data['colors']):
                c.sector(i).setLabelFormat(label_format % (
                                    FontManager.get_db_font(self.layout_data['pie_chart_sector_value_font']),
                                    self.layout_data['pie_chart_sector_value_font_size'],
                                    hex(color),
                                    self.layout_data['sector_value_pct_precision_digits']))

        # draw annotations
        if self.settings['type'] == 'large':
            c.layout()
            index = 1
            for i, header in enumerate(self.chart_data['formatted_header']):
                if self.chart_data['annotations'][header]:
                    sector = c.getSector(i)
                    coord_string = sector.getLabelCoor()

                    content = urllib.unquote(coord_string)

                    res = re.findall(r'shape="rect" coords="(.+?),(.+?),(.+?),(.+?)"', content)
                    coords = res[0]

                    x_coord = (int(coords[2]) + int(coords[0])) / 2
                    y_coord = int(coords[1]) + 25

                    annot_marker = "<*img=%s*>" % self.config.resource_file('annotation.png')
                    c.addText(x_coord, y_coord, annot_marker, "", 0, 0x0, BottomCenter)
                    c.addText(x_coord, y_coord - 32, str(index), FontManager.get_default_bold_font(), 10, 0xffffff, BottomCenter)
                    for annot in self.chart_data['annotations'][header]:
                        annot['index'] = index
                        annot['shape'] = 'rect'
                        annot['chart_by_column_value'] = header
                        annot['chart_element_identifier'] = ''
                        annot['value'] = self.chart_data['formatted_data'][self.chart_data['header'].index(header)]
                        marker_coors = [x_coord - 9, y_coord - 47, x_coord + 10, y_coord - 29]
                        annot['coords'] = ','.join(map(str, marker_coors))
                        annot['annotation_interval'] = 'point'
                        annot['start_time'] = ''
                        annot['finish_time'] = ''
                        annot['raw_start_time'] = ''
                        annot['raw_finish_time'] = ''
                        self.annotations_map.append(annot)
                    index += 1

        filename = ''
        if self.settings['type'] == 'large':
            filename = self._jfile.get_chart_file_name(self.report_data_set_chart_id, self.report_data_set_instance_id)
        elif self.settings['type'] == 'thumbnail':
            filename = self._jfile.get_thumbnail_file_name()
        elif self.settings['type'] == 'preview':
            filename = self._jfile.get_preview_file_name()

        if not c.makeChart(filename):
            raise Exception("ChartDirector cannot create image file %s for chart %s." % (filename, self.report_data_set_chart_id))
        self.file_man.change_perm(filename)

        self.chart_object = c
示例#2
0
    def _get_chart_settings(self):
        """ getting data for layout"""
        self._db.Query("""SELECT
                                dashboard_element.metric_show_max_ever_on_chart_ind,
                                dashboard_element.metric_show_min_ever_on_chart_ind,
                                dashboard_element.name,
                                dashboard_element.metric_display_label,

                                chart_display_format.chart_object_size_x,
                                chart_display_format.chart_object_size_y,
                                chart_display_format.plot_area_x_coord,
                                chart_display_format.plot_area_y_coord,
                                chart_display_format.plot_area_width,
                                chart_display_format.plot_area_height,
                                chart_display_format.title_font_id,
                                chart_display_format.title_font_size,
                                chart_display_format.legend_x_coord,
                                chart_display_format.legend_y_coord,
                                chart_display_format.max_bar_data_points_to_chart,
                                chart_display_format.max_line_data_points_to_chart,
                                chart_display_format.max_x_axis_labels,
                                chart_display_format.include_title_ind,
                                
                                chart_layout.background_color,
                                chart_layout.bar_shape,
                                chart_layout.bar_soft_lighting_direction,
                                chart_layout.border_color,
                                chart_layout.current_value_dot_color,
                                chart_layout.current_value_dot_size,
                                chart_layout.current_value_font_id,
                                chart_layout.current_value_font_size,
                                chart_layout.data_gap_line_type,
                                chart_layout.highlight_current_value_ind,
                                chart_layout.include_legend_ind,
                                chart_layout.include_x_axis_label_ind,
                                chart_layout.include_y_axis_label_ind,
                                chart_layout.legend_background_color,
                                chart_layout.legend_font_id,
                                chart_layout.legend_font_size,
                                chart_layout.line_data_point_dot_size,
                                chart_layout.line_width,
                                chart_layout.metric_bar_color,
                                chart_layout.metric_line_color,
                                
                                chart_layout.bar_gap,
                                chart_layout.bar_group_gap,
                                chart_layout.show_expired_zone_ind,
                                chart_layout.expired_zone_color,
                                
                                chart_layout.min_max_ever_font_id,
                                chart_layout.min_max_ever_font_size,
                                chart_layout.min_max_ever_line_color,
                                chart_layout.min_max_ever_line_type,
                                chart_layout.min_max_ever_line_width,

                                chart_layout.month_display_format,
                                chart_layout.plot_area_background_color,
                                chart_layout.plot_area_background_color_ind,
                                chart_layout.plot_area_horizontal_grid_color,
                                chart_layout.plot_area_vertical_grid_color,
                                chart_layout.show_line_data_points_ind,
                                chart_layout.show_plot_area_grid_ind,
                                chart_layout.title_font_color,
                                chart_layout.x_axis_label_font_color,
                                chart_layout.x_axis_label_font_id,
                                chart_layout.x_axis_label_font_size,
                                chart_layout.x_axis_tick_mark_position,
                                chart_layout.y_axis_font_color,
                                chart_layout.y_axis_font_id,
                                chart_layout.y_axis_font_size,
                                chart_layout.data_gap_line_type,

                                chart_layout.metric_moving_average_line_color,
                                chart_layout.moving_average_line_width,

                                chart_display_format.include_title_ind,
                                
                                chart_layout.metric_stoplight_good_range_start_color,
                                chart_layout.metric_stoplight_good_range_end_color,
                                chart_layout.metric_stoplight_bad_range_start_color,
                                chart_layout.metric_stoplight_bad_range_end_color,
                                
                                chart_layout.metric_stoplight_good_mark_color,
                                chart_layout.metric_stoplight_bad_mark_color,

                                dashboard_element.type,
                                dashboard_element.max_time_before_expired_sec,
                                dashboard_element.metric_start_y_axis_from_zero_ind AS start_y_axis_from_zero_ind,
                                chart_layout_id
                            FROM dashboard_element
                            LEFT JOIN chart_layout
                            ON chart_layout.layout_id = dashboard_element.chart_layout_id
                            LEFT JOIN chart_display_format
                            ON chart_display_format.chart_display_format_id = chart_layout.chart_display_format_id
                            WHERE element_id=%s
                        """, (self.metric_id, ))
        data = self._db.record[0]
        
        if data['type'] == 'metric':
            self.metric_type = 'single'

        #special settings for preview and thumbnail
        
        data['include_min_max_ever_ind'] = 'Y'
        data['include_compare_ind'] = 'Y'
        data['include_average_ind'] = 'Y'
        data['include_annotations_ind'] = 'Y'
        
        if self.type != 'large':
            data['include_min_max_ever_ind'] = 'N'
            data['include_compare_ind'] = 'N'
            data['include_average_ind'] = 'N'
            data['include_annotations_ind'] = 'N'
            if self.type == 'thumbnail':
                data['show_plot_area_grid_ind'] = 'N'
                data['show_line_data_points_ind'] = 'N'
                data['include_title_ind'] = 'N'
                data['include_legend_ind'] = 'N'
                data['include_x_axis_label_ind'] = 'N'
                data['include_y_axis_label_ind'] = 'N'
                if self.metric_type == 'single':
                    self._db.Query("""SELECT *
                                        FROM chart_display_format
                                        WHERE metric_thumbnail_display_format_ind = 'Y'""")
                else:
                    self._db.Query("""SELECT *
                                        FROM chart_display_format
                                        WHERE multi_metric_thumbnail_display_format_ind = 'Y'""")
                    
            elif self.type == 'preview':
                self._db.Query("""    SELECT *
                                    FROM chart_display_format
                                    WHERE preview_display_format_ind = 'Y'""")
            chart_display_format = self._db.record[0]
            for k, v in chart_display_format.iteritems():
                data[k] = v

        if data['bar_gap'] is None:
            data['bar_gap'] = 0
        if data['bar_group_gap'] is None:
            data['bar_group_gap'] = 0

        #if not data.has_key('chart_layout_id') or not data['chart_layout_id']:
        if 'chart_layout_id' not in data or not data['chart_layout_id']:
            raise Exception("missing chart_layout_id")

        if data['include_legend_ind'] == 'Y':
            self._db.Query("""SELECT * FROM font
                                WHERE font_id=%s""", (data['legend_font_id']))
            data['legend_font'] = self._db.record[0]

        if data['include_x_axis_label_ind'] == 'Y':
            # getting font for x axis label
            self._db.Query("""SELECT * FROM font
                                WHERE font_id=%s""", (data['x_axis_label_font_id']))
            data['x_axis_label_font'] = self._db.record[0]

        # getting font for y axis label
        if data['include_y_axis_label_ind'] == 'Y':
            self._db.Query("""SELECT * FROM font
                                WHERE font_id=%s""", (data['y_axis_font_id']))
            data['y_axis_label_font'] = self._db.record[0]

        # getting font for values
        self._db.Query("""SELECT * FROM font
                            WHERE font_id=%s""", (data['current_value_font_id']))
        data['current_value_font'] = self._db.record[0]

        # getting font for title
        if data['include_title_ind'] == 'Y':
            self._db.Query("""SELECT * FROM font
                                WHERE font_id=%s""", (data['title_font_id']))
            data['title_font'] = self._db.record[0]
            if data['title_font_color']:
                data['title_font_color'] = FontManager.get_db_color(data['title_font_color'])
            else:
                data['title_font_color'] = 0xffffff

        # getting styles for min max ever lines
        if data['include_min_max_ever_ind'] == 'Y':
            self._db.Query("""SELECT * FROM font
                                WHERE font_id=%s""", (data['min_max_ever_font_id']))
        
            data['min_max_ever_font'] = self._db.record[0]
        # emulate flip axes property for compatibility with report charts
        data['flip_x_and_y_axis'] = 'N'

        return data
示例#3
0
    def create_chart(self):
        """
        Main function for creating chart
        """
        self._create_plot_area()

        if not self.inited:
            self._prepare_x_scale_values()
        self._set_x_axis_props()
        self._set_y_axis_props()

        self._set_x_axis_date_scale()

        self._create_layers(is_stacked=False)

        # GOOD area start color
        if self.settings["show_stop_light"]:
            # GOOD whisker mark color
            if self.layout_data["metric_stoplight_good_mark_color"] is None:
                self.layout_data["metric_stoplight_good_mark_color"] = 0x00FF00
            else:
                self.layout_data["metric_stoplight_good_mark_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_good_mark_color"]
                )

            # BAD whisker mark color
            if self.layout_data["metric_stoplight_bad_mark_color"] is None:
                self.layout_data["metric_stoplight_bad_mark_color"] = 0xFF0000
            else:
                self.layout_data["metric_stoplight_bad_mark_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_bad_mark_color"]
                )

            # GOOD area start color
            if self.layout_data["metric_stoplight_good_range_start_color"] is None:
                self.layout_data["metric_stoplight_good_range_start_color"] = 0xA0DEFACC
            else:
                self.layout_data["metric_stoplight_good_range_start_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_good_range_start_color"]
                )

            # GOOD area end color
            if self.layout_data["metric_stoplight_good_range_end_color"] is None:
                self.layout_data["metric_stoplight_good_range_end_color"] = 0xA000FF00
            else:
                self.layout_data["metric_stoplight_good_range_end_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_good_range_end_color"]
                )

            # BAD area start color
            if self.layout_data["metric_stoplight_bad_range_start_color"] is None:
                self.layout_data["metric_stoplight_bad_range_start_color"] = 0xA0F0C9C9
            else:
                self.layout_data["metric_stoplight_bad_range_start_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_bad_range_start_color"]
                )

            # BAD area end color
            if self.layout_data["metric_stoplight_bad_range_end_color"] is None:
                self.layout_data["metric_stoplight_bad_range_end_color"] = 0xA0FF0000
            else:
                self.layout_data["metric_stoplight_bad_range_end_color"] = FontManager.get_db_color(
                    self.layout_data["metric_stoplight_bad_range_end_color"]
                )

        compare_lines = list()
        # if self.chart_data.has_key('compare_lines') and self.chart_data['compare_lines']:
        if "compare_lines" in self.chart_data and self.chart_data["compare_lines"]:
            for compare_line in self.chart_data["compare_lines"]:
                compare_lines.append("compare_settings_%s" % compare_line)

        bar_ind = -1

        # iterate metrics. metric_id: metric id, _v: metric data
        for metric_id, metric_elements in self.chart_data["rows"].iteritems():
            # iterate metric elements
            for element_type, element_data in metric_elements.iteritems():
                if element_data is not None:
                    shape = None
                    if element_type == "max_ever_settings" or element_type == "min_ever_settings":
                        element_data["line_type"] = self.layout_data["min_max_ever_line_type"]
                        element_data["display_type"] = "line"
                        element_data["color"] = FontManager.get_db_color(self.layout_data["min_max_ever_line_color"])

                    # if element_data.has_key('axis_number') and element_data['axis_number'] == '2':
                    if "axis_number" in element_data and element_data["axis_number"] == "2":
                        axis = self.c.yAxis2()
                        curr_axis = 1
                    else:
                        curr_axis = 0
                        axis = self.c.yAxis()

                    # set color and line type dash/dot/solid
                    # if not element_data.has_key('line_type'):
                    if "line_type" not in element_data:
                        element_data["line_type"] = ""
                    color = self._get_element_color(
                        element_data["display_type"], element_data["line_type"], element_data["color"]
                    )

                    if element_type == "max_ever_settings" or element_type == "min_ever_settings":
                        # draw max/min ever mark
                        element_data["line_type"] = self.layout_data["min_max_ever_line_type"]
                        element_data["display_type"] = "line"
                        element_data["color"] = FontManager.get_db_color(self.layout_data["min_max_ever_line_color"])
                        mark = axis.addMark(
                            element_data["data"][0],
                            element_data["color"],
                            element_data["label"],
                            FontManager.get_db_font(self.layout_data["min_max_ever_font"]),
                            self.layout_data["min_max_ever_font_size"],
                        )
                        mark.setLineWidth(self.layout_data["min_max_ever_line_width"])
                        mark.setAlignment(TopLeft)
                        mark.setDrawOnTop(False)
                    elif element_type == "stop_light":
                        # draw invisible stop light lines to make this areas visible (included in charting view)
                        if self.chart_data["show_stop_light"] and self.settings["type"] == "large":
                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.datasets[self.layers_count][1] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 1
                            self.layers_count += 1

                            stop_light_area_line = self.c.addSplineLayer()
                            stop_light_area_line.setXData(self._x_axis_data)
                            stop_light_area_line.setUseYAxis(axis)
                            stop_light_area_line.addDataSet(element_data["bad"], Transparent)
                            stop_light_area_line.addDataSet(element_data["good"], Transparent)

                            stop_light_type = "line"

                            # if chart is bar type and show stop light is True
                            if (
                                self.chart_data["rows"][metric_id]["data_settings"]["display_type"] == "bar"
                                and self.settings["show_stop_light"]
                            ):
                                stop_light_type = "bar"

                                bad_stop_light_box = self.c.addBoxWhiskerLayer(
                                    None,
                                    None,
                                    None,
                                    None,
                                    element_data["bad"],
                                    -1,
                                    self.layout_data["metric_stoplight_bad_mark_color"],
                                )

                                bad_stop_light_box.setLineWidth(2)
                                bad_stop_light_box.setXData(self._x_axis_data)
                                bad_stop_light_box.setUseYAxis(axis)
                                bad_stop_light_box.moveFront()

                                good_stop_light_box = self.c.addBoxWhiskerLayer(
                                    None,
                                    None,
                                    None,
                                    None,
                                    element_data["good"],
                                    -1,
                                    self.layout_data["metric_stoplight_good_mark_color"],
                                )
                                good_stop_light_box.setLineWidth(2)
                                good_stop_light_box.setXData(self._x_axis_data)
                                good_stop_light_box.setUseYAxis(axis)
                                good_stop_light_box.moveFront()

                                self.datasets[self.layers_count] = dict()
                                self.datasets[self.layers_count][0] = {
                                    "metric_id": metric_id,
                                    "metric_data": element_type,
                                    "type": "good_stop_light",
                                    "shape": "",
                                }
                                self.dataset_ids[self.layers_count] = 0
                                self.layers_count += 1

                                self.datasets[self.layers_count] = dict()
                                self.datasets[self.layers_count][0] = {
                                    "metric_id": metric_id,
                                    "metric_data": element_type,
                                    "type": "good_stop_light",
                                    "shape": "",
                                }
                                self.dataset_ids[self.layers_count] = 0
                                self.layers_count += 1

                            # add title to legend box
                            if self.layout_data["include_legend_ind"] == "Y" and self.settings["show_stop_light"]:
                                if stop_light_type == "bar":
                                    good_color = self.layout_data["metric_stoplight_good_mark_color"]
                                    bad_color = self.layout_data["metric_stoplight_bad_mark_color"]
                                else:
                                    good_color = self.layout_data["metric_stoplight_good_range_end_color"]
                                    bad_color = self.layout_data["metric_stoplight_bad_range_end_color"]
                                # add GOOD/BAD title to legend box
                                l_legend = self.legend_layer.addDataSet(list(), bad_color, u"Bad Area")
                                l_legend.setDataLabelStyle(self.legend_font, self.legend_font_size, Transparent)
                                l_legend.setLineWidth(0)
                                l_legend.setDataSymbol4(self._cSquareSymbol, 15, bad_color, -1)

                                l_legend = self.legend_layer.addDataSet(list(), good_color, u"Good Area")
                                l_legend.setLineWidth(0)
                                l_legend.setDataSymbol4(self._cSquareSymbol, 15, good_color, -1)
                    else:
                        # draw bar/line chart

                        std_deviation_color = None

                        # hide compare lines for deviation/stoplight chart
                        if element_type in compare_lines and (
                            self.settings["show_std_deviation"] or self.settings["show_stop_light"]
                        ):
                            color = Transparent
                        # chart average line
                        if element_type == "average_settings":
                            # hide average line if it should be shown on main chart
                            if not element_data["show_moving_average"] and not self.settings["show_std_deviation"]:
                                color = Transparent

                            # chart standard deviation area
                            if element_data["show_std_deviation"]:
                                # hide deviation lines for main chart
                                if not self.settings["show_std_deviation"]:
                                    std_deviation_color = Transparent
                                else:
                                    std_deviation_color = color + 0xA0000000

                                min_deviation = list()
                                max_deviation = list()
                                for i, avg in enumerate(element_data["data"]):
                                    if avg == NoValue or element_data["std_deviation_data"][i] is None:
                                        min_deviation.append(NoValue)
                                        max_deviation.append(NoValue)
                                    else:
                                        min_deviation.append(
                                            avg
                                            - element_data["metric_unusual_value_std_dev"]
                                            * element_data["std_deviation_data"][i]
                                        )
                                        max_deviation.append(
                                            avg
                                            + element_data["metric_unusual_value_std_dev"]
                                            * element_data["std_deviation_data"][i]
                                        )

                                top_line = self.c.addLineLayer(max_deviation, Transparent)
                                top_line.setUseYAxis(axis)
                                top_line.setXData(self._x_axis_data)

                                bottom_line = self.c.addLineLayer(min_deviation, Transparent)
                                bottom_line.setUseYAxis(axis)
                                bottom_line.setXData(self._x_axis_data)

                                inter_layer = self.c.addInterLineLayer(
                                    top_line.getLine(), bottom_line.getLine(), std_deviation_color
                                )
                                inter_layer.setUseYAxis(axis)

                                self.datasets[self.layers_count] = dict()
                                self.datasets[self.layers_count][0] = {
                                    "metric_id": metric_id,
                                    "metric_data": element_type,
                                    "type": "std_deviation_top_line",
                                    "shape": "",
                                }
                                self.dataset_ids[self.layers_count] = 0
                                self.layers_count += 1

                                self.datasets[self.layers_count] = dict()
                                self.datasets[self.layers_count][0] = {
                                    "metric_id": metric_id,
                                    "metric_data": element_type,
                                    "type": "std_deviation_bottom_line",
                                    "shape": "",
                                }
                                self.dataset_ids[self.layers_count] = 0
                                self.layers_count += 1

                                self.datasets[self.layers_count] = dict()
                                self.datasets[self.layers_count][0] = {
                                    "metric_id": metric_id,
                                    "metric_data": element_type,
                                    "type": "std_deviation_inter_line_area",
                                    "shape": "",
                                }
                                self.dataset_ids[self.layers_count] = 0
                                self.layers_count += 1

                        if element_data["display_type"] == "line":
                            # line chart
                            line_description = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "line_data",
                                "shape": "point",
                            }
                            line_point_description = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "data",
                                "shape": "point",
                            }
                            if element_type == "data_settings" and self.layout_data["show_line_data_points_ind"] == "Y":
                                show_data_points = True
                                shape = self._set_shape(
                                    self.chart_data["rows"][metric_id]["data_settings"]["line_point_shape"]
                                )
                            else:
                                show_data_points = False
                                shape = None

                            # if element_data.has_key('line_width'):
                            if "line_width" in element_data:
                                line_width = element_data["line_width"]
                            else:
                                line_width = None

                            self._create_line_layer(
                                element_data["data"],
                                element_data["line_style"],
                                line_width,
                                color,
                                axis,
                                show_data_points,
                                shape,
                                line_description,
                                line_point_description,
                            )

                        else:
                            # if element_data['display_type'] == 'bar':
                            bar_ind += 1
                            # bar chart
                            self._create_bar_layer(
                                element_data["data"],
                                color,
                                axis,
                                {"metric_id": metric_id, "metric_data": element_type, "type": "data", "shape": "bar"},
                            )

                        # add layer for annotation markers
                        if element_type == "data_settings" and self.layout_data["include_annotations_ind"] == "Y":
                            # process range annotations
                            if not self.inited:
                                # calculate range annotations only if they are not calculated before
                                # this is needed only for charting deviation/stoplight metrics
                                self._collect_range_annotations(
                                    self.chart_data["range_annotations"][metric_id],
                                    curr_axis,
                                    {"metric_id": metric_id, "element_type": element_type},
                                )

                            # draw point annotations
                            self._draw_point_annotations(
                                self.chart_data["point_annotations"][metric_id],
                                element_data["data"],
                                axis,
                                curr_axis,
                                element_data["display_type"],
                                bar_ind,
                                True,
                                {"metric_id": metric_id, "metric_data": element_type, "type": "annotation"},
                            )

                        # add element name to legend box
                        if self.layout_data["include_legend_ind"] == "Y":
                            axis = self.c.yAxis()
                            # do not show legend if compare lines are hidden
                            if element_type in compare_lines and (
                                self.settings["show_std_deviation"] or self.settings["show_stop_light"]
                            ):
                                continue

                            if element_type == "average_settings":
                                if not element_data["show_moving_average"] and not self.settings["show_std_deviation"]:
                                    continue

                            l_legend = self.legend_layer.addDataSet(list(), color, element_data["label"])

                            if element_data["display_type"] == "line":
                                l_legend.setDataSymbol(CircleShape, element_data["line_width"], color, color)

                            l_legend.setUseYAxis(axis)

                            if element_type == "data_settings":
                                if element_data["display_type"] == "line":
                                    # if element_data.has_key('line_width'):
                                    if "line_width" in element_data:
                                        l_legend.setLineWidth(element_data["line_width"])

                                    if self.layout_data["show_line_data_points_ind"] == "Y":
                                        l_legend.setDataSymbol(
                                            shape, self.layout_data["line_data_point_dot_size"], color, color
                                        )
                                    else:
                                        l_legend.setDataSymbol(CircleShape, element_data["line_width"], color, color)
                                elif element_data["display_type"] == "bar":
                                    l_legend.setLineWidth(0)
                                    l_legend.setDataSymbol4(self._cSquareSymbol, 15, color, -1)

                            if (
                                element_type == "average_settings"
                                and self.settings["show_std_deviation"]
                                and element_data["show_std_deviation"]
                            ):
                                l_legend = self.legend_layer.addDataSet(
                                    list(), color, element_data["std_deviation_label"]
                                )
                                l_legend.setLineWidth(0)
                                l_legend.setDataSymbol4(self._cSquareSymbol, 15, std_deviation_color, -1)

        # show expired zone
        if self.chart_data["expired_zone"]:
            self.c.xAxis().addZone(
                chartTime2(float(self.chart_data["expired_zone"]["start"].strftime("%s"))),
                chartTime2(float(self.chart_data["expired_zone"]["end"].strftime("%s"))),
                self.chart_data["expired_zone"]["color"],
            )

        if self.layout_data["include_annotations_ind"] == "Y":
            if self._range_annotations:
                if not self.inited:
                    self._calc_annotations()
                self.draw_range_annotations()

        if not self.inited:
            self.inited = True

        # final scale y axis
        self._set_y_axes_scaling()

        # ensure that plots fit within specified layout dimensions
        self._pack_plot_area()

        # show real stop light ares for line chart
        if self.settings["show_stop_light"]:
            # freeze chart
            self.c.layoutAxes()
            # get max value of y-axis
            max_y_val1 = self.c.yAxis().getMaxValue()
            max_y_val2 = self.c.yAxis2().getMaxValue()

            min_y_val1 = self.c.yAxis().getMinValue()
            min_y_val2 = self.c.yAxis2().getMinValue()

            for metric_id, _v in self.chart_data["rows"].iteritems():
                for element_type, element_data in _v.iteritems():
                    if element_type == "stop_light":
                        # if element_data.has_key('axis_number') and element_data['axis_number'] == '2':
                        if "axis_number" in element_data and element_data["axis_number"] == "2":
                            axis = self.c.yAxis2()
                            max_y_val = max_y_val2
                            min_y_val = min_y_val2
                        else:
                            axis = self.c.yAxis()
                            max_y_val = max_y_val1
                            min_y_val = min_y_val1

                        # for line metric draw GOOD/BAD areas
                        if self.chart_data["rows"][metric_id]["data_settings"]["display_type"] == "line":
                            not_empty_bad = [val for val in element_data["bad"] if val != NoValue]
                            not_empty_good = [val for val in element_data["good"] if val != NoValue]

                            if element_data["metric_more_is_better_ind"] == "Y":
                                top_area = element_data["good"]
                                bottom_area = element_data["bad"]

                                top_start_color = self.layout_data["metric_stoplight_good_range_start_color"]
                                top_end_color = self.layout_data["metric_stoplight_good_range_end_color"]

                                bottom_start_color = self.layout_data["metric_stoplight_bad_range_start_color"]
                                bottom_end_color = self.layout_data["metric_stoplight_bad_range_end_color"]

                                if not_empty_bad:
                                    bottom_largest = max([val for val in element_data["bad"] if val != NoValue])
                                else:
                                    bottom_largest = min_y_val

                                if not_empty_good:
                                    top_smallest = min([val for val in element_data["good"] if val != NoValue])
                                else:
                                    top_smallest = max_y_val
                            else:
                                top_area = element_data["bad"]
                                bottom_area = element_data["good"]

                                top_start_color = self.layout_data["metric_stoplight_bad_range_start_color"]
                                top_end_color = self.layout_data["metric_stoplight_bad_range_end_color"]

                                bottom_start_color = self.layout_data["metric_stoplight_good_range_start_color"]
                                bottom_end_color = self.layout_data["metric_stoplight_good_range_end_color"]

                                if not_empty_good:
                                    bottom_largest = max([val for val in element_data["good"] if val != NoValue])
                                else:
                                    bottom_largest = min_y_val

                                if not_empty_bad:
                                    top_smallest = max([val for val in element_data["bad"] if val != NoValue])
                                else:
                                    top_smallest = max_y_val

                            # bottom area
                            top_line = self.c.addLineLayer(bottom_area, Transparent)
                            top_line.setUseYAxis(axis)
                            top_line.setXData(self._x_axis_data)

                            bottom_line = self.c.addLineLayer([min_y_val for i in bottom_area], Transparent)
                            bottom_line.setXData(self._x_axis_data)
                            bottom_line.setUseYAxis(axis)

                            top_y = stop_light_area_line.getYCoor(bottom_largest)
                            bottom_y = stop_light_area_line.getYCoor(min_y_val)

                            bottom_color = self.c.linearGradientColor(
                                0, bottom_y, 0, top_y, bottom_end_color, bottom_start_color
                            )

                            bottom_area = self.c.addInterLineLayer(
                                top_line.getLine(), bottom_line.getLine(), bottom_color
                            )
                            bottom_area.setUseYAxis(axis)

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

                            # top area
                            bottom_line = self.c.addLineLayer(top_area, Transparent)
                            bottom_line.setXData(self._x_axis_data)
                            bottom_line.setUseYAxis(axis)

                            top_line = self.c.addLineLayer([max_y_val for i in top_area], Transparent)
                            top_line.setUseYAxis(axis)
                            top_line.setXData(self._x_axis_data)

                            top_y = stop_light_area_line.getYCoor(max_y_val)
                            bottom_y = stop_light_area_line.getYCoor(top_smallest)

                            top_color = self.c.linearGradientColor(
                                0, bottom_y, 0, top_y, top_start_color, top_end_color
                            )

                            top_area = self.c.addInterLineLayer(top_line.getLine(), bottom_line.getLine(), top_color)
                            top_area.setUseYAxis(axis)

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

                            self.datasets[self.layers_count] = dict()
                            self.datasets[self.layers_count][0] = {
                                "metric_id": metric_id,
                                "metric_data": element_type,
                                "type": "good_stop_light",
                                "shape": "",
                            }
                            self.dataset_ids[self.layers_count] = 0
                            self.layers_count += 1

        filename = ""
        if self.settings["type"] == "large":
            if self.settings["show_stop_light"]:
                filename = self._jfile.get_chart_file_name(self.interval, suffix="_stoplight")
            elif self.settings["show_std_deviation"]:
                filename = self._jfile.get_chart_file_name(self.interval, suffix="_std_dev")
            else:
                filename = self._jfile.get_chart_file_name(self.interval, suffix="")
        elif self.settings["type"] == "thumbnail":
            filename = self._jfile.get_thumbnail_file_name()
        elif self.settings["type"] == "preview":
            filename = self._jfile.get_preview_file_name()

        # draw chart
        if not self.c.makeChart(filename):
            raise Exception("ChartDirector cannot create image file %s." % filename)
        self.file_man.change_perm(filename)
示例#4
0
    def get_modified_data(self, data):
        # expired zone settings
        data['expired_zone'] = dict()
        
        if data['expired_date'] and data['orig_header']:
            data['expired_zone']['start'] = data['expired_date']
            data['expired_zone']['end'] = data['orig_header'][-1]
            data['expired_zone']['color'] = FontManager.get_db_color(self.settings['expired_zone_color'])

        if self.metric_type == 'single':
            # get line point shape. for single metrics it's circle
            self._db.Query("""SELECT * FROM chart_data_point_shape WHERE chartdirector_shape_id = 'CircleShape'""")
            line_point_shapes = cycle([shape for shape in self._db.record])
        else:
            # get line point shapes for multi-metrics
            self._db.Query("""SELECT * FROM chart_data_point_shape ORDER BY charting_order""")
            line_point_shapes = cycle([shape for shape in self._db.record])

        for metric_id in data['rows']:
            if not self.chart_display_mode:
                self.chart_display_mode = data['rows'][metric_id]['data_settings']['display_type']
            elif self.chart_display_mode != data['rows'][metric_id]['data_settings']['display_type']:
                self.chart_display_mode = 'both'
            # set line point shape
            data['rows'][metric_id]['data_settings']['line_point_shape'] = None 
            if data['rows'][metric_id]['data_settings']['display_type'] == 'line':
                data['rows'][metric_id]['data_settings']['line_point_shape'] = line_point_shapes.next()

            if data['rows'][metric_id]['average_settings']:
                if self.settings['include_average_ind'] == 'N':
                    del(data['rows'][metric_id]['average_settings'])

            if data['compare_lines']:
                for compare_line in data['compare_lines']:
                    compare_setting = 'compare_settings_%s' % compare_line
                    if self.settings['include_compare_ind'] == 'N':
                        del(data['rows'][metric_id][compare_setting])
                    else:
                        data['rows'][metric_id][compare_setting]['axis_number'] = 1
                        data['rows'][metric_id][compare_setting]['display_type'] = 'line'
                        data['rows'][metric_id][compare_setting]['color'] = FontManager.get_db_color(data['rows'][metric_id][compare_setting]['line_color'])
                        data['rows'][metric_id][compare_setting]['line_style'] = data['rows'][metric_id]['data_settings']['line_style']
                if self.settings['include_compare_ind'] == 'N':
                    del(data['compare_lines'])

            if data['rows'][metric_id]['min_ever_settings']:
                if self.settings['include_min_max_ever_ind'] == 'N':
                    del(data['rows'][metric_id]['min_ever_settings'])
                else:
                    data['rows'][metric_id]['min_ever_settings']['axis_number'] = 1
                    data['rows'][metric_id]['min_ever_settings']['display_type'] = 'line'
                    data['rows'][metric_id]['min_ever_settings']['line_type'] = 'solid'
                    data['rows'][metric_id]['min_ever_settings']['color'] = FontManager.get_db_color(self.settings['min_max_ever_line_color'])
                    data['rows'][metric_id]['min_ever_settings']['line_width'] = self.settings['min_max_ever_line_width']
                    data['rows'][metric_id]['min_ever_settings']['line_style'] = 'jagged'

            if data['rows'][metric_id]['max_ever_settings']:
                if self.settings['include_min_max_ever_ind'] == 'N':
                    del(data['rows'][metric_id]['max_ever_settings'])
                else:
                    data['rows'][metric_id]['max_ever_settings']['axis_number'] = 1
                    data['rows'][metric_id]['max_ever_settings']['display_type'] = 'line'
                    data['rows'][metric_id]['max_ever_settings']['line_type'] = 'solid'
                    data['rows'][metric_id]['max_ever_settings']['color'] = FontManager.get_db_color(self.settings['min_max_ever_line_color'])
                    data['rows'][metric_id]['max_ever_settings']['line_width'] = self.settings['min_max_ever_line_width']
                    data['rows'][metric_id]['max_ever_settings']['line_style'] = 'jagged'
            
        #thinning data according to maximum data points number
        max_data_len = self.settings['max_line_data_points_to_chart']
        if self.chart_display_mode == 'line':
            max_data_len = self.settings['max_line_data_points_to_chart']
        elif self.chart_display_mode == 'bar':
            max_data_len = self.settings['max_bar_data_points_to_chart']
        elif self.chart_display_mode == 'both':
            max_data_len = min(self.settings['max_line_data_points_to_chart'], self.settings['max_bar_data_points_to_chart'])
        self.settings['is_reduced'] = False

        thinned_data = copy.deepcopy(data)

        if self.chart_display_mode == 'bar' or self.chart_display_mode == 'both':
            thinned_data = self.get_thinned_data_bar(thinned_data, max_data_len, data['thin_by_metric_id'])
        else:
            thinned_data = self.get_thinned_data(thinned_data, max_data_len, data['thin_by_metric_id'])

        return thinned_data