class Labels(): def __init__(self, N_labels, fontSize): self.fontSize = fontSize self.initLabels(N_labels) self.fontManager = FontManager(fontSize) def stepFont(self): for label in self.labels: newFont = QtGui.QFont(self.fontManager.step(), self.fontManager.fontSize) label.setFont(newFont) def changeFontSize(self, delta): self.fontManager.changeFontSize(delta) for label in self.labels: font = label.font() font.setPointSize(self.fontManager.fontSize) label.setFont(font) def initLabels(self, N_labels): self.labels = [] self.N_labels = N_labels for i in range(N_labels): self.labels.append(QLabel("")) self.labels[-1].setAlignment(Qt.AlignCenter) def setText(self, string_list): for i, s in enumerate(string_list): self.labels[i].setText(s)
def __init__(self, title, outputFile, paperSize, timestamp="", includeSplunkLogo=None, cidFontList=None): """ outputFile can either be a filename or a file-like object """ self.outputFile = outputFile self.paperSize = paperSize self.reportLabPaperSize = PAPERSIZES[ self.paperSize]['reportLabPaperSize'] self.logoTransformSize = PAPERSIZES[ self.paperSize]['logoTransformSize'] self._log("outputFile: " + str(self.outputFile)) self._log("reportLabPaperSize: " + str(self.reportLabPaperSize)) self._title = title self._timestamp = timestamp if includeSplunkLogo != None: self._includeSplunkLogo = includeSplunkLogo logger.debug("pdf-init pdfrenderer include-splunk-logo=%s" % self._includeSplunkLogo) self._fontManager = FontManager(cidFontList=cidFontList) self.TITLE_STYLE.fontSize = 14 self.TITLE_STYLE.leading = 16 self.CENTER_STYLE.alignment = reportlab.lib.enums.TA_CENTER # TODO: need a better way to determine max cell height # 225 ~= margins + footer height + a few lines for header row self.maxTableCellHeight = self.reportLabPaperSize[1] - 225 return
class PDFRenderer(object): ONE_INCH = 1.0 * inch MIN_HEIGHT_TABLE_AND_CHART = 4 * inch _fontManager = None outputFile = None reportLabPaperSize = (0, 0) _includeSplunkLogo = True _title = "" _story = [] _runningAsScript = False _style = STYLES["Normal"] CENTER_STYLE = copy.deepcopy(STYLES['Normal']) TITLE_STYLE = copy.deepcopy(STYLES["Normal"]) BULLET_STYLE = STYLES["Bullet"] _bulletStyle = STYLES["Bullet"] _tableTitleStyle = STYLES["Title"] _listTitleStyle = STYLES["Bullet"] _hardWrapStyle = copy.deepcopy(STYLES["Normal"]) _hardWrapStyle.wordWrap = "CJK" _TABLE_COL_LEFT_PADDING = 2 _TABLE_COL_RIGHT_PADDING = 2 _MARGINS = [inch, inch, inch, inch] def __init__(self, title, outputFile, paperSize, timestamp="", includeSplunkLogo=None, cidFontList=None): """ outputFile can either be a filename or a file-like object """ self.outputFile = outputFile self.paperSize = paperSize self.reportLabPaperSize = PAPERSIZES[ self.paperSize]['reportLabPaperSize'] self.logoTransformSize = PAPERSIZES[ self.paperSize]['logoTransformSize'] self._log("outputFile: " + str(self.outputFile)) self._log("reportLabPaperSize: " + str(self.reportLabPaperSize)) self._title = title self._timestamp = timestamp if includeSplunkLogo != None: self._includeSplunkLogo = includeSplunkLogo logger.debug("pdf-init pdfrenderer include-splunk-logo=%s" % self._includeSplunkLogo) self._fontManager = FontManager(cidFontList=cidFontList) self.TITLE_STYLE.fontSize = 14 self.TITLE_STYLE.leading = 16 self.CENTER_STYLE.alignment = reportlab.lib.enums.TA_CENTER # TODO: need a better way to determine max cell height # 225 ~= margins + footer height + a few lines for header row self.maxTableCellHeight = self.reportLabPaperSize[1] - 225 return def conditionalPageBreak(self): self._story.append(CondPageBreak(self.MIN_HEIGHT_TABLE_AND_CHART)) def spaceBetween(self, space=0.5 * inch): self._story.append(EnsureSpaceBetween(space)) def renderText(self, text, style=None, escapeText=True): if style is None: style = self._style if escapeText: readyText = su.escape(text) else: readyText = text logger.debug("renderText readyText='%s'" % readyText) self._story.append( Paragraph(self._fontManager.encodeTextForParagraph(readyText), style)) def renderBulletText(self, text, bullet='-', style=None): if style is None: style = self._bulletStyle self._story.append( Paragraph(self._fontManager.encodeTextForParagraph( su.escape(text)), style, bulletText=bullet)) def renderHtml(self, text): if text is None: return def multiple_replacer(*key_values): replace_dict = dict(key_values) replacement_function = lambda match: replace_dict[match.group(0)] pattern = re.compile( "|".join([re.escape(k) for k, v in key_values]), re.M) return lambda string: pattern.sub(replacement_function, string) def multiple_replace(string, *key_values): return multiple_replacer(*key_values)(string) # reportlab supports a set of text manipulation tags # transform those HTML tags that aren't supported into reportlab # supported tags lineBreakingTagReplacements = (u"<li>", u"<li><br/>"), ( u"<h1>", u"<h1><font size='24'><br/><br/>" ), (u"</h1>", u"</font><br/></h1>"), ( u"<h2>", u"<h2><font size='20'><br/><br/>" ), (u"</h2>", u"</font><br/></h2>"), ( u"<h3>", u"<h3><font size='18'><br/><br/>" ), (u"</h3>", u"</font><br/></h3>"), ( u"<h4>", u"<h4><font size='14'><br/>"), (u"</h4>", u"</font><br/></h4>"), ( u"<h5>", u"<h5><font size='12'><br/>" ), (u"</h5>", u"</font><br/></h5>"), (u"<h6>", u"<h6><br/>"), ( u"</h6>", u"<br/></h6>"), (u"<h7>", u"<h7><br/>"), ( u"</h7>", u"<br/></h7>"), (u"<h8>", u"<h8><br/>"), ( u"</h8>", u"<br/></h8>"), (u"<h9>", u"<h9><br/>"), ( u"</h9>", u"<br/></h9>"), ( u"<h10>", u"<h10><br/>"), (u"</h10>", u"<br/></h10>"), ( u"<br>", u"<br/>"), (u"<p>", u"<p><br/>") repText = multiple_replace(text, *lineBreakingTagReplacements) # need to remove some elements # any elements that make references to external things -- don't want reportlab to try to resolve links # reportlab doesn't like the title attribute removeElements = [ '(<img[^>]*>)', '(</img>)', '(title="[^"]*")', '(<a[^>]*>)', '(</a>)' ] repText = re.sub('|'.join(removeElements), '', repText) logger.debug("renderHtml text='%s' repText='%s'" % (text, repText)) self.renderText(repText, escapeText=False) def renderTextNoFormatting(self, text): self._story.append(TableText(text, fontManager=self._fontManager)) def renderListItem(self, text, sequencerNum=None, style=None): if style is None: style = self._listTitleStyle if sequencerNum != None: text = "<seq id=" + str(sequencerNum) + "/>" + text self._story.append( Paragraph( self._fontManager.encodeTextForParagraph(su.escape(text)), style)) def renderTable(self, data, title=None, headerRow=None, columnWidths=[], columnHardWraps=[], columnVAlignments=[], displayLineNumbers=False): """ data should be a 2-D list of embedded lists e.g. [[a,b],[c,d],[e,f]] if headerRow is specified, then that row will be repeated at the top of each page if the table spans multiple pages, columnWidths ([int]) specifies the width of each column, if a column is not specified it will be sized automatically, columnHardWraps ([bool]) specifies whether or not to hard wrap a column, if a column is not specified it will be wrapped softly columnVAlignments (['TOP','MIDDLE','BOTTOM']) specifies vertical alignment of cells in a column, if not specified will be aligned at BOTTOM displayLineNumbers (bool) specifies whether or not to show line numbers """ # handle title and header if title != None: self.renderText(title, style=self._tableTitleStyle) if headerRow != None: data.insert(0, headerRow) logger.debug("renderTable> headerRow: " + str(headerRow)) # handle row numbers if displayLineNumbers: for index, row in enumerate(data): if index == 0 and headerRow != None: row.insert(0, "") else: rowNumber = index if headerRow == None: rowNumber = rowNumber + 1 row.insert(0, str(rowNumber)) numDataCols = 0 # iterate over the data in order to wrap each cell in a Paragraph flowable with a style numberCells = [ ] # an array of tuples identifying cells that are numbers cellWidthsByCol = [] styledData = [] for rowIdx, row in enumerate(data): styledRow = [] for cellNum, cell in enumerate(row): # set the style based on columnHardWraps[cellNum] style = self._style if len(columnHardWraps) > cellNum: if columnHardWraps[cellNum]: style = self._hardWrapStyle cellFlowable = None if "##__SPARKLINE__##" in str(cell): # build sparkline and insert into row cellFlowable = Sparkline(str(cell)) styledRow.append(cellFlowable) else: cellFlowable = TableText( str(cell), fontManager=self._fontManager, maxCellHeight=self.maxTableCellHeight) styledRow.append(cellFlowable) if cellFlowable.isNumeric(): numberCells.append((cellNum, rowIdx)) # build up matrix of cell widths by column if rowIdx == 0: cellWidthsByCol.append([]) cellWidthsByCol[cellNum].append(cellFlowable.width) numDataCols = len(styledRow) styledData.append(styledRow) columnWidths = self.determineColumnWidths( cellWidthsByCol, tableWidth=self.reportLabPaperSize[0] - self._MARGINS[0] - self._MARGINS[2], columnPadding=self._TABLE_COL_LEFT_PADDING + self._TABLE_COL_RIGHT_PADDING) # create the necessary table style commands to handle vertical alignment setting tableStyleCommands = [] if columnVAlignments is not None: for i, valign in enumerate(columnVAlignments): tableStyleCommands.append(('VALIGN', (i, 0), (i, -1), valign)) for numberCell in numberCells: tableStyleCommands.append( ('ALIGN', numberCell, numberCell, 'RIGHT')) # line to the right of all columns tableStyleCommands.append( ('LINEAFTER', (0, 0), (-2, -1), 0.25, colors.lightgrey)) firstDataRow = 0 if headerRow != None: tableStyleCommands.append( ('LINEBELOW', (0, 0), (-1, 0), 1, colors.black)) firstDataRow = 1 # lines to the bottom and to the right of each cell tableStyleCommands.append( ('LINEBELOW', (0, firstDataRow), (-1, -2), 0.25, colors.lightgrey)) # tighten up the columns tableStyleCommands.append( ('LEFTPADDING', (0, 0), (-1, -1), self._TABLE_COL_LEFT_PADDING)) tableStyleCommands.append( ('RIGHTPADDING', (0, 0), (-1, -1), self._TABLE_COL_RIGHT_PADDING)) # create the Table flowable and insert into story table = Table(styledData, repeatRows=(headerRow != None), colWidths=columnWidths) table.setStyle(TableStyle(tableStyleCommands)) self._story.append(table) def determineColumnWidths(self, cellWidthsByCol, tableWidth, columnPadding): columnSizer = ColumnSizer(cellWidthsByCol, tableWidth, columnPadding) return columnSizer.getWidths() def renderSvgString(self, svgString, title=None): svgImageFlowable = pdfgen_svg.getSvgImageFromString( svgString, self._fontManager) if svgImageFlowable is None: self._log("renderSvg> svgImageFlowable for " + svgString + " is invalid") else: if title != None: self.renderText(title, style=self._tableTitleStyle) self._story.append(svgImageFlowable) def save(self): # self._log("starting save", logLevel='info') doc = PDFGenDocTemplate(self.outputFile, pagesize=self.reportLabPaperSize) doc.setTitle(self._title) doc.splunkPaperSize = self.paperSize doc.setTimestamp(self._timestamp) doc.setFontManager(self._fontManager) if self._includeSplunkLogo: doc.setLogoSvgString( _splunkLogoSvg.replace("***logoTransformSize***", str(self.logoTransformSize))) self._log("Doc pageSize: " + str(getattr(doc, "pagesize"))) for flowable in self._story: flowable.hAlign = 'CENTER' # self._log("before doc.build", logLevel='info') doc.build(self._story, onFirstPage=_footer, onLaterPages=_footer) # self._log("after doc.build", logLevel='info') # if len(wrapTimes) > 1: # self._log("wrap time stats; min=%s, max=%s, agg=%s, avg=%s, num=%s" % _getStats(wrapTimes), logLevel='info') # if len(stringWidthTimes) > 1: # self._log("width time stats; min=%s, max=%s, agg=%s, avg=%s, num=%s" % _getStats(stringWidthTimes), logLevel='info') # self._log("font manager cache length=%s" % len(self._fontManager._textWidthCache), logLevel='info') # if len(drawTimes) > 1: # self._log("draw time stats; min=%s, max=%s, agg=%s, avg=%s, num=%s" % _getStats(drawTimes), logLevel='info') def _log(self, msg, logLevel='debug'): if self._runningAsScript: print logLevel + " : " + msg return if logLevel == 'debug': logger.debug(msg) elif logLevel == 'info': logger.info(msg) elif logLevel == 'warning': logger.warning(msg) elif logLevel == 'error': logger.error(msg)
def main() -> None: mode = input('MODE (L, R, C): ') # Initialize a fullscreen window pygame.init() screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # Window title pygame.display.set_caption('ESW Digital Waste Bins') # Make a display # TODO: add more modules to the display # TODO: store in subclass? for each bin # Landfill if mode == 'L': title_fm = FontManager(['impact']) text = title_fm.create_text('LANDFILL', 100, color=WHITE) title = TitleFrame(text=text, bg=BLACK, pady=100) content = Content(display_bg_color=WHITE) Display(title, content).draw(screen) # Compost elif mode == 'C': title_fm = FontManager(['impact']) text = title_fm.create_text('COMPOST', 100, color=WHITE) title = TitleFrame(text=text, bg=GREEN, pady=100) content = Content(display_bg_color=WHITE) Display(title, content).draw(screen) # Recycle elif mode == 'R': title_fm = FontManager(['impact']) text = title_fm.create_text('RECYCLE', 100, color=WHITE) title = TitleFrame(text=text, bg=BLUE, pady=100) content = Content(display_bg_color=WHITE) Display(title, content).draw(screen) else: print('Not a valid option.') return None # Game loop clock = pygame.time.Clock() running = True prev_reading = scaleReading() # initial scale reading while running: # Handle events for event in pygame.event.get(): if event.type == pygame.QUIT: running = False break elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False break curr_reading = scaleReading() weight_diff = curr_reading-prev_reading # check if the reading has changed compared to last time if weight_diff > MIN_WEIGHT_DIFF and motionReading(): # start telling the thrower how much he she saved etc prev_reading = curr_reading elif weight_diff < MIN_WEIGHT_DIFF and motionReading(): # thank the thrower but don't display the weight prev_reading = curr_reading else: prev_reading = curr_reading # Next frame (20 fps) clock.tick(20) # Repaint screen pygame.display.flip() # Exit pygame.quit()
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 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): """ 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 __init__(self, N_labels, fontSize): self.fontSize = fontSize self.initLabels(N_labels) self.fontManager = FontManager(fontSize)
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()