Draw graphs with java

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)< ArrayListscores = new ArrayList(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); 
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 ArrayListscores = new ArrayList(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); >> > 

Your code suggests that you’ve not yet read the tutorials on how to do Swing Graphics, and you need to do this before attempting this stuff. There’s no substitute for this. For e.g., you need to override paintComponent, but I don’t see this anywhere in your code. You can start here: Performing Custom Painting.

«I’m really sorry that this question seems so jumbled..» What ‘question’? I don’t see one in that mess of words. «but I’ve had little sleep.» Not our concern, not our problem & not an excuse for dumping your random thoughts to a Q&A site. Please wait till you’ve had sleep before posting more questions.

@AndrewThompson I’m sorry about that — I know it’s not a valid excuse — just thought there might be some who could sympathise with the state I’m in and forgive the lack of precision in my question and maybe infer the problem even though I may not have made it totally explicit. PetarMinchev, thanks for being able to do that!

Also, your x-axis is going to be very compressed seeing as how it increments by only one. You might want to make this a little bigger (and your y-axis too) by multiplying both by a scaling factor.

Also, won’t your code throw an array out of bounds exception when you try call get(i + 1) in that for loop of yours?

6 Answers 6

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.
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 Listscores; public DrawGraph(List 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); ListgraphPoints = new ArrayList(); 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() < Listscores = new ArrayList(); 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(); >>); > > 

enter image description here

Which will create a graph that looks like so:

Читайте также:  Одно всплывающее окно php

It worked — as in the line graph was drawn!! Thanks for being so patient me! The only problem is that for some reason eclipse is not recognising the setPreferredSize method — I’ve checked the API and it’s still fully supported — have no idea what’s happening there but I can hopefully sort that out by myself — thanks again!

@user1058210: You must be using it wrong. Please show us how you try to call it. Are you calling it outside of a constructor or method block?

Just complementing Hovercraft Full Of Eels’s solution:

I reworked his code, tweaked it a bit, adding a grid, axis labels and now the Y-axis goes from the minimum value present up to the maximum value. I planned on adding a couple of getters/setters but I didn’t need them, you can add them if you want.

Here is the Gist link, I’ll also paste the code below: GraphPanel on Gist

