Buy me a coffee »

Simple chart creation with JFreeChart

While writing my book I encountered a use case where I needed chart representation of data. I used JFreeChart to solve this problem and now I’ll show you some features how it goes.

If you need to create charts from data in Java, JFreeChart is the ideal free tool for this: it is easy to use and has available documentation — if you search after it. The only minor drawback is that the complete developers guide is only available for some spent dollars. This helps the developers to maintain this project.

And this introduction into JFreeChart is not a complete documentation I just show you how to create a simple chart from your dataset — what I needed to my book.

My examples will create a scatter plot chart where points and/or lines are displayed.

Prerequisite

You need JFreeChart as a dependency in your project. I use Maven, so my dependency goes as follows:

<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.0.19</version>
</dependency>

Creating a chart

Creating a chart is simple.

First you need the data you want to represent. My fits into an XYSeries object because I have a sequence of items with two parameters: x and y. By default, data in XYSeries gets sorted by x automatically.

XYSeries series = new XYSeries("Test data");

The XYSeries constructor needs a comparable key as parameter, which identifies the series.

This series of data has to be wrapped up into a collection because the ChartFactory needs an XYDataset to represent. This is because you can display multiple set of data in your chart.

XYSeriesCollection datasetJsoup = new XYSeriesCollection();
datasetJsoup.addSeries(series);

To create a chart use ChartFactory and its methods.

JFreeChart chart = ChartFactory.createScatterPlot(chartTitle, xAxisTitle, yAxisTitle, datasetJsoup);

Now you have a working chart which you can render in your application or save to the file system.

Saving the chart as an image

You can display your charts in your application or save them to image files or PDF. I will not go into detail how to render the created charts in your application or how you can save it to PDF. This is out of my current focus. However I’ll show how to save the chart to a picture file.

For this JFreeChart has the ChartUtilities class, and this class provides nice utility methods to save charts as JPEG or PNG images.

ChartUtilities.saveChartAsPNG(new File(filename), chart, width, height);

As you can see in the example above it is really a one liner. For JPEG images you can call ChartUtilities.saveChartAsJPEG with the same arguments.

And the result looks like this:

single_work2

Displaying all the data in a single chart with a single value range

 

Multiple axis

When working on my book I had to display test results of two different ranges in one chart.

First I created the chart with the datasets. The result was two lines in the chart: one on the bottom one on the top. And in-between a lot of empty space — as you can see in the previous section.

Then I thought multiple value axis would be better: one displays the values of the lower results, and one the values of the higher.

So I separated the two dataset-collections into two XYSersiesCollections and created the chart with the first dataset. Then added the second dataset to the same plot but I modified the range axis representation:

final XYSeriesCollection datasetJsoup = new XYSeriesCollection();
final XYSeriesCollection datasetXmlbeam = new XYSeriesCollection();

final JFreeChart chart = ChartFactory.createScatterPlot(chartTitle, "Iteration", "JSoup time in millis", datasetJsoup);

final ValueAxis secondary = createRangeAxis("XMLBeam time in millis", 500, true, false);
final XYPlot xyPlot = (XYPlot) chart.getPlot();
xyPlot.setRangeAxis(1, secondary);
xyPlot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
xyPlot.setDataset(1, datasetXmlbeam);
xyPlot.mapDatasetToRangeAxis(1, 1);
final XYItemRenderer renderer = new XYLineAndShapeRenderer(false, true);
renderer.setSeriesPaint(0, Color.CYAN);
xyPlot.setRenderer(1, renderer);

The code above creates a secondary value axis for the data range (in this case the Y axis), adds this range to the same plot which was generated with the ChartFactory.

The ItemRenderer makes the representation of the secondary dataset change its colours because if I’d not add it, the two datasets would get the same three colours.

 

The result looks like this:

multiple_work2

Multiple data ranges in the same diagram with different axis

 

The XYLineAndShapeRenderer

As you can see above, the XYLineAndShapeRenderer takes two arguments when creating and both are boolean. The first one tells the renderer to show lines between the points, the second to show the shapes.

If both values are false, you’ll see nothing on your chart. If both are true, you see lines in-between the points and the shapes. If you set the second parameter to false and the first to true, then you get a line graph and the line changes direction at the points.

Multiple plots in one chart

The result of Multiple axis wasn’t the one I needed. So I searched for another solution and I’ve found that multiple plots in one chart would do the trick. Or at least I hoped.

For this I used the two XYSeriesCollections created in the previous section but added them to two different plots with different configuration:

CombinedDomainXYPlot plot = new CombinedDomainXYPlot(domainAxis);
plot.add(createXYPlot(datasetXmlbeam, domainAxis, createRangeAxis("XMLBeam runtime in millis", 500, true, false)));
plot.add(createXYPlot(datasetJsoup, domainAxis, createRangeAxis("JSoup runtime in millis", 100, true, false)));
plot.setOrientation(PlotOrientation.VERTICAL);
final JFreeChart chart = new JFreeChart(chartTitle, JFreeChart.DEFAULT_TITLE_FONT, plot, true);

The key of this feature is the CombinedDomainXYPlot: it lets you to add more plots to the same chart — and have different value axis representations for the datasets but the same domain axis.

The alternative is the CombinedRangeXYPlot where you have different domains but the same value range for your plots.

The result looks like this:

combined_work2

Displaying the datasets in one chart but two distinct plots

 

FSE

FSE is the Future State Edition of JFreeChart. It is hosted on GitHub and the developers of JFreeChart tweak there. It has Maven as build engine, JDK 8 as a minimum requirement because of the JavaFX support (which is integrated into Java 8).

The work goes slowly however JFreeChart gets its new releases: 1.0.19 was released on the 31. 07. 2014. I’m looking forward for this new edition, it should bring some new flavour into the old Java-Chart world.

Conclusion

JFreeChart is an old, well known and free tool for creating charts. So if you are in need for charts in Java, do not hesitate and use this tool because it is easy and fast.

And if you need charts in JavaScript, try JSFreeChart.

About the author

GHajba

Senior developer, consultant, author, mentor, apprentice. I love to share my knowledge and insights what I achieve through my daily work which is not trivial -- at least not for me.

1 comment

Leave a comment: