Back to index

wims  3.65+svn20090927
PieChart.java
Go to the documentation of this file.
00001 /*   
00002  *  Configuration: config.html
00003  *  Status: Free
00004  *  Java Boutique:Upload Date October 11, 1999
00005  *  Author: Saket Kumar
00006  *  download from: http:*javaboutique.internet.com/PieChart/index.html
00007  *  PieChart.java  for Drawing Bar Chart.
00008  *  slightly altered: J.M. Evers 
00009  *  extra params: degree,radian,rounding etc etc                                                                                                           
00010  *  This program is free software; you can redistribute it and/or modify                                       
00011  *  it under the terms of the GNU General Public License as published by                                       
00012  *  the Free Software Foundation; either version 2 of the License, or                                          
00013  *  (at your option) any later version.                                                                        
00014  *                                                                                                             
00015  *  This program is distributed in the hope that it will be useful,                                            
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                                             
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                              
00018  *  GNU General Public License for more details.                                                               
00019  *                                                                                                             
00020  *  You should have received a copy of the GNU General Public License                                          
00021  *  along with this program; if not, write to the Free Software                                                
00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                                                  
00023  */  
00024 
00025 
00026 /*
00027 * adapted for WIMS by jm.evers
00028 * public JS functions: ReadApplet()
00029 * public JS functions: SetApplet()
00030 *
00031 *
00032 *
00033 */
00034 import java.awt.*;
00035 import java.io.*;
00036 import java.lang.*;
00037 import java.applet.Applet;
00038 import java.util.*;
00039 import java.io.PrintStream;
00040 
00041 public class PieChart extends java.applet.Applet {
00042 
00043     String    title;
00044     Font        font;
00045     FontMetrics fontMetrics;
00046     int              titleHeight = 15;
00047     int              columns;
00048     public int       round=1000;
00049     public float values[];
00050     Color       colors[];
00051     public String labels[];
00052     public float percent[];
00053     public float angle[];
00054     public float degree[];
00055     public float radian[];
00056     public float rawinput[];
00057     int              maxLabelWidth = 0;
00058     int         maxValueWidth = 0;
00059     int              max = 0;
00060     int         strWidth=0;
00061     public boolean showLabel=true;   // Whether to display the label or not
00062     public boolean showPercent=false; // Whether to display percentage or not
00063     public boolean showRadians=false; // Whether to display radians or not
00064     public boolean showDegrees=false; // Whether to display degrees or not
00065     public boolean showInput=true; // Whether to display raw input numbers
00066     String      unit; // Whether to display a unit for rawinput values?
00067 
00068     int lx=0,ly=0;          //For Writing Label
00069     int cx=0,cy=0;          //Center of Circle
00070 
00071   public synchronized void init() {
00072     String temp;font = new java.awt.Font("Sanserif", Font.BOLD, 12);
00073     fontMetrics = getFontMetrics(font);
00074     String bgColor=getParameter("bgcolor"); // Background color of Chart
00075     if (bgColor==null)
00076        setBackground(Color.white);
00077     else{
00078         if (bgColor.equals("red")) {
00079             setBackground(Color.red);
00080         } else if (bgColor.equals("green")) {
00081             setBackground(Color.green);
00082         } else if (bgColor.equals("blue")) {
00083             setBackground(Color.blue);
00084         } else if (bgColor.equals("pink")) {
00085             setBackground(Color.pink);
00086         } else if (bgColor.equals("orange")) {
00087             setBackground(Color.orange);
00088         } else if (bgColor.equals("magenta")) {
00089             setBackground(Color.magenta);
00090         } else if (bgColor.equals("cyan")) {
00091             setBackground(Color.cyan);
00092         } else if (bgColor.equals("white")) {
00093             setBackground(Color.white);
00094         } else if (bgColor.equals("yellow")) {
00095             setBackground(Color.yellow);
00096         } else if (bgColor.equals("gray")) {
00097             setBackground(Color.gray);
00098         } else if (bgColor.equals("darkGray")) {
00099             setBackground(Color.darkGray);
00100            } else {
00101         setBackground(Color.white);
00102            }
00103     }
00104     title = getParameter("title"); // Title of the Pie Chart
00105     if (title == null) {title = "WIMS Pie Chart";}
00106 
00107     unit = getParameter("unit"); // Title of the Pie Chart
00108     if (unit == null) {unit = "";}
00109     
00110     temp = getParameter("columns");
00111     if (temp == null) { columns = 5;} else {columns = Integer.parseInt(temp);}
00112 
00113     temp = getParameter("rounding");
00114     if (temp != null){round = Integer.parseInt(temp);if ( round < 1){ round=100;}}
00115 
00116     temp = getParameter("showdegrees");
00117     if (temp == null){showDegrees = false;}
00118     else
00119     {
00120        if (temp.equalsIgnoreCase("YES")){showDegrees = true;}
00121        if (temp.equalsIgnoreCase("NO")){showDegrees = false;}
00122     }
00123     temp = getParameter("showradians");
00124     if (temp == null){showRadians = false;}
00125     else
00126     {
00127        if (temp.equalsIgnoreCase("YES")){showRadians = true;}
00128        if (temp.equalsIgnoreCase("NO")){showRadians = false;}
00129     }
00130 
00131     temp = getParameter("showinput");
00132     if (temp == null){showInput = true;}
00133     else
00134     {
00135        if (temp.equalsIgnoreCase("YES")){showInput = true;}
00136        if (temp.equalsIgnoreCase("NO")){showInput = false;}
00137     }
00138 
00139     temp = getParameter("showlabel");
00140     if (temp == null) {showLabel = false;} 
00141     else 
00142     {
00143        if (temp.equalsIgnoreCase("YES")){showLabel = true;}
00144        if (temp.equalsIgnoreCase("NO")){showLabel = false;}
00145     }
00146 
00147     temp = getParameter("showpercent");
00148     if (temp == null) {showPercent = false;}
00149     else
00150     { 
00151         if (temp.equalsIgnoreCase("YES")){showPercent = true;}
00152         if (temp.equalsIgnoreCase("NO")){showPercent = false;}
00153     }
00154     
00155     radian = new float[columns];
00156     degree = new float[columns];
00157     rawinput = new float[columns];
00158     values = new float[columns];
00159     colors = new Color[columns];
00160     labels = new String[columns];
00161     percent= new float[columns];
00162     angle  = new float[columns];
00163     
00164     
00165     String tmp=null; 
00166     float totalValue=0;
00167     for (int i=0; i < columns; i++) {
00168        tmp=getParameter("Pvalue" + (i+1));
00169        float f = Float.valueOf(tmp.trim()).floatValue();
00170         values[i] =f;
00171        float t = Float.valueOf(tmp).floatValue();
00172        rawinput[i]=t;
00173         totalValue +=  values[i];
00174        // parse the label for this column
00175         temp = getParameter("P" + "label"+ (i+1) );
00176         labels[i] = (temp == null) ? "" : temp;
00177         maxLabelWidth = Math.max(fontMetrics.stringWidth((String)(labels[i])),maxLabelWidth);
00178        // parse the color attribute for this column
00179         temp = getParameter("P" + "color"+ (i+1) );
00180         if (temp != null) {
00181         if (temp.equals("red")) {
00182                   colors[i] = Color.red;
00183         } else if (temp.equals("green")) {
00184                   colors[i] = Color.green;
00185         } else if (temp.equals("blue")) {
00186                   colors[i] = Color.blue;
00187         } else if (temp.equals("pink")) {
00188                   colors[i] = Color.pink;
00189         } else if (temp.equals("orange")) {
00190                   colors[i] = Color.orange;
00191         } else if (temp.equals("magenta")) {
00192                   colors[i] = Color.magenta;
00193         } else if (temp.equals("cyan")) {
00194                   colors[i] = Color.cyan;
00195         } else if (temp.equals("white")) {
00196                   colors[i] = Color.white;
00197         } else if (temp.equals("yellow")) {
00198                   colors[i] = Color.yellow;
00199         } else if (temp.equals("gray")) {
00200                   colors[i] = Color.gray;
00201         } else if (temp.equals("darkGray")) {
00202                   colors[i] = Color.darkGray;
00203               } else {
00204                   colors[i] = Color.gray;
00205               }
00206            } else {
00207               colors[i] = Color.gray;
00208            }
00209     }
00210     float multiFactor = 100 / totalValue;
00211 
00212        for (int i=0; i < columns; i++) {
00213         percent[i]= (float) (Math.round(round*values[i] * multiFactor))/round;
00214         angle[i]  = (float) (Math.round(round*3.6*values[i] * multiFactor))/round;  // Calculation of Angle (360/100)
00215        degree[i] = (float) (Math.round(round*percent[i] * 3.6))/round ;
00216        radian[i] = (float) (Math.round(round*angle[i]/180))/round; // * pi rad !!!
00217     }
00218 
00219   }
00220 
00221 // paint method
00222 
00223   public synchronized void paint(Graphics g) {
00224     int  x=0;
00225     int  y=0;
00226     int width=0,height=0;
00227     int ax=0,ay=0;          //For Drawing Black line from center to Peripherial
00228     int px=0,py=0;          //For Writing Percentage
00229     int radius=0;
00230     width=height=Math.min((getSize().width - 100),(getSize().height - 100));
00231     x=y=50;
00232 
00233     if ( getSize().width > width ){
00234         x = (getSize().width - width ) /2 ; 
00235     }
00236 
00237     cx = x + width/2;
00238     cy = y + height/2;
00239     radius = width/2;
00240 
00241     // Draw the Title of the Chart on Top of the Applet
00242 
00243     strWidth=fontMetrics.stringWidth(title);
00244     Font fnt = new java.awt.Font("Sanserif", Font.BOLD, 16);
00245     g.setFont(fnt);
00246     g.setColor(Color.red);
00247     g.drawString(title,((getSize().width - strWidth )/2),15);
00248     g.setFont(font);
00249     int initAngle=90;
00250     int sweepAngle=0;
00251     int incSweepAngle=0;
00252     int incLabelAngle= (int) (angle[0]/2);
00253 
00254     for (int i=0; i < columns; i++) {
00255         sweepAngle = (int) Math.round(angle[i]);
00256         g.setColor((Color)colors[i]);
00257 
00258         if (i==(columns-1)){
00259             sweepAngle = 360 - incSweepAngle;
00260             g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
00261             g.setColor(Color.black);
00262             g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
00263 
00264             lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
00265             ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
00266            adjustLabel(i);
00267            int ly2=ly+15;
00268 
00269             if (showLabel)
00270            {
00271               g.drawString((String)labels[i] ,lx,ly);
00272               
00273               if (showDegrees){g.drawString(String.valueOf(degree[i]) + "\u00b0" ,lx,ly2);}
00274               
00275               else
00276               { 
00277                   if (showRadians){g.drawString( String.valueOf(radian[i]) +"\u03c0 rad" ,lx,ly2);}
00278                   else
00279                   {
00280                      if (showPercent){g.drawString( String.valueOf(percent[i]) +" %" ,lx,ly2);}
00281                      else
00282                      {
00283                          if (showInput){g.drawString( String.valueOf(rawinput[i])+"  "+unit,lx,ly2);}
00284                      }
00285                   }
00286               }
00287             }
00288            else
00289            {
00290               if (showDegrees){g.drawString(String.valueOf(degree[i]) + "\u00b0" ,lx,ly2);}
00291               
00292               else
00293               { 
00294                   if (showRadians){g.drawString( String.valueOf(radian[i]) +"\u03c0 rad" ,lx,ly2);}
00295                   else
00296                   {
00297                      if (showPercent){g.drawString( String.valueOf((Math.round(round*percent[i]))/round) +" %" ,lx,ly2);}
00298                      else
00299                      {
00300                          if (showInput){g.drawString( String.valueOf(rawinput[i])+"  "+ unit,lx,ly2);}
00301                      }
00302                   }
00303               }
00304            }
00305             break;
00306         }
00307 
00308         g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
00309         g.setColor(Color.black);
00310         g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
00311         incSweepAngle +=sweepAngle;
00312 
00313         ax = (int) (cx + ( radius * Math.cos((incSweepAngle * 3.14f/180) - 3.14f/2)));
00314         ay = (int) (cy + ( radius * Math.sin((incSweepAngle * 3.14f/180) - 3.14f/2)));
00315         g.drawLine(cx,cy,ax,ay);
00316 
00317         lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
00318         ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
00319         adjustLabel(i);
00320        int ly2=ly+15;               
00321        if (showLabel){
00322             g.drawString((String)labels[i],lx,ly);
00323            if ( showDegrees){g.drawString(String.valueOf(degree[i]) + "\u00b0" ,lx,ly2);}
00324            else
00325            {
00326               if ( showRadians){g.drawString(String.valueOf(radian[i])+"\u03c0 rad" ,lx,ly2);}
00327               else
00328               {
00329                   if (showPercent){g.drawString( String.valueOf(percent[i]) +" %" ,lx,ly2);}
00330                   else
00331                   {
00332                      if (showInput){g.drawString( String.valueOf(rawinput[i])+"  "+unit,lx,ly2);}
00333                   }
00334               }
00335            }
00336        }
00337        else
00338        {
00339            if ( showDegrees){g.drawString(String.valueOf(degree[i]) + "\u00b0" ,lx,ly2);}
00340            else
00341            {
00342               if ( showRadians){g.drawString(String.valueOf(radian[i])+"\u03c0 rad" ,lx,ly2);}
00343               else
00344               {
00345                   if (showPercent){g.drawString( String.valueOf((Math.round(round*percent[i]))/round) +" %" ,lx,ly2);}
00346                   else
00347                   {
00348                      if (showInput){g.drawString( String.valueOf(rawinput[i])+"  "+unit,lx,ly2);}
00349                   }
00350               }      
00351            }
00352        }
00353         incLabelAngle = incLabelAngle + (int) (angle[i]/2 + angle[i+1]/2);
00354         initAngle += (-sweepAngle);
00355     }
00356     g.setColor(Color.black);
00357     g.drawLine(cx,cy,cx,cy-radius);
00358   }
00359 
00360   private void adjustLabel(int i){
00361     if ( (lx > cx) && (ly < cy) ){
00362         lx +=5;
00363         ly -=5;
00364     }
00365 
00366     if ( (lx > cx) && (ly > cy) ){
00367         lx +=5;
00368         ly +=10;
00369     }
00370 
00371     if ( (lx < cx) && (ly > cy) ){
00372         strWidth=fontMetrics.stringWidth(labels[i]);
00373         lx -= strWidth+5;
00374         if (lx < 0)
00375             lx=0;
00376     }
00377 
00378     if ( (lx < cx) && (ly < cy) ){
00379         strWidth=fontMetrics.stringWidth(labels[i]);
00380         lx -= strWidth+5;
00381         if (lx < 0)
00382            lx=0;
00383     }
00384   }
00385   
00386   
00387 //     jm.evers 3/2008 modification to avoid intervening of WIMS in the update of the applet
00388 //     that was a real waste of recources !!!
00389 //     public static String replace(String source, String pattern, String replace){
00390 //     if (source!=null){
00391 //         final int len = pattern.length();                                                                                          
00392 //            StringBuffer sb = new StringBuffer();                                                                                      
00393 //            int found = -1;                                                                                                            
00394 //            int start = 0;                                                                                                             
00395 //            while( (found = source.indexOf(pattern, start) ) != -1) {                                                                  
00396 //                sb.append(source.substring(start, found));                                                                             
00397 //                sb.append(replace);                                                                                                    
00398 //                start = found + len;                                                                                                   
00399 //            }                                                                                                                          
00400 //            sb.append(source.substring(start));                                                                                            
00401 //            return sb.toString();                                                                                                          
00402 //            }                                                                                                                              
00403 //        else return "";                                                                                                                    
00404 //    }   
00405   
00406   public String ReadApplet(){
00407   // ATTENTION  MSIE-6 ? will not accept an array[]:it must be a string!!!
00408     int len=values.length;String reply="";
00409     if(len==0){
00410        reply="error empty answer";
00411     }
00412     else
00413     {
00414        float p;String l="";
00415        for(int i=0 ; i<len;i++){
00416            l=labels[i];
00417            p=rawinput[i];
00418            reply=reply+"segment "+i+" [ "+l+" ] = "+p+"\n";
00419        }
00420     }
00421     return reply;
00422   }
00423   // SetApplet() is called by javascript
00424   // it reads the inputfield on the page...strips..."sends" them to the applet
00425   // use a comma seperated list...   
00426   // we cannot handle "pi" or "+" or "-" or "*" or "/" etc
00427   // JAVASCRIPT SHOULD DEAL WITH THIS !!!!!!   
00428   public void SetApplet( String i){
00429     String tmp="";float input;
00430     StringTokenizer R = new StringTokenizer(i,",");
00431     int max=R.countTokens();
00432     float value[]=new float[max];float sum=0;
00433     for(int p=0;p<max;p++){
00434        tmp=R.nextToken();
00435        if(tmp.length()==0){tmp="0";}
00436        input=Float.valueOf(tmp).floatValue();
00437        System.out.println("input = " + input +"\n"); 
00438        rawinput[p]=input;
00439        value[p]=input;
00440        sum=sum+input;
00441     }
00442     for(int p=0;p<max;p++){
00443        input=value[p];
00444        // we show the correct circlediagram...maybe the sum of the degrees were != 360 ...we don't care
00445        angle[p] = 360*input/sum;
00446        percent[p] = 100*input/sum;
00447        radian[p] = (float) (input/sum);
00448        degree[p] = 360*input/sum;
00449     }
00450     repaint(); 
00451   }
00453 }
00454