Dynamic representation of data in picture format is inevitable in this programming era. JFreeChart is one of the best open sources in Java World in providing APIs to display dynamic charts viz., Line Chart, Bar Chart, Pie Chart etc., A wide collection of APIs are available under LGPL license not only to generate different charts but also to customize the generated charts with our own look and feel. My projects are basically Portal Applications that involve displaying a Pie Chart for the backend data. As the creation of pie chart just takes two or three lines, I felt it is important to explore more ways to customize the chart generated and the result is this blog. Following section briefly describes various ways to customize pie chart generated using JFreeChart.
For generating and displaying JFreeCharts we need to include certain libraries which are available in JFreeChart web page.
Place these jar files in your WEB-INF/lib folder:
1.jfreechart-*.jar
2.jcommon-*.jar
Creation of pie chart won’t take you too many lines as it mainly needs the dataset for which you need to generate the chart apart from other details like Chart Title, Flag to say whether we need Legend or not etc., Following code shows a way to create a pie chart with available dataset and customize it in many available ways.
1: import java.awt.Color;
2: import java.text.AttributedString;
3: import java.util.List;
4: import org.jfree.chart.ChartFactory;
5: import org.jfree.chart.JFreeChart;
6: import org.jfree.chart.labels.PieSectionLabelGenerator;
7: import org.jfree.chart.plot.PiePlot;
8: import org.jfree.chart.plot.Plot;
9: import org.jfree.chart.title.TextTitle;
10: import org.jfree.data.general.DefaultPieDataset;
11: import org.jfree.data.general.PieDataset;
12: import org.jfree.ui.RectangleInsets;
13: import org.jfree.util.UnitType;
14: public class CustomizePieChart {
15: public static JFreeChart customizeSamplePieChart( ) {
16: final DefaultPieDataset data =
new DefaultPieDataset ( );
17: data.setValue("Software Engineer",50);
18: data.setValue("Programmer Analyst",20);
19: data.setValue("Technical Specialist",25);
20: data.setValue("Project Manager",10);
21: final boolean withLegend = true;
22: final JFreeChart chart =
ChartFactory.createPieChart("Employee Survey",
data, withLegend, true, true );
23: final PiePlot plot = (PiePlot)chart.getPlot( );
24: plot.setLabelGenerator(new CustomLabelGenerator( ));
25: plot.setLabelBackgroundPaint(Color.WHITE);
In order to customize a pie chart we need to create a plot of type PiePlot. PiePlot extends basic Plot and this plot instance is provided by a static method of JFreeChart. Once a plot is obtained we can do dozens of customizations.
If you have a view at dataset for which the chart will be generated, it is just a collection of (name, value) pairs. Pie chart is generated for value parameter (which must be parsable into double) whereas labels and legends are displayed based on the name given. In order to customize label, we need to create an inner class within the class in which the pie chart is generated and pass an instance of that inner class (where we set some rules of how to display the label) to a method in PiePlot which displays the label the way we defined it in the inner class. See Line no. 24 for the PiePlot’s set method and Line no. 39 for static inner class that defines how label should be displayed.
We can also customize other properties of label using PiePlot. This includes,
1.Setting Label Background
2.Setting Label outline
3.Setting Label shadow
4.Disabling label links etc.,
A pie chart’s legend is optional and if we wish to have, we can also customize it the way we did for label. See Line no. 28 for PiePlot’s set method and line no. 46 for static inner class that defines how legend should be displayed. We can also set the Legend items’ shape to pre-defined shapes and the default one is circle.
23: plot.setLabelOutlinePaint(Color.WHITE);
24: plot.setLabelShadowPaint(Color.WHITE);
25: plot.setLegendItemShape(Plot.DEFAULT_LEGEND_ITEM_BOX);
26: plot.setBaseSectionOutlinePaint(Color.LIGHT_GRAY);
27: plot.setShadowPaint(Color.WHITE);
28: plot.setLegendLabelGenerator(new CustomLegendGenerator());
29: TextTitle title =
new TextTitle("Employee Survey");
30: title.setBackgroundPaint(new Color(0.294f, 0.0f, 0.513f));
31: title.setPaint(new
Color(1.0f, 0.549f, 0.0f));
32: title.setExpandToFitSpace(true);
33: chart.setTitle(title);
34: plot.setInsets(new
RectangleInsets(UnitType.ABSOLUTE, 0.0, 0.0,1.0, 1.0));
35: Color[] colors = {Color.blue, Color.yellow,
Color.green, Color.GRAY};
36: PieRenderer renderer = new PieRenderer(colors);
37: renderer.setColor(plot, data);
38: return chart;
}
A pie chart’s title is defined when a new JFreeChart instance is created. We can also customize the same by creating an instance of type TextTitle and setting properties on created instance. See line no. 29 to 33 for details.
When you create a default pie chart, all pie sections will be painted in system selected colors which are random. If you wish to define which pie section should be painted on which color, well, you can do that by creating another inner class that defines the exact selection of colors. See line no. 36 for 54 for more details.
Apart from aforementioned customizations, following are the miscellaneous ones that I hope will be helpful for you.
- Setting insets
Insets for a pie chart can be customized and we can even set ZERO inset.
See line no. 34 for ZERO insets.
- Setting paints for BaseSection and Shadow.
39: static class CustomLabelGenerator implements PieSectionLabelGenerator {
40: public String generateSectionLabel(final PieDataset dataset,
final Comparable key) {
41: String temp = null;
42: if (dataset != null) {
43: temp = dataset.getValue(key).toString();
44: if(key.toString().equalsIgnoreCase("Software
Engineer")) {
temp = temp + "(Trainees Not Included)";
}
}
45: return temp;
}
}
46: static class CustomLegendGenerator
implements PieSectionLabelGenerator {
47: public String
generateSectionLabel(final PieDataset dataset,
final Comparable key) {
48: String temp = null;
49: if (dataset != null) {
50: temp = key.toString();
/* Modifying a particular legend item based on the Key name */
51: if(key.toString().equalsIgnoreCase("Software
Engineer")) {
52: temp = temp + "(Trainees
Not Included)";
}
}
53: return temp;
}
}
54: static class PieRenderer
{
55: private Color[ ]
color;
56: public PieRenderer(Color[ ] color)
{
57: this.color = color;
}
58: public void setColor(PiePlot plot,
DefaultPieDataset dataset)
{
59: List keys = dataset.getKeys();
60: int aInt;
61: for (int i =
0; i <
keys.size(); i++)
{
62: aInt = i % this.color.length;
63: plot.setSectionPaint(
keys.get(i).toString(),this.color[aInt]);
}
}
}
}
Following are the sample outputs that will show differences between a generic and customized chart. Since the project I involved is basically a web application I used a servlet to display all these charts.
Fig 1: Generic Chart – Not Customized Fig 2: Chart with customized label Fig 3: Chart with customized legend Fig 4: Chart with customized title Fig 5: Chart with ZERO insets Fig 6: Chart with custom pie section colors
Note: Copy the war file into the webapps folder of the Tomcat. Start the Tomcat server & view the charts (JSP) through a browser. [In the address bar give: http://localhost:/CustomizePieChart]