Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing a simple line graph in Java

In my program I want to draw a simple score line graph. I have a text file and on each line is an integer score, which I read in and want to pass as argument to my graph class. I'm having some trouble implementing the graph class and all the examples I've seen have their methods in the same class as their main, which I won't have.

I want to be able to pass my array to the object and generate a graph, but when calling my paint method it is asking me for a Graphics g... This is what I have so far:

public class Graph extends JPanel {      public void paintGraph (Graphics g){          ArrayList<Integer> scores = new ArrayList<Integer>(10);          Random r = new Random();          for (int i : scores){             i = r.nextInt(20);             System.out.println(r);         }          int y1;         int y2;          for (int i = 0; i < scores.size(); i++){             y1 = scores.get(i);             y2 = scores.get(i+1);             g.drawLine(i, y1, i+1, y2);         }     } } 

For now I have inserted a simple random number generator to fill up my array.

I have an existing frame and basically want to instantiate the Graph class and mount the panel onto my frame. I'm really sorry that this question seems so jumbled by the way, but I've had little sleep...

The code in my main statement is:

testFrame = new JFrame(); testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Graph graph = new Graph(); testFrame.add(graph); 

I'm not sure exactly what an SSCE is but this is my attempt at one:

public class Test {      JFrame testFrame;     public Test() {         testFrame = new JFrame();         testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         Graph graph = new Graph();         testFrame.add(graph);         testFrame.setBounds(100, 100, 764, 470);         testFrame.setVisible(true);     } 

Graph.java

public class Graph extends JPanel {     public Graph() {        setSize(500, 500);     }      @Override     public void paintComponent(Graphics g) {         Graphics2D gr = (Graphics2D) g; // This is if you want to use Graphics2D         // Now do the drawing here         ArrayList<Integer> scores = new ArrayList<Integer>(10);          Random r = new Random();          for (int i : scores) {             i = r.nextInt(20);             System.out.println(r);         }          int y1;         int y2;          for (int i = 0; i < scores.size() - 1; i++) {             y1 = (scores.get(i)) * 10;             y2 = (scores.get(i + 1)) * 10;             gr.drawLine(i * 10, y1, (i + 1) * 10, y2);         }     } } 
like image 473
user1058210 Avatar asked Jan 01 '12 13:01

user1058210


People also ask

How do you make a line graph in Java?

To create a line chart, at a minimum, you must define two axes, create the LineChart object by instantiating the LineChart class, create one or more series of data by using the XYChart. Series class, and assign the data to the chart.

Can we draw graph in Java?

In Java, plotting of graph is done by using several topics of core Java. For plotting, we use swing, awt, and awt. geom. We use Swing package to use Jlabel, JButtons, and JPanel in our program.

What is a simple line graph?

A simple line graph is the most basic type of line graph. In this graph, only one dependent variable is tracked, so there is only a single line connecting all data points on the graph. All points on the graph relate to the same item, and the only purpose of the graph is to track the changes of that variable over time.


1 Answers

Problems with your code and suggestions:

