I know there are a lot of Swing charting software libraries out there (JFreechart comes to mind). But a lot of them come across as too bloated and require a lot of time to become familiar with.
My own Piechart is as simple as it gets; collect your segments as percentages in a list, along with the corresponding colours :
ArrayList<Double> values = new ArrayList<Double>(); values.add(new Double(10)); values.add(new Double(20)); values.add(new Double(30)); values.add(new Double(15)); values.add(new Double(15)); ArrayList<Color> colors = new ArrayList<Color>(); colors.add(Color.gray); colors.add(Color.green); colors.add(Color.blue); colors.add(Color.pink); colors.add(Color.yellow); PieChart pieChart = new PieChart(values, colors); myPanel.add(pieChart);
You can get something that looks like this :
Its really basic, but its also very minimalist and does away with a lot of noise that other charting programs offer.
Simple Indicator.
I thought I would also add a couple more modes to my pie chart. The second mode is what I would call a simple indicator mode. This displays just one percentage value as a slice of the pie.
PIeChart pieChart = new PieChart(70);
I find these indicators look very effective as small graphics next to numerical text, as the following example tries to show:
I’m not 100% sure this is the best way to visually enhance percentages, but I think it looks good in certain situations.
Graded Indicator.
Another visual approach to showing a percentage growing into a critical phase, is to somehow grade the colors as the percentage level gets higher. I decided to create a third mode which allows the user to set a number of gradings with corresponding colors. As the percentage gets close to 100% the pie sections get smaller and the colors get more prominent.
Here is an example :
To use the third mode simply add an array of percentages with an array of colours, plus an overall percentage, to a third constructor :
ArrayList<Double> values = new ArrayList<Double>(); values.add(new Double(60)); values.add(new Double(20)); values.add(new Double(10)); values.add(new Double(7)); values.add(new Double(3)); ArrayList<Color> colors = new ArrayList<Color>(); colors.add(new Color(255,255,255)); colors.add(new Color(255,183,183)); colors.add(new Color(255,6,6)); colors.add(new Color(244,255,43)); colors.add(Color.BLUE); PieChart pc = new PieChart(grade, values, colors);
Here is the source code to the pie chart with all three modes :
package com.gg.piechart;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.JPanel;
public class PieChart extends JPanel {
enum Type {
STANDARD, SIMPLE_INDICATOR, GRADED_INDICATOR
}
private Type type = null; //the type of pie chart
private ArrayList values;
private ArrayList colors;
private ArrayList gradingValues;
private ArrayList gradingColors;
double percent = 0; //percent is used for simple indicator and graded indicator
public PieChart(int percent) {
type = Type.SIMPLE_INDICATOR;
this.percent = percent;
}
public PieChart(ArrayList values, ArrayList colors) {
type = Type.STANDARD;
this.values = values;
this.colors = colors;
}
public PieChart(int percent, ArrayList gradingValues, ArrayList gradingColors) {
type = Type.GRADED_INDICATOR;
this.gradingValues = gradingValues;
this.gradingColors = gradingColors;
this.percent = percent;
}
@Override
protected void paintComponent(Graphics g) {
int width = getSize().width;
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias!
RenderingHints.VALUE_ANTIALIAS_ON);
if (type == Type.SIMPLE_INDICATOR) {
//colours used for simple indicator
Color backgroundColor = Color.WHITE;
Color mainColor = Color.BLUE;
g2d.setColor(backgroundColor);
g2d.fillOval(0, 0, width, width);
g2d.setColor(mainColor);
Double angle = (percent / 100) * 360;
g2d.fillArc(0, 0, width, width, -270, -angle.intValue());
} else if (type == Type.STANDARD) {
int lastPoint = -270;
for (int i = 0; i < values.size(); i++) {
g2d.setColor(colors.get(i));
Double val = values.get(i);
Double angle = (val / 100) * 360;
g2d.fillArc(0, 0, width, width, lastPoint, -angle.intValue());
System.out.println("fill arc " + lastPoint + " "
+ -angle.intValue());
lastPoint = lastPoint + -angle.intValue();
}
} else if (type == Type.GRADED_INDICATOR) {
int lastPoint = -270;
double gradingAccum = 0;
for (int i = 0; i < gradingValues.size(); i++) { g2d.setColor(gradingColors.get(i)); Double val = gradingValues.get(i); gradingAccum = gradingAccum + val; Double angle = null; /** * If the sum of the gradings is greater than the percent, then we want to recalculate * the last wedge, and break out of drawing. */ if (gradingAccum > percent) {
System.out.println("gradingAccum > percent");
//get the previous accumulated segments. Segments minus last one
double gradingAccumMinusOneSegment = gradingAccum - val;
//make an adjusted calculation of the last wedge
angle = ((percent - gradingAccumMinusOneSegment) / 100) * 360;
g2d.fillArc(0, 0, width, width, lastPoint, -angle.intValue());
lastPoint = lastPoint + -angle.intValue();
break;
}else {
System.out.println("normal");
angle = (val / 100) * 360;
g2d.fillArc(0, 0, width, width, lastPoint, -angle.intValue());
System.out.println("fill arc " + lastPoint + " "
+ -angle.intValue());
lastPoint = lastPoint + -angle.intValue();
}
}
}
}
}






Wow! Gotta say after searching and studying many Charting libraries, this is the easiest and the simplest one I’ve found. It’s so simple as even a newbie can use it really easily. And you have explained how to use it in a really clear way. Keep up the great work felixzacat!
thanks dude!
I cannot get this code to work, because I keep getting errors about the lines,
g2d.setColor(colors.get(i));
Double val = values.get(i);
saying, incompatible types,
required: color
found: object
Am I missing something here??
you should be passing in an array of Double values, and an array of Color objects. Maybe you are passing in the wrong object type?
Nice job dude,
saves me a lot of time.
Just as a hint: You can use generics for the different ArrayList, like ArrayList.
I get compile errors with the code above if i dont use generics or cast to the right Type.
But really, thx a lot.