import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; 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.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class GraphPanel extends JPanel < private int width = 800; private int heigth = 400; private int padding = 25; private int labelPadding = 25; private Color lineColor = new Color(44, 102, 230, 180); private Color pointColor = new Color(100, 100, 100, 180); private Color gridColor = new Color(200, 200, 200, 200); private static final Stroke GRAPH_STROKE = new BasicStroke(2f); private int pointWidth = 4; private int numberYDivisions = 10; private Listscores; public GraphPanel(List 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 * padding) - labelPadding) / (scores.size() - 1); double yScale = ((double) getHeight() - 2 * padding - labelPadding) / (getMaxScore() - getMinScore()); ListgraphPoints = new ArrayList<>(); for (int i = 0; i < scores.size(); i++) < int x1 = (int) (i * xScale + padding + labelPadding); int y1 = (int) ((getMaxScore() - scores.get(i)) * yScale + padding); graphPoints.add(new Point(x1, y1)); >// draw white background g2.setColor(Color.WHITE); g2.fillRect(padding + labelPadding, padding, getWidth() - (2 * padding) - labelPadding, getHeight() - 2 * padding - labelPadding); g2.setColor(Color.BLACK); // create hatch marks and grid lines for y axis. for (int i = 0; i < numberYDivisions + 1; i++) < int x0 = padding + labelPadding; int x1 = pointWidth + padding + labelPadding; int y0 = getHeight() - ((i * (getHeight() - padding * 2 - labelPadding)) / numberYDivisions + padding + labelPadding); int y1 = y0; if (scores.size() >0) < g2.setColor(gridColor); g2.drawLine(padding + labelPadding + 1 + pointWidth, y0, getWidth() - padding, y1); g2.setColor(Color.BLACK); String yLabel = ((int) ((getMinScore() + (getMaxScore() - getMinScore()) * ((i * 1.0) / numberYDivisions)) * 100)) / 100.0 + ""; FontMetrics metrics = g2.getFontMetrics(); int labelWidth = metrics.stringWidth(yLabel); g2.drawString(yLabel, x0 - labelWidth - 5, y0 + (metrics.getHeight() / 2) - 3); >g2.drawLine(x0, y0, x1, y1); > // and for x axis for (int i = 0; i < scores.size(); i++) < if (scores.size() >1) < int x0 = i * (getWidth() - padding * 2 - labelPadding) / (scores.size() - 1) + padding + labelPadding; int x1 = x0; int y0 = getHeight() - padding - labelPadding; int y1 = y0 - pointWidth; if ((i % ((int) ((scores.size() / 20.0)) + 1)) == 0) < g2.setColor(gridColor); g2.drawLine(x0, getHeight() - padding - labelPadding - 1 - pointWidth, x1, padding); g2.setColor(Color.BLACK); String xLabel = i + ""; FontMetrics metrics = g2.getFontMetrics(); int labelWidth = metrics.stringWidth(xLabel); g2.drawString(xLabel, x0 - labelWidth / 2, y0 + metrics.getHeight() + 3); >g2.drawLine(x0, y0, x1, y1); > > // create x and y axes g2.drawLine(padding + labelPadding, getHeight() - padding - labelPadding, padding + labelPadding, padding); g2.drawLine(padding + labelPadding, getHeight() - padding - labelPadding, getWidth() - padding, getHeight() - padding - labelPadding); Stroke oldStroke = g2.getStroke(); g2.setColor(lineColor); 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(pointColor); for (int i = 0; i < graphPoints.size(); i++) < int x = graphPoints.get(i).x - pointWidth / 2; int y = graphPoints.get(i).y - pointWidth / 2; int ovalW = pointWidth; int ovalH = pointWidth; g2.fillOval(x, y, ovalW, ovalH); >> // @Override // public Dimension getPreferredSize() < // return new Dimension(width, heigth); // >private double getMinScore() < double minScore = Double.MAX_VALUE; for (Double score : scores) < minScore = Math.min(minScore, score); >return minScore; > private double getMaxScore() < double maxScore = Double.MIN_VALUE; for (Double score : scores) < maxScore = Math.max(maxScore, score); >return maxScore; > public void setScores(List scores) < this.scores = scores; invalidate(); this.repaint(); >public List getScores() < return scores; >private static void createAndShowGui() < Listscores = new ArrayList<>(); Random random = new Random(); int maxDataPoints = 40; int maxScore = 10; for (int i = 0; i < maxDataPoints; i++) < scores.add((double) random.nextDouble() * maxScore); // scores.add((double) i); >GraphPanel mainPanel = new GraphPanel(scores); mainPanel.setPreferredSize(new Dimension(800, 600)); JFrame frame = new JFrame("DrawGraph"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); > public static void main(String[] args) < SwingUtilities.invokeLater(new Runnable() < public void run() < createAndShowGui(); >>); > > 

Example pic

It looks like this:

Читайте также:  Html css before img

Источник

How to plot Graph in java

In this tutorial, we will learn how to draw a graph using Java. The drawing graph means plotting coordinates on a Cartesian plane. Co-ordinate is a combination of ordinate and abscissa ie(abscissa, ordinate). We can plot Graph using core Java using several topics ie. panels, graphics, AWT (Abstract Window Toolkit), etc.

To plot a graph in Java

First of all, we will import all the required packages. The Required packages are

we import swing package for the use of JButtons, JPanel, JLabel, etc.

We import awt package, awt acronyms for Abstract Window Toolkit, awt enables the user to make a graphical user interface for front-end of the project.

We import awt.geom package for performing operations related to two-dimensional geometry. Two-dimensional geometry refers to geometry in which we use only the x-axis and y-axis. In three Dimensional geometry, we use three, x-axis, y-axis, z-axis.

Code

import java.awt.*; import javax.swing.*; import java.awt.geom.*; public class G extends JPanel< int[] coordinates=; int mar=50; protected void paintComponent(Graphics g) < super.paintComponent(g); Graphics2D g1=(Graphics2D)g; g1.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); int width=getWidth(); int height=getHeight(); g1.draw(new Line2D.Double(mar,mar,mar,height-mar)); g1.draw(new Line2D.Double(mar,height-mar,width-mar,height-mar)); double x=(double)(width-2*mar)/(coordinates.length-1); double scale=(double)(height-2*mar)/getMax(); g1.setPaint(Color.BLUE); for(int i=0;i> private int getMax()< int max=-Integer.MAX_VALUE; for(int i=0;imax) max=coordinates[i]; >return max; > public static void main(String args[]) < JFrame frame =new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new G()); frame.setSize(400,400); frame.setLocation(200,200); frame.setVisible(true); >>

