def _draw_labels(self, cur_drawing, left_labels, right_labels): """Layout and draw sub-feature labels for the chromosome. Tries to place each label at the same vertical position as the feature it applies to, but will adjust the positions to avoid or at least reduce label overlap. Draws the label text and a coloured line linking it to the location (i.e. feature) it applies to. """ if not self._sub_components: return color_label = self._color_labels segment_width = (self.end_x_position - self.start_x_position) \ * self.chr_percent label_sep = (self.end_x_position - self.start_x_position) \ * self.label_sep_percent segment_x = self.start_x_position \ + 0.5 * (self.end_x_position - self.start_x_position - segment_width) y_limits = [] for sub_component in self._sub_components: y_limits.extend((sub_component.start_y_position, sub_component.end_y_position)) y_min = min(y_limits) y_max = max(y_limits) del y_limits #Now do some label placement magic... #from reportlab.pdfbase import pdfmetrics #font = pdfmetrics.getFont('Helvetica') #h = (font.face.ascent + font.face.descent) * 0.90 h = self.label_size left_labels = _place_labels(left_labels, y_min, y_max, h) right_labels = _place_labels(right_labels, y_min, y_max, h) x1 = segment_x x2 = segment_x - label_sep for (y1, y2, color, name) in left_labels: cur_drawing.add(Line(x1, y1, x2, y2, strokeColor = color, strokeWidth = 0.25)) label_string = String(x2, y2, name, textAnchor="end") label_string.fontName = 'Helvetica' label_string.fontSize = self.label_size if color_label: label_string.fillColor = color cur_drawing.add(label_string) x1 = segment_x + segment_width x2 = segment_x + segment_width + label_sep for (y1, y2, color, name) in right_labels: cur_drawing.add(Line(x1, y1, x2, y2, strokeColor = color, strokeWidth = 0.25)) label_string = String(x2, y2, name) label_string.fontName = 'Helvetica' label_string.fontSize = self.label_size if color_label: label_string.fillColor = color cur_drawing.add(label_string)
def _draw_labels(self, cur_drawing, left_labels, right_labels): """Layout and draw sub-feature labels for the chromosome. Tries to place each label at the same vertical position as the feature it applies to, but will adjust the positions to avoid or at least reduce label overlap. Draws the label text and a coloured line linking it to the location (i.e. feature) it applies to. """ if not self._sub_components: return color_label = self._color_labels segment_width = (self.end_x_position - self.start_x_position) \ * self.chr_percent label_sep = (self.end_x_position - self.start_x_position) \ * self.label_sep_percent segment_x = self.start_x_position \ + 0.5 * (self.end_x_position - self.start_x_position - segment_width) y_limits = [] for sub_component in self._sub_components: y_limits.extend( (sub_component.start_y_position, sub_component.end_y_position)) y_min = min(y_limits) y_max = max(y_limits) del y_limits #Now do some label placement magic... #from reportlab.pdfbase import pdfmetrics #font = pdfmetrics.getFont('Helvetica') #h = (font.face.ascent + font.face.descent) * 0.90 h = self.label_size left_labels = _place_labels(left_labels, y_min, y_max, h) right_labels = _place_labels(right_labels, y_min, y_max, h) x1 = segment_x x2 = segment_x - label_sep for (y1, y2, color, name) in left_labels: cur_drawing.add( Line(x1, y1, x2, y2, strokeColor=color, strokeWidth=0.25)) label_string = String(x2, y2, name, textAnchor="end") label_string.fontName = 'Helvetica' label_string.fontSize = self.label_size if color_label: label_string.fillColor = color cur_drawing.add(label_string) x1 = segment_x + segment_width x2 = segment_x + segment_width + label_sep for (y1, y2, color, name) in right_labels: cur_drawing.add( Line(x1, y1, x2, y2, strokeColor=color, strokeWidth=0.25)) label_string = String(x2, y2, name) label_string.fontName = 'Helvetica' label_string.fontSize = self.label_size if color_label: label_string.fillColor = color cur_drawing.add(label_string)
def draw(self): self.set_bar_color() if self.drawLegend is True: if self.legendPositionType in [ "bottom-left", "bottom-mid", "bottom-right" ]: row_count = len(self.legendCategoryNames) + 1 self.height -= row_count * self.legendFontSize self.y += row_count * self.legendFontSize g = BarChart.draw(self) if self.drawLegend is True: self._draw_legend(g) if self.titleMain != "": title = String(0, 0, self.titleMain) title.fontSize = self.titleMainFontSize title.fontName = self.titleMainFontName title.fillColor = self.titleMainFontColor title.textAnchor = 'start' # title.x = self.x - 20 # title.y = self.y + self.height + 20 title.x = 0 title.y = self.y + self.height + 20 g.add(title) return g
def draw(self): self._calc_labels_size() self._adjust_positon() self.set_line_color() if self.drawLegend is True: if self.legendPositionType in ["bottom-left", "bottom-mid", "bottom-right"]: row_count = len(self.legendCategoryNames) + 1 self.height -= row_count * self.legendFontSize self.y += row_count * self.legendFontSize g = HorizontalLineChart.draw(self) if self.drawLegend: legend_count = 0 for i in range(len(self.legendCategoryNames)): legend = ChartsLegend() legend.positionType = self.legendPositionType if self.legendPositionType != "null": if self.legendPositionType in ["bottom-left", "bottom-mid", "bottom-right"]: legend.backgroundRect = \ Rect(self.x, self.y + legend.bottom_gap - self.labels_height - 15 - ((i+1) * legend.fontSize), self.width, self.height) else: legend.backgroundRect = Rect(self.x, self.y - (i * legend.fontSize * 1.2), self.width, self.height) legend.adjustX = self.legendAdjustX legend.adjustY = self.legendAdjustY legend.fontSize = self.legendFontSize legend.colorNamePairs = [] for j in range(len(self.legendCategoryNames[i])): legend.colorNamePairs.append((ALL_COLORS[legend_count + j], self.legendCategoryNames[i][j])) legend_count += len(self.legendCategoryNames[i]) g.add(legend) if self.titleMain != "": title = String(0, 0, self.titleMain) title.fontSize = self.titleMainFontSize title.fontName = self.titleMainFontName title.fillColor = self.titleMainFontColor title.textAnchor = 'start' # title.x = self.x - 20 title.x = 0 title.y = self.y + self.height + 20 g.add(title) return g
def _rawDraw(self): _text = self._text self._text = _text or "" self.computeSize() self._text = _text g = Group() g.translate(self.x + self.dx, self.y + self.dy) g.rotate(self.angle) y = self._top - self._leading * self._baselineRatio textAnchor = self._getTextAnchor() if textAnchor == "start": x = self._left elif textAnchor == "middle": x = self._left + self._ewidth * 0.5 else: x = self._right # paint box behind text just in case they # fill it if self.boxFillColor or (self.boxStrokeColor and self.boxStrokeWidth): g.add( Rect( self._left - self.leftPadding, self._bottom - self.bottomPadding, self._width, self._height, strokeColor=self.boxStrokeColor, strokeWidth=self.boxStrokeWidth, fillColor=self.boxFillColor, ) ) fillColor, fontName, fontSize = self.fillColor, self.fontName, self.fontSize strokeColor, strokeWidth, leading = self.strokeColor, self.strokeWidth, self._leading svgAttrs = getattr(self, "_svgAttrs", {}) if strokeColor: for line in self._lines: s = _text2Path(line, x, y, fontName, fontSize, textAnchor) s.fillColor = fillColor s.strokeColor = strokeColor s.strokeWidth = strokeWidth g.add(s) y -= leading else: for line in self._lines: s = String(x, y, line, _svgAttrs=svgAttrs) s.textAnchor = textAnchor s.fontName = fontName s.fontSize = fontSize s.fillColor = fillColor g.add(s) y -= leading return g
def draw(self): _text = self._text self._text = _text or '' self.computeSize() self._text = _text g = Group() g.translate(self.x + self.dx, self.y + self.dy) g.rotate(self.angle) y = self._top - self.fontSize textAnchor = self._getTextAnchor() if textAnchor == 'start': x = self._left elif textAnchor == 'middle': x = self._left + self._ewidth * 0.5 else: x = self._right # paint box behind text just in case they # fill it if self.boxFillColor or (self.boxStrokeColor and self.boxStrokeWidth): g.add( Rect( self._left - self.leftPadding, self._bottom - self.bottomPadding, self._width, self._height, strokeColor=self.boxStrokeColor, strokeWidth=self.boxStrokeWidth, fillColor=self.boxFillColor)) fillColor, fontName, fontSize = self.fillColor, self.fontName, self.fontSize strokeColor, strokeWidth, leading = self.strokeColor, self.strokeWidth, ( self.leading or 1.2 * fontSize) if strokeColor: for line in self._lines: s = _text2Path(line, x, y, fontName, fontSize, textAnchor) s.fillColor = fillColor s.strokeColor = strokeColor s.strokeWidth = strokeWidth g.add(s) y = y - leading else: for line in self._lines: s = String(x, y, line) s.textAnchor = textAnchor s.fontName = fontName s.fontSize = fontSize s.fillColor = fillColor g.add(s) y = y - leading return g
def _rawDraw(self): _text = self._text self._text = _text or '' self.computeSize() self._text = _text g = Group() g.translate(self.x + self.dx, self.y + self.dy) g.rotate(self.angle) y = self._top - self._leading * self._baselineRatio textAnchor = self._getTextAnchor() if textAnchor == 'start': x = self._left elif textAnchor == 'middle': x = self._left + self._ewidth * 0.5 else: x = self._right # paint box behind text just in case they # fill it if self.boxFillColor or (self.boxStrokeColor and self.boxStrokeWidth): g.add( Rect(self._left - self.leftPadding, self._bottom - self.bottomPadding, self._width, self._height, strokeColor=self.boxStrokeColor, strokeWidth=self.boxStrokeWidth, fillColor=self.boxFillColor)) fillColor, fontName, fontSize = self.fillColor, self.fontName, self.fontSize strokeColor, strokeWidth, leading = self.strokeColor, self.strokeWidth, self._leading svgAttrs = getattr(self, '_svgAttrs', {}) if strokeColor: for line in self._lines: s = _text2Path(line, x, y, fontName, fontSize, textAnchor) s.fillColor = fillColor s.strokeColor = strokeColor s.strokeWidth = strokeWidth g.add(s) y -= leading else: for line in self._lines: s = String(x, y, line, _svgAttrs=svgAttrs) s.textAnchor = textAnchor s.fontName = fontName s.fontSize = fontSize s.fillColor = fillColor g.add(s) y -= leading return g
def draw_string(string, x, y, font='song', size=14, color='red', anchor='middle'): s1 = String(x, y, string) s1.fontName = font s1.fontsize = size s1.fillColor = color.red s1.testAnchor = 'middle' return s1
def string_demo(): drawing = Drawing(width=400, height=200) for size in range(10, 32, 4): x = 15 + size * 1.5 y = 15 + size * 1.5 my_string = String(x, y, 'Python rocks!') my_string.fontName = 'Courier' my_string.fontSize = size drawing.add(my_string) other_string = String(200, 150, 'Centered Text') other_string.fontName = 'Times-Roman' other_string.fontSize = 40 other_string.fillColor = colors.red other_string.textAnchor = 'middle' drawing.add(other_string) drawing.save(formats=['pdf'], outDir='.', fnRoot='string_demo')
def _addWedgeLabel(self,text,angle,labelX,labelY,wedgeStyle,labelClass=WedgeLabel): # now draw a label if self.simpleLabels: theLabel = String(labelX, labelY, text) theLabel.textAnchor = "middle" theLabel._pmv = angle theLabel._simple_pointer = 0 else: theLabel = labelClass() theLabel._pmv = angle theLabel.x = labelX theLabel.y = labelY theLabel.dx = wedgeStyle.label_dx theLabel.dy = wedgeStyle.label_dy theLabel.angle = wedgeStyle.label_angle theLabel.boxAnchor = wedgeStyle.label_boxAnchor theLabel.boxStrokeColor = wedgeStyle.label_boxStrokeColor theLabel.boxStrokeWidth = wedgeStyle.label_boxStrokeWidth theLabel.boxFillColor = wedgeStyle.label_boxFillColor theLabel.strokeColor = wedgeStyle.label_strokeColor theLabel.strokeWidth = wedgeStyle.label_strokeWidth _text = wedgeStyle.label_text if _text is None: _text = text theLabel._text = _text theLabel.leading = wedgeStyle.label_leading theLabel.width = wedgeStyle.label_width theLabel.maxWidth = wedgeStyle.label_maxWidth theLabel.height = wedgeStyle.label_height theLabel.textAnchor = wedgeStyle.label_textAnchor theLabel.visible = wedgeStyle.label_visible theLabel.topPadding = wedgeStyle.label_topPadding theLabel.leftPadding = wedgeStyle.label_leftPadding theLabel.rightPadding = wedgeStyle.label_rightPadding theLabel.bottomPadding = wedgeStyle.label_bottomPadding theLabel._simple_pointer = wedgeStyle.label_simple_pointer theLabel.fontSize = wedgeStyle.fontSize theLabel.fontName = wedgeStyle.fontName theLabel.fillColor = wedgeStyle.fontColor return theLabel
def _draw_text(format_json, auto_calc=True): width = format_json['rect'][2] height = format_json['rect'][3] d = Drawing(width, height, vAlign="TOP") content = format_json['content'] position = format_json['position'] x = 0 # format_json['x'] y = 0 # format_json['y'] font_size = STATE_DEFAULTS['fontSize'] if "font_size" in format_json: font_size = format_json['font_size'] if auto_calc: if position == "middle": x = int(width / 2) y = int(height / 2) - int(font_size / 2) elif position == "start": y = height else: x = format_json['rect'][0] y = format_json['rect'][1] text = String(x, y, content) text.fontName = DefaultFontName if "font_name" in format_json: text.fontName = format_json['font_name'] text.fontSize = font_size if "font_color" in format_json: text.fillColor = format_json['font_color'] text.textAnchor = position d.add(text) return d
def generatePDF(FI, Equity, Investment, Valuation, monthlyInv, monthlyVal, equityTrades, bondTrades, net_position): logo = 'AIM_logo.jpg' portfolioDate = date.today() months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] portfolioHoldings = [[ '', 'Cost basis($)', 'Value on\n' + str(date.today()), 'Unrealized\ngain/loss($)', 'Unrealized\ngain/loss(%)', '% of\nPortfolio' ], ['Bond'] + FI, ['Equity'] + Equity, ['Total Portfolio'] + [round(a + b, 2) for (a, b) in zip(FI, Equity)]] #Page 4 data equity_data = [[ 'Equity', 'ISIN', 'Sector', 'Qty', 'Buy \nAverage($)', 'Previous \nClosing Price($)', 'Holdings buy\nvalue($)', 'Current\n Value($)', 'Unrealized\n gain/loss ($)', 'Unrealized \ngain/loss(%)', '', '', '% of Asset Class', '% of portfolio' ]] + equityTrades bond_data = [[ 'Bond', 'ISIN', 'Sector', 'Qty', 'Buy \nAverage($)', 'Previous\nClosing Price($)', 'Holdings buy\nvalue($)', 'Current\nValue($)', 'Unrealized\n gain/loss ($)', 'Unrealized \ngain/loss(%)', 'Accrued\nInterest (%)', 'Maturity\n Date', '% of Asset Class', '% of portfolio' ]] + bondTrades portfolioDetails = equity_data + [[''] * 14] + bond_data netPosition = [[ 'Net Position', '', '', '', '', '', 'Holdings buy\nvalue($)', 'Current\n Value($)', 'Unrealized\n gain/loss ($)', 'Unrealized \ngain/loss(%)', '% of Asset Class', '% of portfolio' ]] + net_position styles = getSampleStyleSheet() styleN = styles['Normal'] styleContent = ParagraphStyle(name='content', parent=styles['Normal'], fontSize=18, leading=35) styleH = styles['Heading1'] style_right = ParagraphStyle(name='right', parent=styles['Heading1'], alignment=TA_RIGHT, fontSize=24) style_center = ParagraphStyle(name='center', parent=styles['Normal'], alignment=TA_CENTER, fontSize=16, leading=35) story = [] doc = SimpleDocTemplate('portfolio.pdf', pagesize=landscape(A4), rightMargin=30, leftMargin=30, topMargin=30, bottomMargin=30) myFrame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='myFrame') frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width / 2 - 6, doc.height, id='col1') frame2 = Frame(doc.leftMargin + doc.width / 2 + 6, doc.bottomMargin, doc.width / 2 - 6, doc.height, id='col2') frame3 = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height / 2, id='col3') coverPage = PageTemplate(id='Cover', frames=[myFrame]) threeTemplate = PageTemplate(id='ThreeSec', frames=[frame1, frame2, frame3]) columnTemplate = PageTemplate(id='TwoCol', frames=[frame1, frame2]) #Page 1 story.append(Image(logo, 2 * inch, 2 * inch, hAlign='RIGHT')) story.append(Spacer(0, 10)) story.append(Paragraph("CLIENT PORTFOLIO", style_right)) story.append(HRFlowable(width='100%', thickness=5, color=colors.navy)) story.append(Spacer(0, 15)) story.append( Paragraph( "TABLE OF CONTENTS", ParagraphStyle(name='content', parent=styles['Normal'], fontSize=18, leading=35))) story.append(Paragraph("Investment Value" + "." * 104 + "1", styleN)) story.append(Spacer(0, 15)) story.append(Paragraph("Portfolio Holdings" + "." * 103 + "2", styleN)) story.append(Spacer(0, 15)) story.append(Paragraph("Net Position" + "." * 112 + "3", styleN)) story.append(Spacer(0, 15)) story.append(NextPageTemplate('ThreeSec')) story.append(PageBreak()) #Page 2 story.append(Paragraph("Investment Value", styleH)) story.append(Paragraph("As of " + str(portfolioDate), styleContent)) #Frame1 draw = Drawing(200, 150) rect = Rect(doc.width / 4, 100, 120, 50) rect.fillColor = colors.lightcoral draw.add(rect) my_title = String(doc.width / 4 + 6, 135, 'Total Investment', fontSize=16) my_title.fillColor = colors.white draw.add(my_title) my_title = String(doc.width / 4 + 15, 110, '$' + str(Investment), fontSize=20) my_title.fillColor = colors.white draw.add(my_title) story.append(draw) story.append(FrameBreak()) #Frame 2 story.append(Spacer(0, 75)) draw = Drawing(200, 150) rect = Rect(40, 112, 120, 50) rect.fillColor = colors.orange draw.add(rect) my_title = String(41, 145, 'Current Valuation', fontSize=16) my_title.fillColor = colors.white draw.add(my_title) my_title = String(55, 122, '$' + str(Valuation), fontSize=20) my_title.fillColor = colors.white draw.add(my_title) story.append(draw) story.append(FrameBreak()) #Frame 3 lineChart = line_chart(doc, months, portfolioDate, monthlyInv, monthlyVal, Valuation, Investment) story.append(lineChart) story.append(NextPageTemplate('TwoCol')) story.append(PageBreak()) # Page 3 story.append(Paragraph("Portfolio Holdings", styleH)) story.append(Paragraph("As of " + str(portfolioDate), styleContent)) story.append(Spacer(0, 100)) story.append(Paragraph("Summary of Portfolio Holdings", style_center)) style = TableStyle([('BACKGROUND', (0, -1), (-1, -1), colors.whitesmoke), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('BODYTEXT', (0, 0), (-1, -1), 'TEXTWRAP'), ('LINEABOVE', (0, 0), (-1, 1), 1, colors.black)]) table1 = Table(portfolioHoldings) table1.setStyle(style) story.append(table1) story.append(FrameBreak()) #Frame2 chart = pie_chart_with_legend(doc, FI, Equity) story.append(chart) #Page 4 story.append(PageBreak()) story.append(Paragraph("Details of portfolio holdings", styleH)) story.append(Paragraph("As of " + str(portfolioDate), styleContent)) story.append(Spacer(0, 20)) #style=[('BACKGROUND', (0,1), (-1,1), colors.whitesmoke),('ALIGN',(1,0),(-1,-1),'CENTER'),('FONTSIZE',(0,0),(-1,-1),8),('BODYTEXT',(0,0),(-1,-1),'TEXTWRAP'),('FONTNAME', (0,2), (-1,2), 'Helvetica-Bold')] style2 = [('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('BODYTEXT', (0, 0), (-1, -1), 'TEXTWRAP'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('LINEABOVE', (0, 0), (-1, 1), 1, colors.black)] style = [('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('BODYTEXT', (0, 0), (-1, -1), 'TEXTWRAP'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('LINEABOVE', (0, 0), (-1, 1), 1, colors.black), ('BOX', (0, 0), (-1, -1), 0.25, colors.black)] data_len = len(equity_data) for each in range(3, data_len): bg_color = colors.white if each % 2 == 0: bg_color = colors.whitesmoke #style.append(('BACKGROUND', (0,each), (-1,each), bg_color)) style2.append( ('FONTNAME', (0, data_len + 1), (-1, data_len + 1), 'Helvetica-Bold')) style2.append( ('LINEABOVE', (0, data_len + 1), (-1, data_len + 2), 1, colors.black)) table = Table(portfolioDetails) table.setStyle(TableStyle(style2)) story.append(table) story.append(Spacer(0, 50)) #table=Table(bond_data) #table.setStyle(TableStyle(style2)) #story.append(table) #page 5 #story.append(PageBreak()) story.append(Paragraph("Net Position", styleH)) story.append(Paragraph("As of " + str(portfolioDate), styleContent)) story.append(Spacer(0, 20)) story.append(HRFlowable(width='100%', thickness=1, color=colors.black)) story.append(Spacer(0, 20)) table1 = Table(netPosition) table1.setStyle(style) story.append(table1) doc.addPageTemplates([ coverPage, threeTemplate, columnTemplate, ]) doc.build(story)
def makeSectors(self): # normalize slice data if type(self.data) in (ListType, TupleType) and type(self.data[0]) in (ListType, TupleType): # it's a nested list, more than one sequence normData = [] n = [] for l in self.data: t = self.normalizeData(l) normData.append(t) n.append(len(t)) else: normData = self.normalizeData(self.data) n = len(normData) # labels if self.labels is None: labels = [] if type(n) not in (ListType, TupleType): labels = [""] * n else: for m in n: labels = list(labels) + [""] * m else: labels = self.labels # there's no point in raising errors for less than enough errors if # we silently create all for the extreme case of no labels. if type(n) not in (ListType, TupleType): i = n - len(labels) if i > 0: labels = list(labels) + [""] * i else: tlab = 0 for m in n: tlab = tlab + m i = tlab - len(labels) if i > 0: labels = list(labels) + [""] * i xradius = self.width / 2.0 yradius = self.height / 2.0 centerx = self.x + xradius centery = self.y + yradius if self.direction == "anticlockwise": whichWay = 1 else: whichWay = -1 g = Group() i = 0 sn = 0 startAngle = self.startAngle #% 360 if type(self.data[0]) in (ListType, TupleType): # multi-series doughnut styleCount = len(self.slices) iradius = (self.height / 5.0) / len(self.data) for series in normData: for angle in series: endAngle = startAngle + (angle * whichWay) #% 360 if abs(startAngle - endAngle) >= 1e-5: if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle # if we didn't use %stylecount here we'd end up with the later sectors # all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if type(n) in (ListType, TupleType): theSector = Wedge( cx, cy, xradius + (sn * iradius) - iradius, a1, a2, yradius=yradius + (sn * iradius) - iradius, radius1=yradius + (sn * iradius) - (2 * iradius), ) else: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) startAngle = endAngle if labels[i] != "": averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) theLabel = String(labelX, labelY, labels[i]) theLabel.textAnchor = "middle" theLabel.fontSize = sectorStyle.fontSize theLabel.fontName = sectorStyle.fontName theLabel.fillColor = sectorStyle.fontColor g.add(theLabel) i = i + 1 sn = sn + 1 else: # single series doughnut styleCount = len(self.slices) iradius = self.height / 5.0 for angle in normData: endAngle = startAngle + (angle * whichWay) #% 360 if abs(startAngle - endAngle) >= 1e-5: if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle # if we didn't use %stylecount here we'd end up with the later sectors # all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if n > 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) elif n == 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, iradius=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) # now draw a label if labels[i] != "": averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) theLabel = String(labelX, labelY, labels[i]) theLabel.textAnchor = "middle" theLabel.fontSize = sectorStyle.fontSize theLabel.fontName = sectorStyle.fontName theLabel.fillColor = sectorStyle.fontColor g.add(theLabel) startAngle = endAngle i = i + 1 return g
from reportlab.graphics.shapes import Drawing, String, colors from reportlab.graphics import renderPDF from reportlab.pdfbase.ttfonts import * '''--- 添加中文支持 ---''' pdfmetrics.registerFont(TTFont('mysh', 'C:\WINDOWS\FONTS\ARIAL.TTF')) # 注册要使用的字体 pdfmetrics.registerFont(TTFont('g', 'C:\WINDOWS\FONTS\ARIAL.TTF')) '''--- 创建画布 ---''' d = Drawing(300, 200) # 创建画布并设置画布尺寸 '''--- 创建文本内容并设置样式与位置 ---''' s1 = String(150, 100, '这一行使用字体的字体是微软雅黑!') # 创建字符串并设置坐标、内容 s1.fontName = 'mysh' # 设置字体 s1.fontSize = 14 # 设置字号 s1.fillColor = colors.red # 设置字体颜色 s1.textAnchor = 'middle' # 设置锚点为中心(即位置坐标为文本中心点坐标) s2 = String(150, 120, '陈磊你是最帅的!', fontName='g', fontSize=100, fillColor=colors.yellow, textAnchor='middle') # 另一种设置方式 '''--- 添加内容到画布并生成PDF文件 ---''' d.add(s1) # 将字符串添加到画布 d.add(s2) renderPDF.drawToFile(d, 'myPDF.pdf', '我的第一个PDF文件。') # 生成PDF文件并设置文件名称与文档描述
def _draw_labels(self, cur_drawing, left_labels, right_labels): """Layout and draw sub-feature labels for the chromosome. Tries to place each label at the same vertical position as the feature it applies to, but will adjust the positions to avoid or at least reduce label overlap. Draws the label text and a coloured line linking it to the location (i.e. feature) it applies to. """ if not self._sub_components: return color_label = self._color_labels segment_width = (self.end_x_position - self.start_x_position) \ * self.chr_percent label_sep = (self.end_x_position - self.start_x_position) \ * self.label_sep_percent segment_x = self.start_x_position \ + 0.5 * (self.end_x_position - self.start_x_position - segment_width) y_limits = [] for sub_component in self._sub_components: y_limits.extend((sub_component.start_y_position, sub_component.end_y_position)) y_min = min(y_limits) y_max = max(y_limits) del y_limits # Now do some label placement magic... # from reportlab.pdfbase import pdfmetrics # font = pdfmetrics.getFont('Helvetica') # h = (font.face.ascent + font.face.descent) * 0.90 h = self.label_size for x1, x2, labels, anchor in [ (segment_x, segment_x - label_sep, _place_labels(left_labels, y_min, y_max, h), "end"), (segment_x + segment_width, segment_x + segment_width + label_sep, _place_labels(right_labels, y_min, y_max, h), "start"), ]: for (y1, y2, color, back_color, name) in labels: cur_drawing.add(Line(x1, y1, x2, y2, strokeColor=color, strokeWidth=0.25)) #print(name) label_string = String(x2, y2, name, textAnchor=anchor) white = Color(0,0,1) label_string.fontName = 'Helvetica' label_string.fontSize = h temp = str("http://www.google.com") label_string2 = String(x2 + 60, y2, temp, textAnchor=anchor) label_string2.fontName = 'Helvetica' label_string2.fontSize = h label_string2.fillColor = white label_string3 = String(x2 , y2+1.5, temp, textAnchor=anchor) label_string3.fontName = 'Helvetica' label_string3.fontSize = h/8 label_string3.fillColor = white label_string4 = String(x2 , y2+1.0, temp, textAnchor=anchor) label_string4.fontName = 'Helvetica' label_string4.fontSize = h/8 label_string4.fillColor = white label_string5 = String(x2 , y2, temp, textAnchor=anchor) label_string5.fontName = 'Helvetica' label_string5.fontSize = h label_string5.fillColor = white black = Color(0,0,0) label_string.fillColor = black if color_label: label_string.fillColor = color if back_color: w = stringWidth(name, label_string.fontName, label_string.fontSize) if x1 > x2: w = w * -1.0 back_color = "red" R1 = Rect(x2, y2 - 0.1 * h, w, h, strokeColor=back_color, fillColor=back_color) cur_drawing.add(R1) #cur_drawing.add(label_string2) #cur_drawing.add(label_string3) #cur_drawing.add(label_string4) #cur_drawing.add(label_string5) #print (name,"\t",label_string.getBounds()) cur_drawing.add(label_string)
def _draw_labels(self, cur_drawing, left_labels, right_labels): """Layout and draw sub-feature labels for the chromosome (PRIVATE). Tries to place each label at the same vertical position as the feature it applies to, but will adjust the positions to avoid or at least reduce label overlap. Draws the label text and a coloured line linking it to the location (i.e. feature) it applies to. """ if not self._sub_components: return color_label = self._color_labels segment_width = (self.end_x_position - self.start_x_position) * self.chr_percent label_sep = ( self.end_x_position - self.start_x_position ) * self.label_sep_percent segment_x = self.start_x_position + 0.5 * ( self.end_x_position - self.start_x_position - segment_width ) y_limits = [] for sub_component in self._sub_components: y_limits.extend( (sub_component.start_y_position, sub_component.end_y_position) ) y_min = min(y_limits) y_max = max(y_limits) del y_limits # Now do some label placement magic... # from reportlab.pdfbase import pdfmetrics # font = pdfmetrics.getFont('Helvetica') # h = (font.face.ascent + font.face.descent) * 0.90 h = self.label_size for x1, x2, labels, anchor in [ ( segment_x, segment_x - label_sep, _place_labels(left_labels, y_min, y_max, h), "end", ), ( segment_x + segment_width, segment_x + segment_width + label_sep, _place_labels(right_labels, y_min, y_max, h), "start", ), ]: for (y1, y2, color, back_color, name) in labels: cur_drawing.add( Line(x1, y1, x2, y2, strokeColor=color, strokeWidth=0.25) ) label_string = String(x2, y2, name, textAnchor=anchor) label_string.fontName = "Helvetica" label_string.fontSize = h if color_label: label_string.fillColor = color if back_color: w = stringWidth(name, label_string.fontName, label_string.fontSize) if x1 > x2: w = w * -1.0 cur_drawing.add( Rect( x2, y2 - 0.1 * h, w, h, strokeColor=back_color, fillColor=back_color, ) ) cur_drawing.add(label_string)
def makeSectors(self): # normalize slice data if type(self.data) in (ListType, TupleType) and type( self.data[0]) in (ListType, TupleType): #it's a nested list, more than one sequence normData = [] n = [] for l in self.data: t = self.normalizeData(l) normData.append(t) n.append(len(t)) self._seriesCount = max(n) else: normData = self.normalizeData(self.data) n = len(normData) self._seriesCount = n #labels if self.labels is None: labels = [] if type(n) not in (ListType, TupleType): labels = [''] * n else: for m in n: labels = list(labels) + [''] * m else: labels = self.labels #there's no point in raising errors for less than enough labels if #we silently create all for the extreme case of no labels. if type(n) not in (ListType, TupleType): i = n - len(labels) if i > 0: labels = list(labels) + [''] * i else: tlab = 0 for m in n: tlab = tlab + m i = tlab - len(labels) if i > 0: labels = list(labels) + [''] * i xradius = self.width / 2.0 yradius = self.height / 2.0 centerx = self.x + xradius centery = self.y + yradius if self.direction == "anticlockwise": whichWay = 1 else: whichWay = -1 g = Group() sn = 0 startAngle = self.startAngle #% 360 styleCount = len(self.slices) if type(self.data[0]) in (ListType, TupleType): #multi-series doughnut iradius = (self.height / 5.0) / len(self.data) for series in normData: i = 0 for angle in series: endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle - endAngle) >= 1e-5: if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if type(n) in (ListType, TupleType): theSector = Wedge( cx, cy, xradius + (sn * iradius) - iradius, a1, a2, yradius=yradius + (sn * iradius) - iradius, radius1=yradius + (sn * iradius) - (2 * iradius)) else: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) startAngle = endAngle text = self.getSeriesName(i, '') if text: averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) _addWedgeLabel(self, text, g.add, averageAngle, labelX, labelY, sectorStyle) i = i + 1 sn = sn + 1 else: i = 0 #single series doughnut iradius = self.height / 5.0 for angle in normData: endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle - endAngle) >= 1e-5: if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if n > 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) elif n == 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, iradius=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) # now draw a label if labels[i] != "": averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) theLabel = String(labelX, labelY, labels[i]) theLabel.textAnchor = "middle" theLabel.fontSize = sectorStyle.fontSize theLabel.fontName = sectorStyle.fontName theLabel.fillColor = sectorStyle.fontColor g.add(theLabel) startAngle = endAngle i = i + 1 return g