For last few weeks I was working on Mavis – little tool to generate data for posts on this, and personal blogs. Core feature is generating charts describing my monthly and yearly activities, so I’ll write some posts about generating charts with jfreechart library.
All you need to create simplest possible bar chart is to create dataset instance, and then pass it to chart factory.
Example to create my “monthly activities” chart – for simplicity I just pass int values to dataset.
DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.setValue(1, "Finished", "Books"); dataset.setValue(2, "Finished", "Games"); dataset.setValue(1, "Finished", "Dev Posts"); dataset.setValue(3, "Finished", "Blog Posts"); dataset.setValue(2, "Finished", "Tasks"); JFreeChart chart = ChartFactory.createBarChart( "Month Plot", "Medium", "Finished", dataset, PlotOrientation.VERTICAL, false, // generate legend? true, // generate tooltips? false); // generate url?
And code above renders bar chart shown below. As you can see that most arguments for createBarChart method are self-explanatory, exception are three last Boolean arguments stating if legend, tooltips and url should be generated.
How to add another bar?
If you look at:
dataset.setValue(2, "Finished", "Tasks");
You’ll see setValue uses two strings, but only second is used as axis label (it’s column key) – it’s used to define categorical group. So what’s the point of first one? First one, named “row column”, specifies concrete bar (ie. property) connected with group. For example I could add another bar that shows how many games, books ect. I started to allow comparison with number of finished tiles in respective categories.
- Changing scale of range axis
To change scale of range axis we first need to get ahold of it’s instance. Barchart uses CategoryPlot object as the plot, and NumberAxis as range axis. As axis resides within plot we must first get CategoryPlot instance from chart:
CategoryPlot plot = chart.getCategoryPlot(); NumberAxis axis = (NumberAxis) plot.getRangeAxis();
Then set TickUnit as new NumberTickUnit(double value) with proper scale. For example first plot in this article is scaled with 0.5 value, and second with 1.0.
Simplest – and useful in most cases – way to change bar color is to set series color inside BarRenderer instance of chart.
To get ahold of renderer we use:
CategoryPlot plot = chart.getCategoryPlot(); BarRenderer render = (BarRenderer)plot.getRenderer();
And then we use render.setSeriesPaint(seriesID, java.awt.Paint) to set paint for values with the same “row key” (first string argument in setValue method). First added row is 0, second added row is 1, and so on. So from my previous examples:
java.awt.Paint paint = new Color(249,150,250,255); java.awt.Paint paint2 = new Color(0,150,250,255); render.setSeriesPaint(0, paint); // color for "Finished" values render.setSeriesPaint(1, paint2); // color for "Started" values
Note that it’ll only work for single-color bars. If you need gradient of some kind you’ll probably need to extend BarRenderer.