ABOUT OUR PROJECT

G is the name of the class created, coordinates is the array of points to be plotted on the graph. We are extending JPanel to use it for representing the graph. JPanel is the light-weight container that is invisible. The default Layout of the panel is Flow-Layout. There are several layouts some of them are

  1. grid layout
  2. grid bag layout
  3. flow layout
  4. box layout
  5. border layout
  6. card layout
  7. group layout
  8. spring layout
Читайте также:  Заменить строки массивом java

But flow layout is the default layout for the panel.

Functions and methods used in the project

We are using super.paintComponent(g), as we use the super keyword for calling parent class constructor or parent class method, And in this case, JPanel is the parent class.

Graphic 2D class again extends Graphics class to provide control over geometry. This is a fundamental class for two-dimensional shapes.

RenderingHints are the suggestions to the Java 2D about how it should perform its rendering.

In general, rendering means the way something is performed.

setRenderingHints() refer to the new set of hints that replaces the old ones.

We use Antialiasing for smoothing of the jagged edges in case of very low resolutions.

g1.draw() method is used to draw lines representing the x-axis and y-axis. Four coordinates are used to draw line (x1,y1,x2,y2).

Method setpaint() method is used to set the color to the points which we are plotting on the graph.

We calculate the value of co-ordinates using the method.

In for loop, we are using coordinates.length(), it is the method used to find the length of the array ie. coordinates.

The methods getWidth() and getHeight() are the methods of component that we use to return the height and width of the component we are using.

And x1 and y1 are the variables, that we use to plot points with respect to the size of the component instead of the cartesian plane.

The setting of size and layout of the Frame

The frame is the object of JFrame and further, we perform four operations ie.

  • setLocation to set the location of the frame.
  • setDefaultClose Operation to close the frame.
  • setVisible to set the visibility of the frame.
  • setSize to set the size of the frame.

The output result will show a graph like you can see below:

Источник

Визуализация графов на JAVA

Все мы прекрасно знаем такую замечательную структуру данных как — графы. Множество самых разнообразных задач формулируется в терминах графов и многие могут быть решены с помощью этого мощнейшего инструмента. Мы знаем кучу алгоритмов на графах и различные их реализации. Все это здорово, но что если перед нами вдруг встанет задача отобразить этот самый граф? Нет проблем? А если вершин с десяток, а если сотни, а куча дуг между ними?
Не стоит беспокоиться, с решеним подобного рода задач отлично справится библиотека Jgraph.

Jgraph — это open source бибилиотека для визуализации графов, написанная на Java и полностью совместима со Swing`oм. Библиотека разработана с поддержкой различных представлений сущностей и их отношений, неориентированные грфы, ориентированные графы, мультиграфы, графы с параллельными дугами, гиперграфы. Позволяет использовать различные алгоритмы позиционирования вершин и прочие вкусности, подробности тут.

Элементарный граф с двумя вершинами можно визуализировать следующим образом.

Прежде всего добавляем зависимость в наш pom файл.

И далее нехитрая форма

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;

public class HabrGraph extends JFrame

public static void main(String[] args) HabrGraph frame = new HabrGraph();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 320);
frame.setVisible(true);

public HabrGraph()
super(«HabraGraph»);

mxGraph graph = new mxGraph();
Object parent = graph.getDefaultParent();

graph.getModel().beginUpdate();
try
Object v1 = graph.insertVertex(parent, null, «Habra», 20, 20, 80, 30);
Object v2 = graph.insertVertex(parent, null, «Habr», 240, 150, 80, 30);
graph.insertEdge(parent, null, «Дуга», v1, v2);
>
finally
graph.getModel().endUpdate();
>

mxGraphComponent graphComponent = new mxGraphComponent(graph);
getContentPane().add(graphComponent);
>

В результать получим следующее симпатичное окошко

Если Jgraph не понравится советую обратить внимание на не менне мощную библиотеку JUNG.

Надеюсь перечисленные выше библиотеки пригодятся в вашей работе и станут украшением вашего проекта, а можеть быть и неотъемлемой частью функционала.

Источник

Оцените статью