Is there a way to include some arbitrary text in the legend in a JFreeChart PieChart? I know it's possible to assign a PieSectionLabelGenerator
in order to customize the labels of each of the Pie's sections that appear on the chart's legend.
I'd like to insert some text into the legend, completely unrelated to any of the pie sections, like, for instance, "Legend".
I'm building the Chart like this:
private JFreeChart constructChart() {
List<Object[]> llistaValorsArr;
ParamsDTO dto = (ParamsDTO) getModelObject();
List llistaValors = statisticsService.getStatistics(dto);
if (!llistaValors.isEmpty() && !(llistaValors.get(0) instanceof Object[])){
llistaValorsArr = new ArrayList<Object[]>();
llistaValorsArr.add(new Object[]{llistaValors.get(0), ""});
}
else{
llistaValorsArr = (List<Object[]>) llistaValors;
}
DefaultPieDataset dataSet = new DefaultPieDataset();
for (Object[] objects : llistaValorsArr) {
dataSet.setValue((Comparable) objects[1], (Number)objects[0]);
}
String title = "Total: " + new Double(DatasetUtilities.calculatePieDatasetTotal(dataSet)).intValue();
JFreeChart chart = ChartFactory.createPieChart(title, dataSet, true, false, true);
final PiePlot plot = (PiePlot) chart.getPlot();
plot.setForegroundAlpha(0.5f);
plot.setNoDataMessage("No data");
PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator("{0} - {1} ({2})"){
@Override
protected Object[] createItemArray(PieDataset dataset, Comparable key) {
// TODO Auto-generated method stub
Object[] array = super.createItemArray(dataset, key);
array[0] = getEntityLabel(key);
return array;
}
};
plot.setLabelGenerator(labelGenerator);
plot.setLegendLabelGenerator(labelGenerator);
//plot.setStartAngle(290);
boolean circular = true;
plot.setCircular(circular);
return chart;
}
UPDATE: I just found out JFreeChart.addSubtitle()
, hoping it would allow to position it just above the legend, but it will just add a subtitle next to the chart's Title.
UPDATE 2: I've been trying to place a TextTitle
inside the LegendTitle
's wrapper, but it appears to be null at chart construction time.
LegendTitle legend = chart.getLegend();
BlockContainer container = legend.getWrapper();
container.add(new TextTitle("Legend"));
It shouldn't really be that complicated to add a 'Legend' text to decorate the legend.
Looking at the source code of org.jfree.chart.JFreeChart
, and seeing that addLegend()
is nothing more than addSubtitle()
behind the scenes, everything indicates that this should be achieved using addSubtitle()
.
Looking at the part where org.jfree.chart.JFreeChart
adds its own LegendTitle
item, we can find the setup JFreeChart
uses for placing the Legend here.
So, the solution is to add, for instance, a TextTitle
to the Chart
in an analogous way. The relevant setting here is setPosition(RECTANGLE.BOTTOM)
.
TextTitle legendText = new TextTitle("This is LEGEND: ");
legendText.setPosition(RectangleEdge.BOTTOM);
chart.addSubtitle(legendText);
I have a Multi Axis chart that i recently built and came up with this scheme to distinguish the time periods i was displaying using a line chart to show the previous 12 months imposed over a bar chart showing the current 12 months.
If you want to add text before your other series so that your legend looks something like this:
Previous 12 Months: * charges * adj * cash Current 12 Months: * charges * adj * cash
where the *'s are the shapes/colors of your series. (i would have included a pic, but i dont have enough rep points ... this is my first post to stack overflow =) )
Then i would suggest adding a series and making it the first series in your chart(s) (series 0). Name this series whatever text you want to display (my example is "Previous 12 Months: ". Then you can use some java to customize series 0 so that the data is not show on the chart, but you still get the label in the legend.
This is what my custmoize method for making a line chart line/shape not visible:
@Override
public void customize(JFreeChart chart, JRChart jasperChart) {
LineAndShapeRenderer renderer = (LineAndShapeRenderer) chart.getCategoryPlot().getRenderer();
renderer.setSeriesLinesVisible(0, false);
renderer.setSeriesShapesVisible(0, false);
etc ....
}
If it is another type of chart like the bar chart then just make series 0's color to match the background and give it a value like 1. Note that this does add more space between the bars! The extra space between the bars on my chart made it look better, but this wouldn't be a good solution if you like the spacing between your charts bars.
Not sure if this is useful for answering the initial question but its another option for anyone looking to add text the their charts legend.
Enjoy!
Another possibility is to create a class implementing the interface org.jfree.chart.LegendItemSource
which provides all your additional legend items. Then you add your own LegendItemSource
to your LegendTitle
object (the only other item source is the PieChart).
chart.getLegend().setSources(sourcesContainingTheOriginalAndYourNewOne);
If you want to control where to place the legend items or in which orderm of each item source, you can override LegendTitle.