EasyChart legend: increase key line width and change colours

Sorry for the potentially simple question (my java knowledge is very basic). I’ve looked through the API for the PMIEasyChart and JFreeChart, but am more or less fumbling around…

Is it possible to increase the width of the lines in the key legend on the EasyChart - without increasing the pen line width - via python?
I’d like to keep the pen width set to 1, but set the corresponding legend item to 2, for example, to help to distinguish colours apart.

Similarly, is it possible to change the legend background colour to match the background colour in the chart area, and the pen label font colour ?

Cheers

1 Like

While someone probably has a cool scripting solution for you, here’s the poor man’s version I’ve sucessfully used on one of our dashboards: hide the legend and use labels instead. Example attached.

2 Likes
	from java.awt import BasicStroke,Font
	
	plot = chart.getPlot()
	renderer = plot.getRenderer()
	
	renderer.setBaseLegendTextFont(Font("Arial",Font.BOLD,16))
	
	seriesIndex = 0
	lineWidth = 4
	renderer.setSeriesStroke(seriesIndex,BasicStroke(lineWidth))
1 Like

Jae’s is closer to what you want, but for the sake of it, here’s as far as I got without modifying the line actually drawn on the chart:

	renderer = chart.getPlot().getRenderer()
	shape = renderer.getLegendLine()
	
	rect = shape.getBounds2D()
	rect.setRect(shape.getX1(), shape.getY1(), rect.getWidth(), rect.getHeight() + 4)
	
	renderer.setLegendLine(rect)

1 Like

Oops, didn’t check to see that it modified the graph’s width too.

Well, that ended up being way more involved than I figured it would be. But because I enjoyed myself:
(Preemptive disclaimer: Don’t even think of trying to call in to support if this doesn’t work for you)

	from org.jfree.chart.renderer.xy import XYLineAndShapeRenderer
	from org.jfree.chart import LegendItem
	legend = chart.getLegend()
	plot = chart.getPlot()
	renderer = plot.getRenderer()
	
	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)
					collection.add(legend)
			return collection
			
	newRenderer = CustomRenderer(True, False)
	newRenderer.setBaseSeriesVisibleInLegend(True)
	legend.setSources([newRenderer])

6 Likes

That was a chuckle I needed. :laughing:

Oh, yeah, and to answer the other questions about tying the legend background to the chart background, add this:

	legend.setBackgroundPaint(self.background)
	legend.setItemPaint(self.foreground)

4 Likes

Hi Paul,

Firstly thanks a lot for your time, I didn’t realise that it would be so involved!

Where do I need to add this script to? It looks like you defined in within a custom method (due to ‘self’), or a script library. If so, what parameters do I need to define?

I’ve looked in the API in the definitions for PMIEasyChart and PMIChart and can’t find the method getPlot() (PMIChart has getPlots()) so I’m curious how you found this? I’m still very new to Python and Java…

Cheers again

This code would be a drop in on the configureChart extension function; if you are trying to fire it from an external source it takes more coercing to get the root JFreeChart object.

As for the code itself: It’s a combination of a lot of diving into the JFreeChart API manual and knowledge that I’ve acquired by brute forcing/shamelessly copying examples posted elsewhere online.

I also removed the legend border:

	from org.jfree.chart.block import BlockBorder 
	chart.legend.setFrame(BlockBorder.NONE)
2 Likes

I’ve been trying to change the position of the Legend from the bottom to the right and I just can’t get it to work. if I do the “.getPosition()” it will give me the current position “RectangleEdge.BOTTOM”, but if I try to use the “.setPosition” I get the following error:
‘org.jfree.chart.title.LegendTitle’ object has no attribute ‘setPostion’
I’m super new to JAVA to be honest.

Here’s the code

from java.awt import Color,BasicStroke,Font
from org.jfree.chart import LegendItem

plot = chart.getPlot()
legend = chart.getLegend()



print legend.getPosition()
legend.setPostion(RectangleEdge.RIGHT)

Typo in setPosition(). You’re missing an ‘i’.

Well, that’s embarrassing…Still getting this error.

global name ‘RectangleEdge’ is not defined

You need to import RectangleEdge.

Thanks for your help! Finally got it. :slight_smile:

1 Like

This works great with a single subplot, but fails when a second subplot is added.
I’ll browse the JFreeChart API manual to see if I can make it work with two subplots, but in case someone sees this that has already figured this out, that would save me some time!

Use a technique like this to account for each subplot:
http://forum.inductiveautomation.com/t/labels-for-data-points-in-chart/14740/5?u=pgriffith

Thanks! I’ll give this a try!