Results 1 to 3 of 3
  1. #1
    adlb1300 is offline Member
    Join Date
    Jul 2007
    Posts
    46
    Rep Power
    0

    Default Help with graphing problem

    I'm working on a project that reads data from a file for the high, low and month close of a stock by month. Once the data is read I have to graph the the high and low marks for each month. The high and low mark for each month needs to be connected by a vertical line. I was able to code it so that the user can choose the file to pull the data from and I also have it so the data is read from the file. I also have a lot of the graph completed. The issue I'm having is graphing the data and also labeling the data ranges on the x and y axis based on the info pulled from the file. Below is the code I already have and any help would be greatly appreciated. I also have included a sample of what the data file looks like and also what the graph needs to look like.

    Sample file:
    MAY 7 18 20
    JUN 10 19 26
    JUL 12 14 22
    AUG 14 24 38
    SEP 34 45 52
    OCT 42 51 56
    NOV 45 49 53
    DEC 40 45 55

    Sample of graph:

    Contained in attached zip file
    Java Code:
    import java.io.File;
    import java.util.Vector;
    import javax.swing.JFrame;
    
    public class StockGraph {
    
        
        public static void main(String[] args) {
         
            String input;
            
            JFrame f = new JFrame();
            ChooseFile nf = new ChooseFile();
            nf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            input = nf.getFile();
            StockMonth sm = new StockMonth(input);
            Graph g = new Graph();
            f.add(g);
            f.setSize(700,700);
            f.setVisible(true);
      
        }
     }
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.*;
    import java.io.IOException;
    import java.util.Vector;
    import javax.swing.*;
    
    public class ChooseFile extends JFrame {
        
        private JTextArea outputArea;
        private JScrollPane scrollPane;
        private File fileIn;
        private String fileName;
        private String input;
        private Vector<String> month = new Vector<String>();
        private Vector<String> lowPrice = new Vector<String>();
        private Vector<String> monthClose = new Vector<String>();
        private Vector<String> highPrice = new Vector<String>();
        
        public ChooseFile() {
            
            super("Stock Graph");
            outputArea = new JTextArea();
            scrollPane = new JScrollPane(outputArea);
            add(scrollPane, BorderLayout.CENTER);
            setSize(400, 400);
            setVisible(true);
            
        }
        
        public String getFile(){
            
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            
            int result = fileChooser.showOpenDialog(this);
            
            if(result == JFileChooser.CANCEL_OPTION);
            //   System.exit(1);
            
            File fileName = fileChooser.getSelectedFile();
            
            if((fileName == null) || (fileName.getName().equals(""))){
                
                JOptionPane.showMessageDialog(this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE);
                //   System.exit(1);
            } else{
                input = fileName.getPath();
            }
            return input;
        } // end getFile() method
    } // end ChooseFile class
    Java Code:
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.util.Vector;
    
    public class StockMonth {
        
        private File fileIn;
        private String fileName;
        private String input;
        private Vector<String> month = new Vector<String>();
        private Vector<String> lowPrice = new Vector<String>();
        private Vector<String> monthClose = new Vector<String>();
        private Vector<String> highPrice = new Vector<String>();
        
        public StockMonth(String input) {
            
            procFile(input);
            
        }
        
        protected void procFile(String input) {
            
            boolean more = true; // file contains more data
            
            try{
                
                System.out.println(input);
                fileIn = new File(input);
                FileReader in = new FileReader(fileIn);
                BufferedReader br = new BufferedReader(in);
                
                String dataLine;
                
                while(more){
                    // get the next line of data
                    dataLine = br.readLine();
                    
                    if(dataLine == null){
                        // switches more to false once all data is read from file
                        // allowing program to break out of loop
                        more = false;
                    } else{
                        
                        setMonth(dataLine);
                        setLowPrice(dataLine);
                        setMonthClose(dataLine);
                        setHighPrice(dataLine);                   
                    }
                }
            } catch(Exception fe) {
                // System.out.println(fe.toString());
            } // end catchthrow new UnsupportedOperationException("Not yet implemented");
        }
    
        private void setMonth(String dataLine) {
            
            month.add(dataLine.substring(0,3).trim());
            System.out.println(month);
        }
        
        private void setLowPrice(String dataLine){
            
            lowPrice.add(dataLine.substring(4,8).trim());
            System.out.println(lowPrice);
        }
        
        private void setMonthClose(String dataLine){
            
            monthClose.add(dataLine.substring(8,12).trim());
            System.out.println(monthClose);
        }
    
        private void setHighPrice(String dataLine){
            
            highPrice.add(dataLine.substring(12).trim());
            System.out.println(highPrice);
        }
        
        public Vector getMonth(){
                
                return month;
        }
        
        public Vector getLowPrice(){
    
            return lowPrice;
        }
        
        public Vector getMonthClose(){
            
            return monthClose;
        }
        
        public Vector getHighPrice(){
            
            return highPrice;
    }
    }
    Java Code:
    import java.awt.*;
    import java.awt.geom.*;
    import java.util.*;
    import javax.swing.*;
    
    public class Graph extends JPanel {
        final int PAD = 40;  // sets size of pad between the graph and edge of frame
    
        
        Graph() {
            
    
        }
        
       // Method creates all aspects of the graph and plots data
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            int w = getWidth();
            int h = getHeight();
           
            // draws axes 
            g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
            g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
            
            // gridlines of graph
            int gridY = 48;
            for(int lineCounter = 0; lineCounter < 11; lineCounter++){
                g2.draw(new Line2D.Double(PAD, PAD + gridY, h-PAD, PAD + gridY));
                gridY = gridY + 48;
            }
            
            // adds main title to graph
            g2.drawString("Monthly High-Low Stock Graph", 290, 20);
            
            // adds title of x-axis to graph
            g2.drawString("Month", 300, 660);
            
            // adds title of y-axis to graph
            String yTitle[] = {"S", "t", "o", "c", "k", " ", "P", "r", "i", "c", "e", "s"};
            int xAxisTitle = 5;
            int yAxisTitle = 175;
            for(int titleCounter = 0; titleCounter < yTitle.length; titleCounter++){
                g2.drawString(yTitle[titleCounter], xAxisTitle, yAxisTitle);
                yAxisTitle = yAxisTitle + 25;
            }
            
            // adds data ranges to y-axis
            String yLabel[] = {};
            int xAxis = 20;
            int yAxis = 100;
            for(int yCounter = 0; yCounter < yLabel.length; yCounter++){
                g2.drawString(yLabel[yCounter], xAxis, yAxis);
                yAxis = yAxis + 31;
            }
            
            // adds frequency scale to x-axis
            String xLabel[] = {};
            int xCoordinate = 123;
            int yCoordinate = 405;
            for(int xCounter = 0; xCounter < xLabel.length; xCounter++){
                g2.drawString(xLabel[xCounter], xCoordinate, yCoordinate);
                xCoordinate = xCoordinate + 48;
            }
            
        }
    }
    Attached Files Attached Files
    Last edited by adlb1300; 11-26-2007 at 01:29 AM.

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Labels work okay. Note resizing behavior of new labels and data.
    Changes:
    In StockGraph pass the reference to StockMonth into Graph:
    Java Code:
            Graph g = new Graph(sm);
    In StockMonth add the generic type declarations to the four get methods
    Java Code:
        public Vector<String> getMonth(){
    to avoid compiler "Xlint:unchecked" warnings.
    the Graph class, left rough:
    Java Code:
    import java.awt.*;
    import java.awt.font.*;
    import java.awt.geom.*;
    import java.util.*;
    import javax.swing.*;
    
    public class Graph extends JPanel {
        final int PAD = 40;  // sets size of pad between the graph and edge of frame
        final int SPAD = 2;
        final int CLOSE = 15;
        StockMonth stockMonth;
        int[] maxValues;
        int[] closeVals;
        int[] minValues;
        
        Graph(StockMonth sm) {
            stockMonth = sm;
            // The numeric information could be better
            // stored as Integer in the vectors of StockMonth.
            // Make up arrays to store the data locally.
            initArrays();
        }
        
       // Method creates all aspects of the graph and plots data
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            int w = getWidth();
            int h = getHeight();
           
            // draws axes 
            g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
            g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
            
            // gridlines of graph
            int steps = 11;
            float gridY = //48;
                        (float)(h - 2*PAD)/steps;
            //System.out.printf("gridY = %.1f%n", gridY);
            for(int lineCounter = 0; lineCounter < steps; lineCounter++){
                float y = lineCounter*gridY;
                g2.draw(new Line2D.Double(//PAD, PAD + y, h-PAD, PAD + y));
                                          PAD, PAD + y, w-PAD, PAD + y));
    //            gridY = gridY + 48;
            }
    
            // adds main title to graph
            g2.drawString("Monthly High-Low Stock Graph", 290, 20);
            
            // adds title of x-axis to graph
            g2.drawString("Month", 300, 660);
            
            // adds title of y-axis to graph
            String[] yTitle = {"S", "t", "o", "c", "k", " ", "P", "r", "i", "c", "e", "s"};
            int xAxisTitle = 5;
            int yAxisTitle = 175;
            for(int titleCounter = 0; titleCounter < yTitle.length; titleCounter++){
                g2.drawString(yTitle[titleCounter], xAxisTitle, yAxisTitle);
                yAxisTitle = yAxisTitle + 25;
            }
    
            Font font = g2.getFont().deriveFont(16f);
            g2.setFont(font);
            FontRenderContext frc = g2.getFontRenderContext();
            LineMetrics lm = font.getLineMetrics("0", frc);
            float height = lm.getAscent() + lm.getDescent();
    
            // adds data ranges to y-axis
            // You could use this to determine the max value of ordinate.
            int max = getMaxValue();
            
    //        String[] yLabel = {};
    //        int xAxis = 20 - SPAD;
    //        int yAxis = 100;
            int stepVal = 6;
            for(int yCounter = 0; yCounter < steps; yCounter++) {
                String s = String.valueOf(stepVal*(steps - yCounter));
                float width = (float)font.getStringBounds(s, frc).getWidth();
                float x = PAD - SPAD - width;
                float y = PAD + yCounter*gridY + height/2 - lm.getDescent();
                g2.drawString(s, x, y);
    //            yAxis = yAxis + 31;
            }
    
            // adds frequency scale to x-axis
            Vector<String> v = stockMonth.getMonth();
            int size = v.size();
            String[] months = (String[])v.toArray(new String[size]);
    //        int xCoordinate = 123;
    //        int yCoordinate = 405;
            float xInc = (float)(w - 2*PAD)/size;
            float y = h - PAD + SPAD + lm.getAscent();
            for(int j = 0; j < months.length; j++) {
                String s = months[j];
                float width = (float)font.getStringBounds(s, frc).getWidth();
                float x = PAD + j*xInc + xInc/2 - width/2;
                g2.drawString(months[j], x, y);
    //            xCoordinate = xCoordinate + 48;
            }
    
            // Plot data.
            // Each step of stepVal in model units = gridY in view units
            float scale = (float)(h - 2*PAD)/(steps);
            for(int j = 0; j < size; j++) {
                float x = PAD + j*xInc + xInc/2;
                float yMax   = h - PAD - gridY*((float)maxValues[j]/stepVal);
                float yClose = h - PAD - gridY*((float)closeVals[j]/stepVal);
                float yMin   = h - PAD - gridY*((float)minValues[j]/stepVal);
                g2.draw(new Line2D.Float(x, yMax, x, yMin));
                g2.draw(new Line2D.Float(x, yClose, x+CLOSE, yClose));
            }
        }
    
        private int getMaxValue() {
            int max = 0;
            for(int j = 0; j < maxValues.length; j++) {
                if(maxValues[j] > max)
                    max = maxValues[j];
            }
            return max;
        }
    
        private void initArrays() {
            Vector<String> highs  = stockMonth.getHighPrice();
            Vector<String> closes = stockMonth.getMonthClose();
            Vector<String> lows   = stockMonth.getLowPrice();
            System.out.println("highs  = " + highs);
            System.out.println("closes = " + closes);
            System.out.println("lows   = " + lows);
            maxValues = new int[highs.size()];
            minValues = new int[highs.size()];
            closeVals = new int[highs.size()];
            for(int j = 0; j < maxValues.length; j++) {
                maxValues[j] = Integer.parseInt((String)highs.get(j));
                closeVals[j] = Integer.parseInt((String)closes.get(j));
                minValues[j] = Integer.parseInt((String)lows.get(j));
            }
        }
    }
    For future reference the data file (spacing) format that works for the parsing code in StockMonth is:
    Java Code:
    MAY  7   18  20
    JUN 10   19  26
    JUL 12   14  22
    AUG 14   24  38
    SEP 34   45  52
    OCT 42   51  56
    NOV 45   49  53
    DEC 40   45  55

  3. #3
    adlb1300 is offline Member
    Join Date
    Jul 2007
    Posts
    46
    Rep Power
    0

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •