The Java Program: PieChart.java
1 // PieChart.java -- pie chart applet
2
3 // Original author : Saket Kumar, saket_kumar@hotmail.com
4
5 import java.applet.Applet;
6
7 import java.awt.Color;
8 import java.awt.Graphics;
9 import java.awt.Font;
10 import java.awt.FontMetrics;
11
12 public class PieChart extends Applet {
13
14 String title;
15 Font font;
16 FontMetrics fontMetrics;
17 int titleHeight = 15;
18 int columns;
19 int values[];
20 Color colors[];
21 String labels[];
22 float percent[];
23 float angle[];
24 int maxLabelWidth = 0;
25 int maxValueWidth = 0;
26 int max = 0;
27 int strWidth=0;
28 boolean showLabel=true; // Whether to display label or not
29 boolean showPercent=true; // Whether to display percent or not
30
31 int cx=0,cy=0; //Center of Circle
32 int lx=0,ly=0;
33
34 private Color parseColor (String nm, Color def) {
35 if (nm==null) return (def);
36 if (nm.equals("red")) {
37 return (Color.red);
38 } else if (nm.equals("green")) {
39 return (Color.green);
40 } else if (nm.equals("blue")) {
41 return (Color.decode ("#3399FF"));
42 } else if (nm.equals("pink")) {
43 return (Color.pink);
44 } else if (nm.equals("orange")) {
45 return (Color.orange);
46 } else if (nm.equals("magenta")) {
47 return (Color.magenta.brighter());
48 } else if (nm.equals("cyan")) {
49 return (Color.cyan);
50 } else if (nm.equals("white")) {
51 return (Color.white);
52 } else if (nm.equals("yellow")) {
53 return (Color.yellow);
54 } else if (nm.equals("gray")) {
55 return (Color.gray.brighter());
56 } else if (nm.equals("darkGray")) {
57 return (Color.gray);
58 } else {
59 return (def);
60 }
61 }
62
63
64 public synchronized void init() {
65 String temp;
66 font = new java.awt.Font("Sanserif", Font.BOLD, 12);
67 fontMetrics = getFontMetrics(font);
68 setBackground (parseColor (getParameter("bgcolor"), Color.white));
69 title = getParameter("title"); // Title of the Pie Chart
70
71 temp = getParameter("columns");
72 if (temp == null) {
73 columns = 5;
74 } else {
75 columns = Integer.parseInt(temp);
76 }
77
78 temp = getParameter("showlabel");
79 showLabel = (temp==null || temp.equalsIgnoreCase ("yes"));
80
81 temp = getParameter("showpercent");
82 showPercent = (temp==null || temp.equalsIgnoreCase ("yes"));
83
84 values = new int[columns];
85 colors = new Color[columns];
86 labels = new String[columns];
87 percent= new float[columns];
88 angle = new float[columns];
89
90 float totalValue=0;
91
92 for (int i=0; i < columns; i++) {
93
94 temp = getParameter("Pvalue" + (i+1));
95 if (temp != null) {
96 try {
97 values[i] = Integer.parseInt(temp);
98 } catch (NumberFormatException e) {
99 values[i] = 0;
100 }
101 }
102 totalValue += values[i];
103 if (values[i] > max) {
104 max = values[i];
105 }
106
107 // parse the label for this column
108 temp = getParameter("P" + "label"+ (i+1) );
109 labels[i] = (temp == null) ? "" : temp;
110 maxLabelWidth = Math.max(fontMetrics.stringWidth((String)(labels[i])),
111 maxLabelWidth);
112
113 // parse the color attribute for this column
114 colors[i] = parseColor (getParameter("P" + "color"+ (i+1)), Color.gray);
115 }
116
117 final float multiFactor = 100 / totalValue;
118 for (int i=0; i < columns; i++) {
119 percent[i]= values[i] * multiFactor;
120 angle[i] = (float) (percent[i] * 3.6) ; // Calculation of Angle (360/100)
121 }
122 }
123
124 public synchronized void paint(Graphics g) {
125 // Draw the title of the chart at the top
126 if (title!=null) {
127 final int strWidth=fontMetrics.stringWidth(title);
128 final Font fnt = new java.awt.Font("Sanserif", Font.BOLD, 16);
129 g.setFont (fnt);
130 g.setColor (Color.red);
131 g.drawString (title,((getSize().width - strWidth)/2),15);
132 g.setFont (font);
133 }
134
135 int width = Math.min((getSize().width - 100),(getSize().height - 100));
136 int height = width;
137 int x=50;
138 int y=x;
139
140 if (getSize().width > width){
141 x = (getSize().width - width ) /2 ;
142 }
143
144 // Center of pie (cx, cy are global variables)
145 cx = x + width/2;
146 cy = y + height/2;
147 final int radius = width/2;
148
149 int initAngle=90;
150 int sweepAngle=0;
151 int incSweepAngle=0;
152 int incLabelAngle= (int) (angle[0]/2);
153
154 for (int i=0; i < columns; i++) {
155 sweepAngle = (int) Math.round(angle[i]);
156 g.setColor((Color)colors[i]);
157
158 if (i==(columns-1)){
159 sweepAngle = 360 - incSweepAngle;
160 g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
161 g.setColor(Color.black);
162 g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
163
164 if (showLabel){
165 lx = (int) (cx + (radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
166 ly = (int) (cy + (radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
167 adjustLabel(i); // modify lx, ly
168 g.drawString((String)labels[i],lx,ly);
169 }
170 if (showPercent){
171 final int px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
172 final int py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
173 g.drawString(String.valueOf(Math.round(percent[i]))+"%",px,py);
174 }
175 break;
176 }
177
178 g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
179 g.setColor(Color.black);
180 g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
181 incSweepAngle +=sweepAngle;
182
183 // Black line from center to Peripherial
184 final int ax = (int) (cx + (radius * Math.cos((incSweepAngle * 3.14f/180) - 3.14f/2)));
185 final int ay = (int) (cy + (radius * Math.sin((incSweepAngle * 3.14f/180) - 3.14f/2)));
186 g.drawLine(cx,cy,ax,ay);
187
188 if (showLabel){
189 lx = (int) (cx + (radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
190 ly = (int) (cy + (radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
191 adjustLabel(i); // modify lx, ly
192 g.drawString((String)labels[i],lx,ly);
193 }
194 if (showPercent){
195 final int px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
196 final int py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
197 final int strWidth = fontMetrics.stringWidth(Math.round(percent[i])+"%");
198 g.drawString(String.valueOf(Math.round(percent[i]))+"%",(px - strWidth/2),py);
199 }
200
201 incLabelAngle = incLabelAngle + (int) (angle[i]/2 + angle[i+1]/2);
202 initAngle += (-sweepAngle);
203 }
204 g.setColor(Color.black);
205 g.drawLine(cx,cy,cx,cy-radius);
206 }
207
208 private void adjustLabel(int i){
209 if ( (lx > cx) && (ly < cy) ){
210 lx +=5; ly -=5;
211 }
212
213 if ( (lx > cx) && (ly > cy) ){
214 lx +=5; ly +=10;
215 }
216
217 if ( (lx < cx) && (ly > cy) ){
218 strWidth=fontMetrics.stringWidth(labels[i]);
219 lx -= strWidth+5;
220 if (lx < 0) lx=0;
221 }
222
223 if ( (lx < cx) && (ly < cy) ){
224 strWidth=fontMetrics.stringWidth(labels[i]);
225 lx -= strWidth+5;
226 if (lx < 0) lx=0;
227 }
228 }
229
230 }