A pie chart (or a circle chart) is a circular statistical
graphic which is divided into slices to illustrate numerical proportion. In a
pie chart, the arc length of each slice (and consequently its central angle and
area), is proportional to the quantity it represents.
- jfreeChart-1.0.19.jar
- jcommon-1.0.8.jar
The provided code consists of three Java classes that are
part of a pie chart visualization application. Here's a breakdown of each
class:
1. DemoData Class
package
com.kartik.pie; public class
DemoData { private String name; private String description; private double data; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String
description) { this.description = description; } public double getData() { return data; } } |
This is a simple data model that holds information for each
slice of the pie chart. It has three attributes: name, description, and data.
Ø name:
The name of the data item.
Ø description:
A description of the data item (currently not utilized in the code).
Ø data:
A double value representing the size of the pie slice.
Methods:
Ø Getters
and setters for each field (getName(), setName(), getDescription(), setDescription(),
getData(), and setData()).
2. CustomRingPlot Class
package
com.kartik.pie; import
java.awt.Color; import
java.awt.Font; import
java.awt.Graphics2D; import
java.awt.geom.Rectangle2D; import
org.jfree.chart.plot.PiePlotState; import
org.jfree.chart.plot.RingPlot; import
org.jfree.data.general.PieDataset; import
org.jfree.text.TextUtilities; import
org.jfree.ui.TextAnchor; public class
CustomRingPlot extends RingPlot { /** * */ private static final long serialVersionUID =
1L; private Font centerTextFont; private Color centerTextColor; private int total; public CustomRingPlot(PieDataset dataset,
Font centerTextFont, Color centerTextColor) { super(dataset); this.centerTextFont = centerTextFont; this.centerTextColor = centerTextColor; } public CustomRingPlot(PieDataset dataset,
Font centerTextFont, Color centerTextColor, int total) { super(dataset); this.centerTextFont = centerTextFont; this.centerTextColor = centerTextColor; this.total = total; } protected void drawItem(Graphics2D g2, int
section, Rectangle2D dataArea, PiePlotState state, int currentPass) { super.drawItem(g2, section, dataArea,
state, currentPass); g2.setFont(this.centerTextFont); g2.setPaint(Color.BLACK); TextUtilities.drawAlignedString("Total
Spendings", g2, (float) dataArea.getCenterX(), (float)
dataArea.getCenterY(), TextAnchor.BOTTOM_CENTER); g2.setPaint(this.centerTextColor); g2.setFont(new Font(Font.SANS_SERIF,
Font.HANGING_BASELINE, 14));
TextUtilities.drawAlignedString("$" + this.total, g2, (float) dataArea.getCenterX(), (float)
dataArea.getCenterY(), TextAnchor.TOP_CENTER); } /* * protected void drawItem(Graphics2D g2,
int section, Rectangle2D dataArea, * PiePlotState state, int currentPass) {
super.drawItem(g2, section, * dataArea, state, currentPass);
g2.setFont(this.centerTextFont); * g2.setPaint(Color.BLACK); *
TextUtilities.drawAlignedString("Total Spendings", g2, (float) * dataArea.getCenterX(), (float)
dataArea.getCenterY(), * TextAnchor.BOTTOM_CENTER);
g2.setPaint(this.centerTextColor); * g2.setFont(new Font(Font.SANS_SERIF,
Font.HANGING_BASELINE, 14)); *
TextUtilities.drawAlignedString("$", g2, (float)
dataArea.getCenterX(), * (float) dataArea.getCenterY(),
TextAnchor.TOP_CENTER); } */ } |
This class extends RingPlot from the JFreeChart library to
create a custom pie chart. It adds additional features such as custom text in
the center of the ring plot (like total spendings).
Key Features:
Ø Custom
Font and Color: The constructor accepts a dataset (PieDataset), a font for
the center text, a color for the text, and the total value for display.
Ø Custom
Rendering: The drawItem method is overridden to draw custom text at the
center of the ring plot, showing the label "Total Spendings" and the
total value.
Ø Item
Drawing: It draws text using the TextUtilities.drawAlignedString() method,
positioning it relative to the pie chart's center.
3. PieChartDemo2 Class
Code 3: package
com.kartik.pie; import
java.awt.BasicStroke; import
java.awt.Color; import
java.awt.Font; import
java.awt.GradientPaint; import
java.awt.Point; import
java.awt.geom.Rectangle2D; import
java.io.File; import
java.io.FileNotFoundException; import
java.io.FileOutputStream; import
java.io.IOException; import
java.text.DecimalFormat; import
java.util.ArrayList; import
java.util.List; import
javax.swing.JPanel; import
org.jfree.chart.ChartPanel; import
org.jfree.chart.ChartUtilities; import
org.jfree.chart.JFreeChart; import
org.jfree.chart.labels.PieSectionLabelGenerator; import
org.jfree.chart.labels.StandardPieSectionLabelGenerator; import
org.jfree.chart.plot.RingPlot; import
org.jfree.chart.title.LegendTitle; import
org.jfree.data.general.DefaultPieDataset; import
org.jfree.data.general.PieDataset; import
org.jfree.ui.ApplicationFrame; import
org.jfree.ui.RectangleEdge; import
org.jfree.ui.RectangleInsets; import
org.jfree.ui.RefineryUtilities; import
org.jfree.util.Rotation; /** * A simple demonstration application showing
how to create a pie chart using * data from a {@link DefaultPieDataset}. */ public class
PieChartDemo2 extends ApplicationFrame { private static int totalAmount=0; /** * */ private static final long serialVersionUID =
1L; private static int maxSize=0; /** * Default constructor. * * @param title the frame title. */ public PieChartDemo2(String title) { super(title); setContentPane(createDemoPanel()); } /** * * * @return A sample dataset. */ private static PieDataset createDataset()
{ DefaultPieDataset dataset = new
DefaultPieDataset(); /*dataset.setValue("one",
new Double(43.2)); dataset.setValue("two", new
Double(10.0)); dataset.setValue("three",
new Double(27.5)); dataset.setValue("four",
new Double(17.5)); dataset.setValue("five",
new Double(11.0)); dataset.setValue("six", new
Double(19.4)); dataset.setValue("seven",
new Double(43.2));*/ List<DemoData> data=setData(); totalAmount=sumOfValue(data); dataset=getdata(data); return dataset; } private static DefaultPieDataset
getdata(List<DemoData> data){ DefaultPieDataset dataSet=new
DefaultPieDataset(); for (DemoData demoData : data) { dataSet.setValue(demoData.getName(),
demoData.getData()); } return dataSet; } private static int
sumOfValue(List<DemoData> data){ int sum=0; for (DemoData demoData : data) { sum+=demoData.getData(); } return sum; } private static List<DemoData>
setData(){ List<DemoData> list=new
ArrayList<DemoData>(); DemoData one=new DemoData(); one.setName("ONE"); one.setData( new Double(43.2)); list.add(one); DemoData two=new DemoData(); two.setName("TWO"); two.setData(new Double(10.0)); list.add(two); DemoData three=new DemoData(); three.setName("THREE"); three.setData( new Double(27.5)); list.add(three); DemoData four=new DemoData(); four.setName("FOUR"); four.setData( new Double(17.5)); list.add(four); DemoData five=new DemoData(); five.setName("FIVE"); five.setData( new Double(11.0)); list.add(five); DemoData six=new DemoData(); six.setName("SIX"); six.setData( new Double(19.4)); list.add(six); DemoData seven=new DemoData(); seven.setName("SEVEN"); seven.setData( new Double(9.2)); list.add(seven); DemoData twenty=new DemoData(); twenty.setName("twentyOne"); twenty.setData( new Double(65.0)); list.add(twenty); return list; } private static JFreeChart
createChart(PieDataset dataset) { //RingPlot plot = new RingPlot(dataset); RingPlot plot = null; //PiePlot plot = (PiePlot)
chart.getPlot(); // plot = (RingPlot) chart.getPlot(); plot = new
CustomRingPlot((PieDataset)dataset, new Font(Font.SANS_SERIF, Font.BOLD, 13),
Color.BLUE,totalAmount); JFreeChart chart = new
JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, plot, true); chart.setBackgroundPaint(new
GradientPaint(new Point(100, 100), Color.WHITE, new Point(100, 100),
Color.WHITE)); plot.setNoDataMessage("No data
available"); plot.setDirection(Rotation.ANTICLOCKWISE); plot.setSectionDepth(0.50D); //this is
required for circle radios plot.setBaseSectionOutlineStroke(new
BasicStroke(0.5f)); plot.setCircular(true); plot.setSeparatorsVisible(false); //this is
required otherwise inside circle lot of straight line will come plot.setForegroundAlpha(1.0f); //this is
required to display deep color inside pie chart plot.setOutlinePaint(null); //this is
required for circle border if comment this line plot.setShadowPaint(null); plot.setOuterSeparatorExtension(50); plot.setInnerSeparatorExtension(50); plot = setSectionPaintColors(plot); LegendTitle legend = chart.getLegend();
legend.setPosition(RectangleEdge.RIGHT);//this is also required to
display legend label //legend.setFrame(BlockBorder.NONE); //this is required legend border if you
need otherwise comments this line Rectangle2D r2DD = new
Rectangle2D.Double(0, 0, 5, 15); plot.setLegendItemShape(r2DD); /*StandardPieSectionLabelGenerator
standardPieSectionLabelGenerator = new
StandardPieSectionLabelGenerator(("{0}:{2}"),NumberFormat.getNumberInstance(),
new DecimalFormat("0.0%"));
plot.setLabelGenerator(standardPieSectionLabelGenerator);*/ @SuppressWarnings("unchecked") List<String> key=dataset.getKeys(); for (String string : key) { if(string.length()>maxSize){ maxSize=string.length(); } } PieSectionLabelGenerator labelGenerator =
new StandardPieSectionLabelGenerator("{2}{1}{0}", new
DecimalFormat("0.00"), new DecimalFormat("0%") ){ private static final long
serialVersionUID = 1L; @SuppressWarnings("rawtypes") @Override protected Object[]
createItemArray(PieDataset dataset, Comparable key) { Object[] array =
super.createItemArray(dataset, key); Object[] array1 = new
Object[array.length]; int count=0; for (Object object : array) { StringBuffer sss=new
StringBuffer(); if(count == 1){ sss.append(object.toString());
sss=charSpace(sss,object.toString().length(),9); }else if(count == 2){
sss=charDigit(sss,object.toString().length(),5); sss.append(object.toString());
if(object.toString().length()==2){
sss=charSpaceDigit(sss,object.toString().length()+1,6); } else{
sss=charSpace(sss,object.toString().length(),6); } }else if(count == 0){ sss.append(object.toString().substring(0,
1).toUpperCase() +
object.toString().substring(1,object.toString().length()).toLowerCase()); }else{ sss.append(object.toString()); } array1[count] =
sss.toString(); count++; } return array1; } }; plot.setLabelGenerator(null); //plot.setLabelGenerator(labelGenerator);
//this is required if you need display inside circle your description
otherwise put null
plot.setLegendLabelGenerator(labelGenerator); //this is required to
display legend label chart.setPadding(new RectangleInsets(-6, 0,
0, 20)); //this is required for right side of legend space chart.setBorderVisible(true); chart.setBorderPaint(Color.WHITE); chart.setBorderStroke(new
BasicStroke(0.3f)); return chart; } /** * Creates a panel for the demo (used by
SuperDemo.java). * * @return A panel. */ public static JPanel createDemoPanel() { JFreeChart chart =
createChart(createDataset()); try { ChartUtilities.writeChartAsPNG(new
FileOutputStream(new File("D:\\sampleChart.png")) , chart, 400,
300); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return new ChartPanel(chart); } private static RingPlot
setSectionPaintColors(RingPlot plot) { List<?> listOfData =
plot.getDataset().getKeys(); String[] color = getColors(); if (color != null && color.length
> 0) { int count=0; for (Object string : listOfData) {
plot.setSectionPaint((String)string,Color.decode(color[count])); count++; } } return plot; } private static String[] getColors() { String[] colors ={"#41f46e",
"#f47f41",
"#5b2a44","#DF0096","#CF0096","#EE0096","#BBCCCC","#4286f4"}; return colors; } private static StringBuffer
charSpace(StringBuffer sb,int datalength,int MaxSize){ if(datalength==MaxSize){ sb.append(" "); return sb; }else{ sb.append(" "); return charSpace(sb,datalength+1,MaxSize); } } private static StringBuffer
charSpaceDigit(StringBuffer sb,int datalength,int MaxSize){ if(datalength==MaxSize){ sb.append(" "); return sb; }else{ sb.append(" "); return
charSpaceDigit(sb,datalength+1,MaxSize); } } private static StringBuffer
charDigit(StringBuffer sb,int datalength,int MaxSize){ if(datalength==2){ sb.append(" "); return sb; } return sb;
} /** * Starting point for the demonstration
application. * * @param args ignored. */ public static void main(String[] args) { PieChartDemo2 demo = new
PieChartDemo2("Pie Chart Demo 1"); demo.pack(); RefineryUtilities.centerFrameOnScreen(demo); demo.setVisible(true); } } |
This class sets up the pie chart using JFreeChart and
renders it using a dataset created with the DemoData class.
Key Features:
Ø createDataset():
This method creates a pie dataset by using data from DemoData instances. The
dataset is populated with values like "ONE", "TWO", etc.,
each with its respective data.
Ø createChart():
This method builds the actual pie chart using a RingPlot, and it applies the CustomRingPlot
for custom drawing.
ü
It configures the look of the pie chart,
including section depth, legend placement, and colors for different sections.
ü
A custom label generator is used to space out
the chart's sections and add specific formatting.
Ø setSectionPaintColors():
This method applies custom colors to each section of the pie chart. Colors are
fetched from a predefined array of hex color codes.
Ø Main
Method: The entry point for the application, where the pie chart is
displayed in a Swing frame using ChartPanel and exported to a PNG file.
Enhancements and Customizations:
- Custom
Labels and Center Text: The ring chart has text at its center
("Total Spendings"), with additional data displayed in the
legend. This enhances the user interface, providing quick summary
information.
- Color
Customization: The pie chart sections are colored with custom colors
for better visualization.
- Exporting
Chart to PNG: The chart can be exported as a PNG file by saving it to
disk using ChartUtilities.writeChartAsPNG().
If you have specific questions, feel free to let me know!
0 Comments