Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Bar Graph Help

setpreferredsize

  • Please log in to reply
9 replies to this topic

#1 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 06 June 2012 - 05:28 PM

ok so I'm doing an exercise in this book I'm reading and I have to create a bar graph for stock prices in a week given by the user. I have everything down except how to make the bars. The annoying thing about the book is that the bar for Monday MUST be chartheight/2, I don't know why, so I think that means that the other four bars have to be proportionate to height/2. Can someone help me with the height and y coordinate of the other four bars? Here is my code thus far:
import java.util.Scanner;
import javax.swing.JFrame;
public class StockChart {

static Scanner input = new Scanner(System.in);

public static void main(String[] args){
  System.out.print("Enter stock name: ");
  String name = input.nextLine().trim();
  double[] p = getPrices();
  System.out.print("Enter width of chart: ");
  int width = Integer.parseInt(input.nextLine());
  System.out.print("Enter height of chart: ");
  int height = Integer.parseInt(input.nextLine());
  JFrame frame = new JFrame("Chart for " + name);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  StockChartPanel panel = new StockChartPanel(p, width, height);
  frame.getContentPane().add(panel);
  frame.pack();
  frame.setVisible(true);
}

//prompts the user to enter the stock prices and stores them in an array of double values
private static double[] getPrices(){
  double[] prices = new double[5];
  for(int i = 0; i < 5; i++){
   System.out.print("Enter ");
   switch(i){
   case 0:
	System.out.print("Monday ");
	break;
   case 1:
	System.out.print("Tuesday ");
	break;
   case 2:
	System.out.print("Wednesday ");
	break;
   case 3:
	System.out.print("Thursday ");
	break;
   case 4:
	System.out.print("Friday ");
	break;
   }
   System.out.print("price: ");
   prices[i] = input.nextDouble();
   input.nextLine();
  }
  return prices;
}

}

panel class:
import javax.swing.JPanel;
import java.awt.*;
public class StockChartPanel extends JPanel{

double[] prices;
int height, width;

public StockChartPanel(double[] p, int h, int w){
  prices = p;
  height = h;
  width = w;
  //the height is height+height/10 because there is a margin under the bars so I can write the days
  setPreferredSize(new Dimension(width, height+height/10));
}

public void paintComponent(Graphics g){
  int y = height/2;
  g.setColor(Color.RED);
  g.fillRect(0, height/2, width/5, height-(height/2));
  g.setColor(Color.BLUE);
  /////////////////////////////////////this is where I'm having trouble///////////////////////////////////////////////////////////////////////////////////////
  g.fillRect(width/5, (int)(y+(prices[0]/(height/2)*prices[1])), width/5, (int)(height - (y+(prices[0]/(height/2)*prices[1]))));
}

}

as you can probably see, I'm having a lot of trouble figuring out the y coordinate and the height of the second bar, let alone the other three. If anyone could help that would be swell.

Thanks a lot
  • 0

#2 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 06 June 2012 - 08:18 PM

Actually, the y coordinate is opposite to our real-world. So we have to must translate the y cordinate. Try the following code for paintComponent method.


public void paintComponent(Graphics g){

  double maxPrice = 0.0;
  for (int i = 0; i < p.length; i++)
     if (maxPrice < p[i])
          maxPrice = p[i];

  float gapBetweenBar = 5;
  float bottomMarging = 10;

  float chartWidth = (width - (gapBetweenBar * (p.length + 1))) / p.length;

  for (int i = 0; i < p.length; i++)
	{
	  float chartHeight = (height - bottomMarging) * (float)p[i] / (float)maxPrice;
      float y = (height - bottomMarging - chartHeight); // translating the y cordinate
	  g.setColor(Color.BLUE);
      g.fillRect((gapBetweenBar * (i + 1)) + (i * chartWidth), y, chartWidth, chartHeight);
   }

}


  • 0

#3 BlackRabbit

BlackRabbit

    CodeCall Legend

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3871 posts
  • Location:Argentina
  • Programming Language:C, C++, C#, PHP, JavaScript, Transact-SQL, Bash, Others
  • Learning:Java, Others

Posted 06 June 2012 - 08:58 PM

Here , i took KC's code, and make it compile :D , so this actually works


    public void paintComponent(Graphics g){

	    double maxPrice = 0.0;
	    for (int i = 0; i < prices.length; i++)
		    if (maxPrice < prices[i])
			    maxPrice = prices[i];

	    float gapBetweenBar = 5;
	    float bottomMarging = 10;

	    float chartWidth = (width - (gapBetweenBar * (prices.length + 1))) / prices.length;

	    for (int i = 0; i < prices.length; i++)
	    {
		    float chartHeight = (height - bottomMarging) * (float)prices[i] / (float)maxPrice;
		    float y = (height - bottomMarging - chartHeight); // translating the y cordinate
		    g.setColor(Color.BLUE);
		    g.fillRect(
				    (int)((gapBetweenBar * (i + 1)) + (i * chartWidth)),
				    (int)y,
				    (int)chartWidth, (int)chartHeight);
	    }

    }
 

its not over yet, you should change this line in stockchart too :


StockChartPanel panel = new StockChartPanel(p, height, width);


