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
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
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)
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