Can’t Serialize JFreeChart Chart?

I was getting a serialization exception when I tried to serialize a JFreeChart chart to a file. The error message and corresponding stacktrace offered little in the way of clues. I finally figured out that the problem was with an interface implementation I had set for generating custom legend item labels. I used a lambda expression to supply the interface (XYSeriesLabelGenerator) implementation. Alternatively, one might use an anonymous inner class to provide the implementation. Neither of these approaches will work, as it is not possible (as far as I know) to implement the Serializable interface for the implementation. So, I used the good, old, named top-level class:

Source Code for CustomSeriesLabelGenerator

XYItemRenderer renderer = ...;
renderer.setLegendItemLabelGenerator(
        new CustomSeriesLabelGenerator());

So, if you are getting an error when serializing a JFreeChart chart, check how you have passed any interface implementations into a setter… that may be the problem.

JFreeChart Tool Tips for Multiple Data Series

In a JFreeChart x-y scatter chart I have two series of data. I needed to add custom tool tips CustomXYToolTipGenerator for each series. The first approach I tried I never was able to get it to work:

XYPlot plot = ...;
XYItemRenderer renderer = plot.getRenderer();
List<String> tips1 = ...;
List<String> tips2 = ...;
CustomXYToolTipGenerator tipGenerator1 =
        new CustomXYToolTipGenerator();
tipGenerator1.addToolTipSeries(tips1);
CustomXYToolTipGenerator tipGenerator2 =
        new CustomXYToolTipGenerator();
tipGenerator2.addToolTipSeries(tips2);
renderer.setBaseToolTipGenerator(null);
renderer.setSeriesToolTipGenerator(0,
        tipGenerator1);
renderer.setSeriesToolTipGenerator(1,
        tipGenerator2);

The tool tips for the first series would work, but there would be no tool tips for the second series.

Luckily, there is a second approach, which worked:

CustomXYToolTipGenerator tipGenerator =
        new CustomXYToolTipGenerator();
tipGenerator.addToolTipSeries(tips1);
tipGenerator.addToolTipSeries(tips2);
renderer.setBaseToolTipGenerator(tipGenerator);

If I ever figure out why the first approach did not work, I will update this post. If anybody has an idea, please leave a comment! Thanks!

Custom XY Tool Tip Generator in JFreeChart

Using JFreeChart I added a custom xy tool tip generator to a scatter plot:

JFreeChart chart = ChartFactory.createScatterPlot( ... );
XYPlot plot = chart.getXYPlot();
XYItemRenderer renderer = plot.getRenderer();
CustomXYToolTipGenerator tipGenerator =
         new CustomXYToolTipGenerator();
List tipsMain = new ArrayList<>();
tipGenerator.addToolTipSeries(tipsMain);
renderer.setBaseToolTipGenerator(tipGenerator);

I then populated the data for the series and the tool tips:

XYSeries series1 = new XYSeries("S1");
for (TechBundle bundle : techBundles) {
    double cost = bundle.getCost();
    double fe   = bundle.getFE();
    series1.add(cost, fe);
    tipsMain.add(String.format("%s $%.0f %.2f",
            bundle.getBundleID(), cost, fe));
}

The problem was the tool tips were not correct for the point. Tool tip for point n would be shown for point m.

This is due to the fact that by default the xy series is automatically sorted (in ascending order of x-values). That sorting messed-up the alignment of the data and the tool tips. The fix is to turn-off the automatic sorting, which must be done when the series is constructed:

XYSeries series1 = new XYSeries("S1", false);