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.bar_positive_value_color, chart_layout.bar_negative_value_color, 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, dashboard_element.multi_chart_primary_axis_start_from_zero_ind AS primary_axis_start_from_zero_ind, dashboard_element.multi_chart_secondary_axis_start_from_zero_ind AS secondary_axis_start_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' data['primary_axis_start_from_zero_ind'] = data['start_y_axis_from_zero_ind'] data['secondary_axis_start_from_zero_ind'] = data['start_y_axis_from_zero_ind'] #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': self._db.Query(""" SELECT * FROM chart_display_format WHERE preview_display_format_ind = 'Y'""") chart_display_format = self._db.record[0] data['preview'] = chart_display_format else: data['preview'] = None 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.0 if data['bar_group_gap'] is None: data['bar_group_gap'] = 0.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 if data['bar_positive_value_color']: data['bar_positive_value_color'] = FontManager.get_db_color(data['bar_positive_value_color']) else: data['bar_positive_value_color'] = None if data['bar_negative_value_color']: data['bar_negative_value_color'] = FontManager.get_db_color(data['bar_negative_value_color']) else: data['bar_negative_value_color'] = None # 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 charting settings for compatibility with report charts data['flip_x_and_y_axis'] = 'N' data['use_stacked_bars_ind'] = '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._set_y_axes_formats() self._create_layers() # 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 = [] 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. uid: metric uid, _v: metric data for uid, 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 'axis_number' in element_data and element_data['axis_number'] == '2': axis = self.c.yAxis2() axis_index = 1 else: axis_index = 0 axis = self.c.yAxis() # set color and line type dash/dot/solid 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] = {} self.datasets[self.layers_count][0] = {'uid': uid, 'metric_data': element_type, 'type': 'good_stop_light', 'shape': ''} self.datasets[self.layers_count][1] = {'uid': uid, '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'][uid]['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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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'] # add GOOD/BAD title to legend box l_legend = self.legend_layer.addDataSet([], bad_color, u"Bad Level") l_legend.setDataLabelStyle(self.legend_font, self.legend_font_size, Transparent) l_legend.setLineWidth(2) #l_legend.setDataSymbol4(self._cSquareSymbol, 15, bad_color, -1) l_legend.setDataSymbol(CircleShape, 1, bad_color, bad_color) l_legend = self.legend_layer.addDataSet([], good_color, u"Good Level") l_legend.setLineWidth(2) #l_legend.setDataSymbol4(self._cSquareSymbol, 15, good_color, -1) l_legend.setDataSymbol(CircleShape, 1, good_color, good_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([], 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([], 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']: # make it absolute transparent std_deviation_color = Transparent else: # make it half transparent std_deviation_color = color + 0xa0000000 min_deviation = [] max_deviation = [] 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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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 = {'uid': uid, 'metric_data': element_type, 'type': 'line_data', 'shape': 'point'} line_point_description = {'uid': uid, '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'][uid]['data_settings']['line_point_shape']) else: show_data_points = False shape = None if 'line_width' in element_data: line_width = element_data['line_width'] else: line_width = None if self.chart_data['split_xtd_periods']: self._create_line_layer_xtd(element_data['data'], element_data['line_style'], line_width, color, axis, show_data_points, shape, line_description, line_point_description) else: 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: bar_ind += 1 # bar chart self._create_bar_layer(element_data['data'], color, axis, axis_index, bar_ind, True, {'uid': uid, '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'][uid], axis_index, {'uid': uid, 'element_type': element_type}) # draw point annotations self._draw_point_annotations( self.chart_data['point_annotations'][uid], element_data['data'], axis, axis_index, element_data['display_type'], bar_ind, True, {'uid': uid, '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([], 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([], 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 uid, _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'][uid]['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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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] = {} self.datasets[self.layers_count][0] = {'uid': uid, '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) if self.settings['type'] == 'large' and not (self.settings['show_stop_light'] or self.settings['show_std_deviation']) and self.settings['is_index']: self.create_resized_preview()
def get_modified_data(self, data): # expired zone settings data['expired_zone'] = {} 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_uid in data['rows']: if not self.chart_display_mode: self.chart_display_mode = data['rows'][metric_uid]['data_settings']['display_type'] elif self.chart_display_mode != data['rows'][metric_uid]['data_settings']['display_type']: self.chart_display_mode = 'both' # set line point shape data['rows'][metric_uid]['data_settings']['line_point_shape'] = None if data['rows'][metric_uid]['data_settings']['display_type'] == 'line': if data['rows'][metric_uid]['data_settings']['shape_id']: res = self._db.Query("""SELECT * FROM chart_data_point_shape WHERE chart_data_point_shape_id = %s""", (data['rows'][metric_uid]['data_settings']['shape_id'])) if res: data['rows'][metric_uid]['data_settings']['line_point_shape'] = self._db.record[0] if not data['rows'][metric_uid]['data_settings']['line_point_shape']: data['rows'][metric_uid]['data_settings']['line_point_shape'] = line_point_shapes.next() if data['rows'][metric_uid]['average_settings']: if self.settings['include_average_ind'] == 'N': del(data['rows'][metric_uid]['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' and not (self.type == 'preview' and data['rows'][metric_uid][compare_setting]['highlight_interval_ind'] == 'Y')): del(data['rows'][metric_uid][compare_setting]) else: data['rows'][metric_uid][compare_setting]['axis_number'] = 1 data['rows'][metric_uid][compare_setting]['display_type'] = 'line' data['rows'][metric_uid][compare_setting]['color'] = FontManager.get_db_color(data['rows'][metric_uid][compare_setting]['line_color']) data['rows'][metric_uid][compare_setting]['line_style'] = data['rows'][metric_uid]['data_settings']['line_style'] if self.settings['include_compare_ind'] == 'N': del(data['compare_lines']) if data['rows'][metric_uid]['min_ever_settings']: if self.settings['include_min_max_ever_ind'] == 'N': del(data['rows'][metric_uid]['min_ever_settings']) else: data['rows'][metric_uid]['min_ever_settings']['axis_number'] = 1 data['rows'][metric_uid]['min_ever_settings']['display_type'] = 'line' data['rows'][metric_uid]['min_ever_settings']['line_type'] = 'solid' data['rows'][metric_uid]['min_ever_settings']['color'] = FontManager.get_db_color(self.settings['min_max_ever_line_color']) data['rows'][metric_uid]['min_ever_settings']['line_width'] = self.settings['min_max_ever_line_width'] data['rows'][metric_uid]['min_ever_settings']['line_style'] = 'jagged' if data['rows'][metric_uid]['max_ever_settings']: if self.settings['include_min_max_ever_ind'] == 'N': del(data['rows'][metric_uid]['max_ever_settings']) else: data['rows'][metric_uid]['max_ever_settings']['axis_number'] = 1 data['rows'][metric_uid]['max_ever_settings']['display_type'] = 'line' data['rows'][metric_uid]['max_ever_settings']['line_type'] = 'solid' data['rows'][metric_uid]['max_ever_settings']['color'] = FontManager.get_db_color(self.settings['min_max_ever_line_color']) data['rows'][metric_uid]['max_ever_settings']['line_width'] = self.settings['min_max_ever_line_width'] data['rows'][metric_uid]['max_ever_settings']['line_style'] = 'jagged' if self.metric_type == 'single' and self.chart_display_mode == 'bar' and data['metric_change_bar_color_on_value_ind'] == 'Y': self.settings['is_pos_neg_colored_bars'] = True else: self.settings['is_pos_neg_colored_bars'] = False #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_uid']) else: thinned_data = self.get_thinned_data(thinned_data, max_data_len, data['thin_by_metric_uid']) return thinned_data
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.c = c if self.settings['type'] == 'large': self.create_map_file() if self.settings['is_index']: self.create_resized_preview()