Simple Pie Chart in Java Swing

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();
				}
			}
		}
	}
}
Posted in Swing | Tagged , , , | 5 Comments

5 comments on “Simple Pie Chart in Java Swing

  1. Ruwan Rathnayake on said:

    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!

  2. zlloyd1 on said:

    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??

    • felixzacat on said:

      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?

  3. Philipp on said:

    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.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>