How to plot a Line Graph in Java using dataset from a text file?
Asked Answered
A

1

0

I have written a Java GUI program which opens a text file and reads the data in the left panel. Now I want to display a graph of the data read from the same file on the right panel.

I have used JFileChooser to open files and read the data and display them on a text area. I want the data read from the file to be displayed using a two dimensional X-Y graph. The axis of the graph should be labeled using the label information specified in the data file. The values on the X-axis should begin from the x-axis start value specified, with intervals which increment at a rate determined by the x-axis interval value. The values on the Y-axis will need to be determined from the data itself. Each point plotted on the graph should be joined using a single line.

I have used several methods but none worked. I have tried reading each line on the text file as arrays and use the arrays as the dataset, but it didn't work as well. Please help me plot a graph from the data on the text file. Any help would be appreciated. Thanks.

P.S The graph should be plotted using AWT/Swing libraries only.

The data on the file is as follows:

Title: Effect of Age on Ability
Xlabel: Age
Ylabel: Ability
start: 0
interval: 15
0, 3, 4.2, 7, 5.1, 10, 3.2

Following are my code which I have written so far:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.List;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

@SuppressWarnings("serial")
public class GUI extends JFrame {

    private String[] readLines = new String[6];

    public GUI() {
        // Setting Title, size and layout
        setTitle("Data Visualiser");
        setSize(950, 1000);
        setLayout(new BorderLayout());

        // Creates a menubar for a JFrame
        final JMenuBar menuBar = new JMenuBar();

        // Add the menubar to the frame
        setJMenuBar(menuBar);

        // Define and add two drop down menu to the menubar, "file" and "help"
        JMenu fileMenu = new JMenu("File");
        JMenu helpMenu = new JMenu("Help");
        menuBar.add(fileMenu);
        menuBar.add(helpMenu);

        // adding menu items and icons to the "file" drop down menu,
        final JMenuItem openAction = new JMenuItem("Open", new ImageIcon("images/Open-icon.png"));

        final JMenuItem saveAction = new JMenuItem("Save", new ImageIcon("images/save-file.png"));

        final JMenuItem exitAction = new JMenuItem("Exit", new ImageIcon("images/exit-icon.png"));

        final JMenuItem aboutAction = new JMenuItem("About", new ImageIcon("images/about-us.png"));

        //////////////////////////////////////////////////////////////////////////////////////////////
        // Create a text area.
        final JTextArea textArea = new JTextArea("");
        textArea.setFont(new Font("Serif", Font.BOLD, 16));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setEditable(false);
        JScrollPane textScrollPane = new JScrollPane(textArea);
        // textArea.add(textScrollPane, BorderLayout.CENTER); //add the
        // JScrollPane to the panel

        // Scrollbars
        textScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        textScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        textScrollPane.setPreferredSize(new Dimension(350, 550));
        textScrollPane.setBorder(
            BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Textual Representation"),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)));

        // Create an graphics pane.
        JPanel graphicsArea = new JPanel();
        //graphicsArea.setFont(new Font("Serif", Font.BOLD, 16));
        JScrollPane graphicsScrollPane = new JScrollPane(graphicsArea);

        // Scrollbars
        graphicsScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        graphicsScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        graphicsScrollPane.setPreferredSize(new Dimension(550, 550));
        graphicsScrollPane.setBorder(
            BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Graphical Representation"),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)));

        // Put the graphics pane and the text pane in a split pane.
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, textScrollPane, graphicsScrollPane);
        splitPane.setOneTouchExpandable(true);
        splitPane.setResizeWeight(0.5);

        JPanel rightPane = new JPanel(new GridLayout(1, 0));
        rightPane.add(splitPane);

        // Put everything together.
        JPanel leftPane = new JPanel(new BorderLayout());
        add(rightPane, BorderLayout.LINE_END);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // file menu shortcut
        fileMenu.setMnemonic(KeyEvent.VK_F);

        fileMenu.add(openAction);
        // openAction.addActionListener(this);
        openAction.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                if (arg0.getSource().equals(openAction)) {

                    // using JFileChooser to open the text file
                    JFileChooser fileChooser = new JFileChooser();

                    if (fileChooser.showOpenDialog(fileChooser) == JFileChooser.APPROVE_OPTION) {
                        // fileChooser.setCurrentDirectory(new
                        // File(System.getProperty("user.home"))); // setting
                        // current
                        // directory
                        File file = fileChooser.getSelectedFile();
                        BufferedReader br = null;

                        try {
                            // FileReader fr = new FileReader(file);
                            Scanner f = new Scanner(file);
                            for (int i = 0; i < 6; i++) {
                                readLines[i] = f.nextLine();
                                textArea.setText(textArea.getText() + readLines[i] + "\n");
                                String array[] = readLines[i].split(" ");

                            }
                        } catch (FileNotFoundException e) {
                            JOptionPane.showMessageDialog(new JFrame(), "File not found!", "ERROR!",
                                JOptionPane.ERROR_MESSAGE); // error message
                            // if file not
                            // found
                        } catch (NullPointerException e) {
                            // System.out.println(e.getLocalizedMessage());
                        } finally {
                            if (br != null) {
                                try {
                                    br.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                    }
                }
            }
        });

        fileMenu.add(saveAction);
        fileMenu.add(exitAction);

        // exit button shortcut
        exitAction.setMnemonic(KeyEvent.VK_X);
        exitAction.addActionListener(new ActionListener() {

            // setting up exit button
            public void actionPerformed(ActionEvent arg0) {
                if (arg0.getSource().equals(exitAction)) {
                    System.exit(0);
                }
            }
        });

        fileMenu.addSeparator();

        helpMenu.addSeparator();
        helpMenu.add(aboutAction);

        // about button shortcut
        aboutAction.setMnemonic(KeyEvent.VK_A);
        aboutAction.addActionListener(new ActionListener() {

            // clicking on about button opens up a dialog box which contain
            // information about the program
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane.showMessageDialog(menuBar.getComponent(0),
                    "This program is based on the development of a data visualization tool. \n"
                    + "The basic concept is to produce a piece of software which reads in raw textual data, \n"
                    + "analyses that data, then presents it graphically to the user.",
                    "About Us", JOptionPane.PLAIN_MESSAGE);
            }
        });

    }
}
Admixture answered 20/4, 2016 at 20:28 Comment(2)
You will need to be specific about the actual problem you're facing, and provide a complete, minimal example that helps us understand the problem. Not many people will be willing to look at your code dump, vague problem statement, and fix everything about your program for you.Pharyngitis
I am sorry if the description was not clear enough. I basically want to plot a line graph using the data provided in a text file. I have provided the content of the text file in the description (title, xlabel, ylabel, etc.)Admixture
A
3