i don't know it is gonna be useful to you, but for testing purposes i hardcoded the chart values so you can test many times without having to bother on the many required data inputs

    public static void main(String[] args)
    {
	    System.out.print("Enter stock name: ");
	    String name = "Chartie";
	    //String name = input.nextLine().trim();
	    //double[] p = getPrices();

	    double[] p = new double[] {100,130,174,85,95};

	    System.out.print("Enter width of chart: ");
	    //int width = Integer.parseInt(input.nextLine());
	    int width = 400;
	    System.out.print("Enter height of chart: ");
	    //int height = Integer.parseInt(input.nextLine());
	    int height = 300;

	    JFrame frame = new JFrame("Chart for " + name);

	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//	    StockChartPanel panel = new StockChartPanel(p, width, height);
	    StockChartPanel panel = new StockChartPanel(p, height, width);
	    frame.getContentPane().add(panel);
	    frame.pack();
	    frame.setVisible(true);
    }
 

now, is that your only problem ?
cause given that code you might want to work on this todo list :

- fix the frame not to resize
- give the name to the columns in the graph
- write the column's values somewhere around each column (or do the axis scale)

is there anything else we can do for you ?
  • 0

#4 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 07 June 2012 - 08:09 AM

I appreciate you guys giving me code, but that isn't what I was looking for. I just want someone to explain to me how to figure the y coordinate / height, not just give me code and tell me it works. I don't learn anything that way.

I edited my code to show exactly where I'm having trouble (the panel class, last line).

thanks you guys
  • 0

#5 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 07 June 2012 - 08:26 AM

Well, one of the ways to learn is the debug the code and learn the logic. However, I have also said the things in brief in a line --

Actually, the y coordinate is opposite to our real-world. So we have to must translate the y cordinate. Try the following code for paintComponent method.


However to tell you in details: When you works with Cartesian 2D coordinate in Math, the center (0,0) is bottom-left corner and you increase X coordinate from left to right and increase Y coordinate from bottom to top. But the center in computer is the top-left corner and you increase X coordinate from left to right but increase Y coordinate from top to bottom. Note that, we want to draw our coordinate things in computer as real world. So, we need a Y-axis conversion from real-world coordinates to computer screen. This conversion is called -Translating Axis. This is what you need to do in your code.

Now my suggestion is that debug the code I posted above (use the BR's successfully compile version) and understand the things.
  • 0

#6 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 07 June 2012 - 08:35 AM

I know how the coordinate system works in computers. The code you provided me doesn't really seem relevant. You made a formula for computing the x coordinate, but I already know what every x coordinate will be. I know that the width of all the bars is already going to be width/5. I know that the height for the first bar (the monday bar) is chartheight/2. Therefore, the y coordinate for the first bar will, by default, be chartheight-chartheight/2 which is chartheight/2. The problem comes when trying to figure out where to place the other bars on the y axis, because I need to place them relative to the monday bar. The height of the bar will then be chartheight - y.
  • 0

#7 BlackRabbit

BlackRabbit

    CodeCall Legend

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3871 posts
  • Location:Argentina
  • Programming Language:C, C++, C#, PHP, JavaScript, Transact-SQL, Bash, Others
  • Learning:Java, Others

Posted 07 June 2012 - 01:08 PM

i think i start getting where you are going cruelhand,

so, no code, just hints so you learn and code yourself

. you have the reference frame, which will be the amount of pixels you get from : frame height minus borders height minus titles / scales height, that is your bars 100% possible height, meaning, the Y 100 for a drawn bar

lets think you have a 140 pixels frame, and the available Y for the bars is 100, and the start Y coordinate is 20

now, you get a series of values you need to fit in that Y, values are the monday's price, tuesday's price, etc

so, first thing is to calculate the maximum value to be shown, lets supouse its for tuesday and it is 500
and lets thing you want the maximum value to reach top Y
so you will now know that a 500 price is equivalent to a 100 pixels height Y bar

now you get wednesday, 320 in price, so you calculate the proportional, which is 320/500
and multiply that by the Y max height (100 in this case) and that will give you the bar's height

so you draw a bar from Y bars frame start (20 now, remember, calculating the frame borders, title, etc)
from there, Y:20 to Y:20 + (bar proportional height * bar's available frame (100 in this example) )
and that will give you the proportional Y coordinate according to you own frame size and scale
  • 0

#8 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 07 June 2012 - 01:24 PM

but the thing is, the height of the monday bar has to be chartheight/2. So every other value must be relative to the monday bar instead of the maximum value, right?
  • 0

#9 BlackRabbit

BlackRabbit

    CodeCall Legend

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3871 posts
  • Location:Argentina
  • Programming Language:C, C++, C#, PHP, JavaScript, Transact-SQL, Bash, Others
  • Learning:Java, Others

Posted 07 June 2012 - 01:34 PM

oh, cruelhand,

in that case, what it changes is like this :

Y:maximum = monday's *2

so monday's value is 50% of the scale, and the rest of the idea i gave you is still good, with one exception,
you will have to ponder when a bar excedes the bar maximum Y, meaning, if tuesday's price is bigger than monday's * 2, you have only to draw up to y:maximum and not surpase the bar's frame upper limit, maybe you can paint it in another color if that happens
  • 0

#10 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 07 June 2012 - 02:07 PM

I'm not really concerned about what happens if there is an outlier. This program is only for a java book I'm learning from and the stocks in a week normally fluctuate between plus and minus 5, so I won't have to worry about a huge leap like double. Thanks a lot for your help blackrabbit, I really appreciate it.
  • 0





Also tagged with one or more of these keywords: setpreferredsize

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download