"Vertical labels" from reportlab.lib.colors import PCMYKColor, Color, CMYKColor, black from reportlab.graphics.charts.legends import Legend from reportlab.graphics.shapes import Drawing, _DrawingEditorMixin, String, Line from reportlab.lib.validators import Auto from reportlab.lib.formatters import DecimalFormatter from reportlab.graphics.charts.barcharts import VerticalBarChart from reportlab.graphics.charts.textlabels import Label from reportlab.pdfbase.pdfmetrics import stringWidth, EmbeddedType1Face, registerTypeFace, Font, registerFont class BarChart10(_DrawingEditorMixin,Drawing): ''' Chart Features -------------- - The bar labels are vertical, this is controlled through the **chart.barLabels.angle** property. - Simple category axis: dates are not necessary here. This chart was built with our [Diagra](https://docs.reportlab.com/diagra/) solution. Not the kind of chart you looking for? Go [up](..) for more charts, or to see different types of charts click on [ReportLab Charts Gallery](/chartgallery/). ''' def __init__(self,width=348,height=146,*args,**kw): Drawing.__init__(self,width,height,*args,**kw) # adding a vertical bar chart self._add(self,VerticalBarChart(),name='chart',validate=None,desc=None) # setting font fontName = 'Helvetica' # fontSize = 6 for bar labels, 7 for legend, 8 for axis labels # chart settings self.chart.width = 334 # it takes all the area - below also works #self.chart.width = self.width - self.chart.x self.chart.height = 91 #self.height - self.chart.y -2 self.chart.fillColor = None # bar properties self.chart.groupSpacing = 20 self.chart.barSpacing = 1 self.chart.bars.strokeWidth = 0 self.chart.bars.strokeColor = None #self.chart.fillColor self.chart.barLabels.angle = 90 self.chart.barLabelFormat = DecimalFormatter(2) self.chart.barLabels.boxAnchor ='w' self.chart.barLabels.boxFillColor = None self.chart.barLabels.boxStrokeColor= None self.chart.barLabels.fontName = fontName self.chart.barLabels.fontSize = 5 self.chart.barLabels.dy = 3 self.chart.barLabels.boxTarget = 'hi' # value axis properties self.chart.valueAxis.labels.fontName = fontName self.chart.valueAxis.labels.fontSize = 8 self.chart.valueAxis.strokeDashArray = (5,0) self.chart.valueAxis.visibleGrid = False self.chart.valueAxis.strokeWidth = 0.25 self.chart.valueAxis.avoidBoundFrac = 0.5 self.chart.valueAxis.rangeRound ='both' self.chart.valueAxis.gridStart = 13 self.chart.valueAxis.gridEnd = 342 self.chart.valueAxis.labelTextFormat = DecimalFormatter(0, suffix=None, prefix=None) self.chart.valueAxis.labels.boxAnchor='e' self.chart.valueAxis.labels.dx = -1 self.chart.valueAxis.visibleTicks = 0 # category axis properties self.chart.categoryAxis.strokeDashArray = (5,0) self.chart.categoryAxis.visibleGrid = False self.chart.categoryAxis.visibleTicks = True self.chart.categoryAxis.strokeWidth = 0.25 self.chart.categoryAxis.tickUp = 3 self.chart.categoryAxis.tickDown = 0 self.chart.categoryAxis.labelAxisMode ='low' self.chart.categoryAxis.labels.textAnchor = 'middle' self.chart.categoryAxis.labels.boxAnchor = 'n' self.chart.categoryAxis.labels.fillColor = black self.chart.categoryAxis.labels.angle = 0 self.chart.categoryAxis.labels.fontName = fontName self.chart.categoryAxis.labels.fontSize = 7 #8 self.chart.categoryAxis.labels.dx = 0 #-10 self.chart.categoryAxis.labels.dy = -2 # adding legend self._add(self,Legend(),name='legend',validate=None,desc=None) self.legend.boxAnchor = 'nw' self.legend.deltax = 0 self.legend.deltay = 10 self.legend.columnMaximum = 3 self.legend.fontName = fontName self.legend.fontSize = 6 self.legend.alignment = 'right' self.legend.strokeWidth = 0 self.legend.strokeColor = None self.legend.autoXPadding = 0 self.legend.dx = 7 self.legend.dy = 7 self.legend.dxTextSpace = 7 self.legend.variColumn = True self.legend.subCols.minWidth = 157 #self.chart.width/2 self.legend.colorNamePairs = Auto(obj=self.chart) # adding a horizontal line to the chart self.chart.annotations=[lambda c,cA,vA: Line(c.x,c.y,c.x+c.width,c.y,strokeColor=black,strokeWidth=0.5)] # sample data colorsList = [PCMYKColor(0,0,0,100,spotName='XXX X',alpha=100), PCMYKColor(50,0,25,30,spotName='7475C',alpha=100), PCMYKColor(50,0,25,30,spotName='7475C',density=40,alpha=100), PCMYKColor(0,0,0,50,spotName='XXX X',alpha=100), PCMYKColor(0,0,0,25,spotName='XXX X',alpha=100), PCMYKColor(0,0,0,40,spotName='XXX X',alpha=100), PCMYKColor(50,0,25,30,spotName='7475C',density=25,alpha=100), PCMYKColor(0,0,0,25,spotName='XXX X',alpha=100)] series = 'BP', 'Shell Transport & Trading', 'Liberty International', 'Persimmon', 'Royal Bank of Scotland', for i, s in enumerate(series): self.chart.bars[i].name = s self.chart.data = [[-9.0299999999999994, -9.0299999999999994, -4.5800000000000001, 7.2699999999999996, 11.109999999999999], [-9.4399999999999995, -9.4399999999999995, -5.0700000000000003, 5.8499999999999996, 0.0], [2.1699999999999999, 2.1699999999999999, 7.6600000000000001, 0.0, 4.5800000000000001], [-5.1399999999999997, -5.1399999999999997, 0.0, 8.1699999999999999, 11.380000000000001], [-4.8799999999999999, -4.8799999999999999, 0.02, 5.8099999999999996, 8.6999999999999993]] for i, _ in enumerate(self.chart.data): self.chart.bars[i].fillColor = colorsList[i] self.chart.categoryAxis.categoryNames = [u'Quarter', u'YTD', u'1-year', u'3-year', u'5-year'] # defining initial colours set, this will be replaced by the palette on running # applying colours to bars self.width = 400 self.height = 200 self.chart.x = 24 self.chart.y = 60 self.legend.x = 24 self.legend.y = 35 self.chart.bars[0].fillColor = PCMYKColor(23,51,0,4,spotName='XXX X',alpha=100) self.chart.bars[2].fillColor = PCMYKColor(100,60,0,50,alpha=100) self.chart.bars[3].fillColor = PCMYKColor(100,0,90,50,alpha=100) self.chart.bars[4].fillColor = PCMYKColor(0,100,100,40,alpha=100) self.chart.bars[1].fillColor = PCMYKColor(66,13,0,22,alpha=100) if __name__=="__main__": #NORUNTESTS BarChart10().save(formats=['pdf'],outDir='.',fnRoot=None)