Starting from your example, note the following:

  • Use a ChartPanel for your graphicsArea; then, your openAction() can simply invoke setChart().

  • Parse the chosen file in creatChart(); the title and data lines are shown, but the remaining attributes are left as an exercise.

  • Consider using Properties for your file format;

  • For greater flexibility, use Action as shown here.

  • To change the chart panel's default size, override getPreferredSize() as shown here.

  • Swing GUI objects should be constructed and manipulated only on the event dispatch thread.

P.S. The graph should be plotted using AWT/Swing libraries only.

For a single chart, replace ChartPanel with JPanel and override paintComponent() to perform the rendering. You can transform coordinates using the approach is outlined here or here.

image

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

//* @see https://mcmap.net/q/1330780/-how-to-plot-a-line-graph-in-java-using-dataset-from-a-text-file */
public class GUI extends JFrame {

    public GUI() {
        super("Data Visualiser");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        final JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        JMenu fileMenu = new JMenu("File");
        JMenu helpMenu = new JMenu("Help");
        menuBar.add(fileMenu);
        menuBar.add(helpMenu);

        final JMenuItem openAction = new JMenuItem("Open", new ImageIcon("images/Open-icon.png"));
        final JMenuItem saveAction = new JMenuItem("Save", new ImageIcon("images/save-file.png"));
        final JMenuItem exitAction = new JMenuItem("Exit", new ImageIcon("images/exit-icon.png"));
        final JMenuItem aboutAction = new JMenuItem("About", new ImageIcon("images/about-us.png"));

        final JTextArea textArea = new JTextArea(8, 16);
        textArea.setFont(new Font("Serif", Font.BOLD, 16));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setEditable(false);
        JScrollPane textScrollPane = new JScrollPane(textArea);
        textScrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Textual Representation"),
            BorderFactory.createEmptyBorder(5, 5, 5, 5)));

        ChartPanel graphicsArea = new ChartPanel(null);
        graphicsArea.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Graphical Representation"),
            BorderFactory.createEmptyBorder(5, 5, 5, 5)));

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, textScrollPane, graphicsArea);
        splitPane.setOneTouchExpandable(true);
        splitPane.setResizeWeight(0.5);
        add(splitPane, BorderLayout.LINE_END);

        fileMenu.setMnemonic(KeyEvent.VK_F);
        fileMenu.add(openAction);
        openAction.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (arg0.getSource().equals(openAction)) {
                    JFileChooser fileChooser = new JFileChooser(new File("."));
                    if (fileChooser.showOpenDialog(fileChooser) == JFileChooser.APPROVE_OPTION) {
                        File file = fileChooser.getSelectedFile();
                        graphicsArea.setChart(creatChart(file));
                    }
                }
            }

            private JFreeChart creatChart(File file) {
                String title = null;
                String xAxisLabel = null;
                String yAxisLabel = null;
                BufferedReader in = null;
                int start = 0;
                int interval = 0;
                String data = null;
                String line = null;
                try {
                    in = new BufferedReader(new FileReader(file));
                    while ((line = in.readLine()) != null) {
                        textArea.append(line + "\n");
                        if (line.startsWith("Title")) {
                            title = line.split(":")[1].trim();
                        }
                        // parse other lines here
                        if (!line.contains(":")) {
                            data = line;
                        }
                    }
                } catch (IOException ex) {
                    ex.printStackTrace(System.err);
                }
                XYSeries dataset = new XYSeries(file.getName());
                for (String s : data.split(",")) {
                    dataset.add(start, Double.valueOf(s));
                    start += interval;
                }
                return ChartFactory.createXYLineChart(title,
                    xAxisLabel, yAxisLabel, new XYSeriesCollection(dataset));
            }
        });
        fileMenu.add(saveAction);
        fileMenu.add(exitAction);
        exitAction.setMnemonic(KeyEvent.VK_X);
        exitAction.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (arg0.getSource().equals(exitAction)) {
                    System.exit(0);
                }
            }
        });
        fileMenu.addSeparator();
        helpMenu.addSeparator();
        helpMenu.add(aboutAction);
        aboutAction.setMnemonic(KeyEvent.VK_A);
        aboutAction.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane.showMessageDialog(null,
                    "Visualization tool.",
                    "About Us", JOptionPane.PLAIN_MESSAGE);
            }
        });
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new GUI();
        });
    }
}
Aliment answered 21/4, 2016 at 9:0 Comment(6)
Thank you so much. But how can I draw the graph with swing and not with other libraries such as jfreechart?Admixture
I'd definitely use a chart library; more are cited here.Aliment
I need this graph plotted only using AWT/Swing libraries. :(Admixture
Why? Please edit your question to reflect this requirement; one approach is outlined here.Aliment
Is there a way to create the graph in similar fashion like you showed using Swing library?Admixture
Yes, but get a one-of-a-kind chart. Inevitably you end up building your own library, which is one reason why there are so many.Aliment

© 2022 - 2024 — McMap. All rights reserved.