Monday, February 15, 2016

Drawing Bar Chart Based On User Input

This program produces a bar chart on the screen based on data input from user. Two text areas hold the data for x and y axis. When a button is pressed, the chart will be displayed on a jpanel.



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class DrawStats extends JFrame{
    JTextArea tarea1=null;
    JTextArea tarea2=null;
    int[] dataX=null;
    double[] dataY=null;
    JTextField tftitle=null;
    JButton bDraw=null;
    JPanel panelGraph=null;
    
    public static void main(String[] args){
        DrawStats ap=new DrawStats();
    }
    public DrawStats(){
        super("Drawing Graph");
        setSize(850,750);
        setResizable(false);
        
        GridBagLayout gb=new GridBagLayout();
        setLayout(gb);
        GridBagConstraints gbc=new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;

        tftitle=new JTextField(20);
        add(tftitle,gbc);
        gbc.insets=new Insets(10,0,0,0);
        gbc.gridy++;
        JPanel panelTA=new JPanel();
        panelTA.setLayout(new FlowLayout());
        tarea1=new JTextArea();
        JScrollPane scrollPane1=new JScrollPane(tarea1);
        scrollPane1.setPreferredSize(new Dimension(100,100));
        panelTA.add(scrollPane1);
        tarea2=new JTextArea();
        JScrollPane scrollPane2=new JScrollPane(tarea2);
        scrollPane2.setPreferredSize(new Dimension(100,100));
        panelTA.add(scrollPane2);
        add(panelTA,gbc);
        gbc.gridy++;
        bDraw=new JButton("Draw");
        bDraw.addActionListener(new ButtonHandler());
        add(bDraw,gbc);
        gbc.gridy++;
        panelGraph=new JPanel();
        panelGraph.setPreferredSize(new Dimension(700,450));
        panelGraph.setBackground(Color.white);
        add(panelGraph,gbc);
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        show();
    }
    class ButtonHandler implements ActionListener{
        public void actionPerformed(ActionEvent e){
            repaint();
        }
    }
    public void paint( Graphics g ) {
            super.paint(g);
            
            int counter1=tarea1.getLineCount();
            int counter2=tarea2.getLineCount();
            
            if(counter1!=counter2){
                System.exit(0);
            }
            else{
                dataX=new int[counter1];
                dataY=new double[counter2];
            }
            
            StringTokenizer stoken=new StringTokenizer(tarea1.getText(),"\r\n");
            counter1=0;
            while(stoken.hasMoreTokens()){
                String st=stoken.nextToken();
                for(int i=0;i<st.length();i++){
                    if(st.charAt(i)<'0'||st.charAt(i)>'9'){
                        System.exit(0);
                    }
                }
                dataX[counter1]=Integer.parseInt(st);
                counter1++;
            }
            
            StringTokenizer stoken2=new StringTokenizer(tarea2.getText(),"\r\n");
            counter2=0;
            while(stoken2.hasMoreTokens()){
                String st=stoken2.nextToken();
                for(int i=0;i<st.length();i++){
                    if(st.charAt(i)<'0'||st.charAt(i)>'9'){
                        if(st.charAt(i)!='.'){
                            System.exit(0);
                        }
                    }
                }
                dataY[counter2]= Double.parseDouble(st);
                counter2++;
            }
            
            Point p=panelGraph.getLocationOnScreen();
            
            int posX=p.x+50;
            double posY=p.y;

            int panelWidth=panelGraph.getWidth();
            int dataWidth=(panelWidth-100)/dataX.length;
            
            double dataMax=dataY[0];
            for(int i=1;i<(dataY.length-1);i++){
                if(dataMax<dataY[i+1])
                    dataMax=dataY[i+1];
            }
            double panelHeight=panelGraph.getHeight();                        
            double dataHeight=(panelHeight-100)/dataMax;
           
            Font f=new Font("Arial",Font.BOLD,11);
            FontMetrics fm=panelGraph.getFontMetrics(f);
            g.setFont(f);
            g.drawString(tftitle.getText(),(panelWidth/2)-(fm.stringWidth(tftitle.getText())/2)+p.x,p.y+12);
            
            for(int i=0;i<dataX.length;i++){
                g.drawRect(posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)),dataWidth,(int)(dataY[i]*dataHeight));
                g.drawString(dataX[i]+"",posX,(int)(panelHeight+posY+20));
                if(dataY[i]%1==0){
                    g.drawString((int)dataY[i]+"",((dataWidth/2)-(fm.stringWidth(dataY[i]+"")/2))+posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)-10));
                }
                else{
                    g.drawString(dataY[i]+"",((dataWidth/2)-(fm.stringWidth(dataY[i]+"")/2))+posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)-10));
                }
                
                posX=posX+dataWidth;
            }
                    
            g.dispose();
    }
}


int[] dataX;
double[] dataY;

These two arrays act as a temporary storage for x-axis and y-axis data. The array "dataY" is of double data type as the data items for y-axis may consist of floating-point numbers. The example below shows the win lose ratio of Chicago Bulls for the last ten years.


int counter1=tarea1.getLineCount();
int counter2=tarea2.getLineCount();

The method getLineCount() counts the number of data records. The results are then compared to ensure the data series on the two text areas match or in other words, each data item has a pair. The variables "counter1" and "counter2" also determine the length of the two arrays.

int panelWidth=panelGraph.getWidth();
int dataWidth=(panelWidth-100)/dataX.length;

Here, the data interval for x-axis is determined.

double dataMax=dataY[0];
for(int i=1;i<(dataY.length-1);i++){
 if(dataMax<dataY[i+1])
        dataMax=dataY[i+1];
}
double panelHeight=panelGraph.getHeight();                        
double dataHeight=(panelHeight-100)/dataMax;

These lines of code determine the data interval for y-axis.

Font f=new Font("Arial",Font.BOLD,11);
FontMetrics fm=panelGraph.getFontMetrics(f);
g.setFont(f);
g.drawString(tftitle.getText(),(panelWidth/2)-(fm.stringWidth(tftitle.getText())/2)+p.x,p.y+12);

To draw the title of the graph in the center position of the drawing area, class Font and FontMetrics are utilized.

for(int i=0;i<dataX.length;i++){
 g.drawRect(posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)),dataWidth,(int)(dataY[i]*dataHeight));
        g.drawString(dataX[i]+"",posX,(int)(panelHeight+posY+20));
        .
        .
        .
        posX=posX+dataWidth;
}

The bar chart is produced using drawRect() method. The second parameter calculates the starting point (y coordinate) of the bar. The last parameter determines the height of the bar.

for(int i=0;i<dataX.length;i++){
 .
 .
 .
        if(dataY[i]%1==0){
         g.drawString((int)dataY[i]+"",((dataWidth/2)-(fm.stringWidth(dataY[i]+"")/2))+posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)-10));
 }
        else{
         g.drawString(dataY[i]+"",((dataWidth/2)-(fm.stringWidth(dataY[i]+"")/2))+posX,(int)((panelHeight+posY)-(dataY[i]*dataHeight)-10));
 }
 posX=posX+dataWidth;
}

This portion of program puts the value of each data item on the corresponding part of the graph. The if-else statement is needed to determine whether the data set for y-axis is integer or double. If it is integer, the decimal will not be displayed.

Source of data:
http://www.statista.com/statistics/269029/number-of-goals-scored-at-fifa-world-cups-since-1930/ http://www.landofbasketball.com/teams/records_chicago_bulls.htm

No comments:

Post a Comment