Dynamic report chart, legend not hiding unused pens

As it can bee seen in the below picture, all my preconfigured pens are showing in the legend. How can I hide those not used? The solution below does not do anything (commented with # added )


image
I almost have a dynamic reporting chart. (supplying variable amount of pens into a reporting chart. Thanks to @PGriffith for the following code:

########################################################
	#builds a new dataset, removes null pens:
	#import system
	from org.jfree.data.xy import DefaultXYDataset
	from org.jfree.data.xy import LegendItemCollection # added (trying to delete legend items not used)
	plot = chart.getPlot()
	renderer = plot.getRenderer()
	legenditems = plot.getLegendItems()
	dataset = plot.getDataset()
	newds = DefaultXYDataset()
	
	newLegendItems=LegendItemCollection()  # added (trying to delete legend items not used)

	xlist = range(dataset.getItemCount(0))
	for col in range(dataset.getSeriesCount()):
		ylist = []
		for row in range(dataset.getItemCount(col)):
			ylist.append(dataset.getY(col, row))
		try: 
			sum(ylist)
			newds.addSeries(legenditems.get(col).getLabel(), [xlist, ylist])
			newLegendItems.add(legenditems.get(col))  # added (trying to delete legend items not used)
		except TypeError:
			del ylist
			
	renderer.setSeriesPaint(4, Color.BLACK) # this is to activate the theme from the normal pen settings of the chart
	
	plot.setDataset(0, newds)
	plot.setFixedLegendItems(newLegendItems)  # added (trying to delete legend items not used)

Last I would love to have a real time axis, but I have understood that this is impossible for the average mortal beeing… (or?) :slight_smile:

1 Like

Take a look at this other post of mine about changing the legend:

The trick is to implement a 'custom' XYItemRenderer class that allows you to provide your own arbitrary set of legend items to display.

1 Like

Thank you this worked!

The reporting timeseries chart can now support a dynamic dataset.

A short how to for the next guy:

  1. Define the maximum amount of pens your chart will have.
  2. Edit the chart-script according to the code below.
  3. Populate your chart like you normally do.

Just make sure that your pen labels for the chart are the same as your dataset(datasource) column labels. This is used to match which labels to hide. See screenshot below:

Code for hiding legend items not used:

from org.jfree.chart.renderer.xy import XYLineAndShapeRenderer
	from org.jfree.chart import LegendItem
		
	plot = chart.getPlot()
	renderer = plot.getRenderer()
	legend = chart.getLegend()
	legenditems = plot.getLegendItems()
	dataset = plot.getDataset()
	
	xlist = range(dataset.getItemCount(0))
	includedLabels=[]
	for col in range(dataset.getSeriesCount()):
		ylist = [dataset.getY(col, row) for row in range(dataset.getItemCount(col))]
		try: 
			sum(ylist)
			includedLabels.append(legenditems.get(col).getLabel())
		except TypeError:
			pass
			
	class CustomRenderer(XYLineAndShapeRenderer):
		def getLegendItem(self, dataset, series):
			original = renderer.getLegendItem(dataset, series)
			new = LegendItem(
				original.getLabel(),
				original.getDescription(),
				original.getToolTipText(),
				"", #urlText
				original.getShape(),
				original.getLinePaint(), #set fill paint to line paint
				original.getOutlineStroke(),
				original.getOutlinePaint()
			)
			new.setSeriesIndex(series)
			new.setDatasetIndex(dataset)
			return new
		
		def getLegendItems(self):
			collection = XYLineAndShapeRenderer.getLegendItems(self)
			for ds in range(plot.getDatasetCount()):
				for series in range(plot.getSeriesCount()):
					legend = self.getLegendItem(ds, series)
					if legend.getLabel() in includedLabels:
						collection.add(legend)
			return collection
	
	newRenderer = CustomRenderer(True, False)
	newRenderer.setBaseSeriesVisibleInLegend(True)
	legend.setSources([newRenderer])
4 Likes