Re: Set verticalbarchart label x, y positions depending on value
Kostadin Atanasov <[email protected]>
| Newsgroups | gmane.comp.python.reportlab.user |
|---|---|
| Message-ID | <DB6PR0801MB1349BA35843B7D99680D3D3BA9320@DB6PR0801MB1349.eurprd08.prod.outlook.com> |
I usually calculate the value of each series (segment in the bar) as a % of the max Y scale value and use it to decide whether to display the label at all (the label is still in absolute units, the % is only for decision). My cutoff is around 3 or 4%. Typically if the value is so low nobody is very worried that the label is missing. If you have many cases of values below 4% this means that your bar is very fragmented - then you have a different problem - probably bar is not the best visualisation. Kostadin Atanasov ________________________________ From: reportlab-users <[email protected]> on behalf of Robin Becker <[email protected]> Sent: Monday, August 20, 2018 5:38:10 PM To: reportlab-users Subject: Re: [reportlab-users] Set verticalbarchart label x, y positions depending on value On 18/08/2018 00:14, Matt Bartolome wrote: > Hi, I have a stacked vertical bar chart where I need to either manually > place labels or iterate over the existing labels and move them based on > their position (crossing my fingers that there is a simpler way). The > problem I have is that my stacked bar chart has overlapping labels when the > y values are close to zero because of the scale of my chart. > > My barLabels settings are like so: > > self.chart.barLabelFormat = lambda x: '${0}'.format(x) if x > 0 else None > self.chart.barLabels.boxAnchor = 'w' > self.chart.barLabels.boxFillColor = None > self.chart.barLabels.boxStrokeColor = None > self.chart.barLabels.fontName = fontName > self.chart.barLabels.fontSize = 6 > self.chart.barLabels.dy = 5 > self.chart.barLabels.dx = -8 > self.chart.barLabels.boxTarget = 'mid' > > I was hoping there was a setting to avoid overlap, but if that doesn't > exist I would like to loop over the x,y positions of the existing labels > and create my own simple labels to replace them but I can't figure out how I don't think we have a magic way to get the bar labels to not overlap; normally people want stacked bar labels to be inside the bar, but as you observe when bars become short there's no place to put the label inside. However, here is some code I have used in the past def label_fixer(chart,colors,needed): vA = chart.valueAxis vA.setPosition(chart.x, chart.y, chart.height) chart._getConfigureData() vA.configure(chart._configureData) barLabels = chart.barLabels for i,d in enumerate(chart.data): for j, v in enumerate(d): if v is None: continue h = v * vA._scaleFactor bl = barLabels[(i,j)] if needed<=h: bl.boxAnchor = 'n' bl.fillColor = barLabels.fillColor bl.dx = bl.dy = 0 elif v>0: bl.fillColor = colors[i] if not i: bl.boxAnchor = 'nw' bl.dx = chart.barWidth * 0.5 else: bl.boxAnchor = 's' and in the chart code getContents method label_fixer(chart=chart,needed=1.2*chart.barLabels.fontSize+4, colors=[self._orange,self._grey]) this was for a simple chart where the top of two stacked bars was likely to be too small. If that happens the bar is moved up so is outside. If the lower bar needs a fix we moved the label to the side and downwards (bl.boxAnchor = 'nw'), The main idea is to get the scaling and then you can check how tall the bar is going to be. Then you need a strategy for changing the default position. > to do that. > > Thanks, > Matt > ........ -- Robin Becker _______________________________________________ reportlab-users mailing list [email protected] https://pairlist2.pair.net/mailman/listinfo/reportlab-users