Report chart hides bar value labels when update BarRenderer

I'm having some issues with Bar Chart in report module, I updated the chart renderer to a custom one (BarRenderer) to change each bar depend on the value, and it worked but after that, all the bar value labels just disappeared

The code:

def configureChart(self, chart):
	from org.jfree.chart.renderer.category import BarRenderer, StandardBarPainter, AbstractCategoryItemRenderer
	from org.jfree.chart.labels import StandardCategoryItemLabelGenerator
	from org.jfree.ui import RectangleInsets, Layer
	from org.jfree.chart.plot import ValueMarker
	from java.awt import Color, BasicStroke#, RenderingHints
	from java.text import NumberFormat
	
	design = "test"
	mTarget = 0.01
	axisLimiter = 0.00001
	chartValueLimiter = 0.00002
	dataKey = "Rend_"
	chart.setTitle(design)
	
	# ------ Chart label format configuration ------
	numberFormat = NumberFormat.getInstance()
	numberFormat.setMaximumFractionDigits(6)
	numberFormat.setMinimumFractionDigits(6)
	defaultFormat = StandardCategoryItemLabelGenerator.DEFAULT_LABEL_FORMAT_STRING
	labelGenerator = StandardCategoryItemLabelGenerator(defaultFormat, numberFormat)
	#chart.getCategoryPlot().getRenderer().setBaseItemLabelGenerator(labelGenerator)
	#chart.getCategoryPlot().getRenderer().setBaseItemLabelPaint(Color.black)
	
	# ----- Chart marker configuration ---------
	marker = ValueMarker(mTarget) # position is the value on the axis
	#marker.setLabel('%.4f in'%mTarget)
	marker.setPaint(Color(136, 31, 31))
	marker.setStroke(BasicStroke(0.75))
	marker.setLabelOffset(RectangleInsets(10,20,0,0))
	#marker.setAlpha(0.47)
	chart.getPlot().addRangeMarker(marker, Layer.BACKGROUND)
	
	# ----- Chart Y axis configuration ---------
	axisMin = 9999
	axisMax = 0
	ds = self.data
	#print data.items()
	for i in range(0, ds.getRowCount()):
		cnt = ds.getValueAt(i, 1)
		axisMin = cnt if cnt < axisMin else axisMin
		axisMax = cnt if cnt > axisMax else axisMax
	#print axisMin, axisMax
	if axisMin == axisMax:
		if axisMin < mTarget: 
			axisMin = axisMin - axisLimiter
			axisMax = mTarget + axisLimiter
		elif axisMin > mTarget:
			axisMin = mTarget - axisLimiter
			axisMax = axisMax + axisLimiter
	else:
		axisMin = mTarget + axisLimiter if axisMin - axisLimiter > mTarget else axisMin - axisLimiter
		axisMax = mTarget + axisLimiter if axisMax + axisLimiter < mTarget else axisMax + axisLimiter
	#print 'New axis range: ', axisMin, axisMax		
	chart.getPlot().getRangeAxis().setNumberFormatOverride(numberFormat)
	chart.plot.rangeAxis.setRange(axisMin, axisMax)
	chart.getPlot().getRangeAxis().setVisible(True)
	"""
	#Change each bar color
	class CustomRenderer(BarRenderer):
		def getItemPaint(self, row, column):
			cntValue = chart.getCategoryPlot().getDataset().getValue(row, column)
			inRange = cntValue > mTarget-chartValueLimiter and cntValue < mTarget+chartValueLimiter
			return Color.green if inRange else Color.red
	chart.getCategoryPlot().setRenderer(CustomRenderer())
	"""
	chart.getCategoryPlot().getRenderer().setBaseItemLabelGenerator(labelGenerator)
	chart.getCategoryPlot().getRenderer().setBaseItemLabelPaint(Color.black)
	#Remove shadows and gradients
	chart.getCategoryPlot().getRenderer().setBarPainter(StandardBarPainter())
	chart.getCategoryPlot().getRenderer().setShadowVisible(False)

This is the chart with the commented code:
image
And without it:
image
What I think is the BarRender class has another method to set the labels but i haven't found the way yet
Any ideas?

This is doable, but you have to set the label generator to your custom renderer and then set its visibility to true. You will get the result you are looking for if you change your commented code to look like this:

	class CustomRenderer(BarRenderer):
		def getItemPaint(self, row, column):
			cntValue = chart.getCategoryPlot().getDataset().getValue(row, column)
			inRange = cntValue > mTarget-chartValueLimiter and cntValue < mTarget+chartValueLimiter
			return Color.green if inRange else Color.red
	chart.getCategoryPlot().setRenderer(CustomRenderer())
	modifiedRenderer = chart.getCategoryPlot().getRenderer()
	modifiedRenderer.setBaseItemLabelGenerator(labelGenerator)
	modifiedRenderer.setBaseItemLabelsVisible(True)

This code gets the modified renderer after it has been set, and subsequently applies the desired labels using the label generator that you already have in place in line 21 of your code.

2 Likes

lol I feel so dumb right now, just needed to add the .setBaseItemLabelsVisible(True) method hahaha
Thank u so much, it worked :smiley:

2 Likes