  • Again you need to change the preferredSize of the component (here the Graph JPanel), not the size
  • Don't set the JFrame's bounds.
  • Call pack() on your JFrame after adding components to it and before calling setVisible(true)
  • Your foreach loop won't work since the size of your ArrayList is 0 (test it to see that this is correct). Instead use a for loop going from 0 to 10.
  • You should not have program logic inside of your paintComponent(...) method but only painting code. So I would make the ArrayList a class variable and fill it inside of the class's constructor.

For example:

import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.Stroke; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.*;  @SuppressWarnings("serial") public class DrawGraph extends JPanel {    private static final int MAX_SCORE = 20;    private static final int PREF_W = 800;    private static final int PREF_H = 650;    private static final int BORDER_GAP = 30;    private static final Color GRAPH_COLOR = Color.green;    private static final Color GRAPH_POINT_COLOR = new Color(150, 50, 50, 180);    private static final Stroke GRAPH_STROKE = new BasicStroke(3f);    private static final int GRAPH_POINT_WIDTH = 12;    private static final int Y_HATCH_CNT = 10;    private List<Integer> scores;     public DrawGraph(List<Integer> scores) {       this.scores = scores;    }     @Override    protected void paintComponent(Graphics g) {       super.paintComponent(g);       Graphics2D g2 = (Graphics2D)g;       g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);        double xScale = ((double) getWidth() - 2 * BORDER_GAP) / (scores.size() - 1);       double yScale = ((double) getHeight() - 2 * BORDER_GAP) / (MAX_SCORE - 1);        List<Point> graphPoints = new ArrayList<Point>();       for (int i = 0; i < scores.size(); i++) {          int x1 = (int) (i * xScale + BORDER_GAP);          int y1 = (int) ((MAX_SCORE - scores.get(i)) * yScale + BORDER_GAP);          graphPoints.add(new Point(x1, y1));       }        // create x and y axes        g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, BORDER_GAP, BORDER_GAP);       g2.drawLine(BORDER_GAP, getHeight() - BORDER_GAP, getWidth() - BORDER_GAP, getHeight() - BORDER_GAP);        // create hatch marks for y axis.        for (int i = 0; i < Y_HATCH_CNT; i++) {          int x0 = BORDER_GAP;          int x1 = GRAPH_POINT_WIDTH + BORDER_GAP;          int y0 = getHeight() - (((i + 1) * (getHeight() - BORDER_GAP * 2)) / Y_HATCH_CNT + BORDER_GAP);          int y1 = y0;          g2.drawLine(x0, y0, x1, y1);       }        // and for x axis       for (int i = 0; i < scores.size() - 1; i++) {          int x0 = (i + 1) * (getWidth() - BORDER_GAP * 2) / (scores.size() - 1) + BORDER_GAP;          int x1 = x0;          int y0 = getHeight() - BORDER_GAP;          int y1 = y0 - GRAPH_POINT_WIDTH;          g2.drawLine(x0, y0, x1, y1);       }        Stroke oldStroke = g2.getStroke();       g2.setColor(GRAPH_COLOR);       g2.setStroke(GRAPH_STROKE);       for (int i = 0; i < graphPoints.size() - 1; i++) {          int x1 = graphPoints.get(i).x;          int y1 = graphPoints.get(i).y;          int x2 = graphPoints.get(i + 1).x;          int y2 = graphPoints.get(i + 1).y;          g2.drawLine(x1, y1, x2, y2);                }        g2.setStroke(oldStroke);             g2.setColor(GRAPH_POINT_COLOR);       for (int i = 0; i < graphPoints.size(); i++) {          int x = graphPoints.get(i).x - GRAPH_POINT_WIDTH / 2;          int y = graphPoints.get(i).y - GRAPH_POINT_WIDTH / 2;;          int ovalW = GRAPH_POINT_WIDTH;          int ovalH = GRAPH_POINT_WIDTH;          g2.fillOval(x, y, ovalW, ovalH);       }    }     @Override    public Dimension getPreferredSize() {       return new Dimension(PREF_W, PREF_H);    }     private static void createAndShowGui() {       List<Integer> scores = new ArrayList<Integer>();       Random random = new Random();       int maxDataPoints = 16;       int maxScore = 20;       for (int i = 0; i < maxDataPoints ; i++) {          scores.add(random.nextInt(maxScore));       }       DrawGraph mainPanel = new DrawGraph(scores);        JFrame frame = new JFrame("DrawGraph");       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       frame.getContentPane().add(mainPanel);       frame.pack();       frame.setLocationByPlatform(true);       frame.setVisible(true);    }     public static void main(String[] args) {       SwingUtilities.invokeLater(new Runnable() {          public void run() {             createAndShowGui();          }       });    } } 

Which will create a graph that looks like so: enter image description here

like image 151
Hovercraft Full Of Eels Avatar answered Sep 19 '22 21:09

Hovercraft Full Of Eels