javajavafxgraphjfreechartjfreechart-fx

I want to input values to be plotted on a scatter plot graph


I would like to create an application in Java I can use to plot points onto a scatterplot. I'm using the JFreeChart external library for this. I've tried creating a text.box to input the values, however it wont let me use the variable in different methods could someone please help me it'd be greatly appreciated.

package Grava;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.statistics.HistogramDataset;
import org.jfree.chart.fx.ChartViewer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.data.statistics.HistogramDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import java.io.File;
import java.io.IOException;

public class Main extends graph{
    static Stage window;
    Stage window1;
    Button button;
    Button exitButton;
    Button button1;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        window = primaryStage;
        window.setTitle("Grava");
        Image image = new Image("Grava.logo.png");
        window.getIcons().add(image);

        String arr[] = {"Voltage", "Current", ""};
        /*
        Integer yVariables[] = {4, 6, 8, 10};
        Integer xVariables[] = {1, 2, 3, 4};
        Integer deltaY = ((yVariables[(yVariables.length - 1)]) - (yVariables[0]));
        Integer deltaX = ((xVariables[(xVariables.length - 1)]) - (xVariables[0]));
        Integer gradient = ((deltaY) / (deltaX));
        */
        ChoiceBox dropDown = new ChoiceBox(FXCollections.observableArrayList(arr));
        GridPane grid = new GridPane();
        grid.setPadding(new Insets(10, 10, 10, 100));
        grid.setVgap(8);

        TextField passInput = new TextField();
        passInput.setPromptText("password");
        GridPane.setConstraints(passInput, 1, 0);

        TextField Xbox1 = new TextField();
        passInput.setPromptText("password");
        GridPane.setConstraints(Xbox1, 5, 0);

        TextField Xbox2 = new TextField();
        passInput.setPromptText("password");
        GridPane.setConstraints(Xbox2, 10, 0);

        button = new Button("click me");
        GridPane.setConstraints(button, 1, 2);
        button.setOnAction(e -> System.out.println(passInput.getText()));

        button1 = new Button("click me for graph");
        GridPane.setConstraints(button1,100,50);
        button1.setOnAction(e->{

            GridPane grid1 = new GridPane();
            grid.setPadding(new Insets(10, 10, 10, 100));
            grid.setVgap(8);
            java.awt.Button button = new java.awt.Button("hey click me");
            ChartViewer viewer = new ChartViewer(createChart());
            window.setScene(new Scene(viewer));
            Scene scene = new Scene(grid1, 300, 200);
            window.setTitle("VI Characteristics graph");
            window.setWidth(600);
            window.setHeight(400);
            window.show();
                });

        exitButton = new Button("Exit button");
        GridPane.setConstraints(exitButton, 10, 10);
        exitButton.setOnAction(e -> closeProgram());

        grid.getChildren().addAll(passInput,Xbox1,Xbox2, button,button1, exitButton, dropDown);
        Scene scene = new Scene(grid, 300, 200);

        ChartViewer viewer = new ChartViewer();
        //window.setScene();
        window.setScene(scene);
        window.show();
    }
    public static JFreeChart createChart() {


        XYSeriesCollection dataset = new XYSeriesCollection();

        XYSeries series1 = new XYSeries("Voltage");
        series1.add(10, 35);
        series1.add(11, 37);
        series1.add(12, 41);
        series1.add(12, 39);
        series1.add(13, 44);
        series1.add(14, 51);
        series1.add(15, 52);
        series1.add(15, 54);
        series1.add(16, 57);
        series1.add(17, 62);
        series1.add(17, 66);
        series1.add(18, 70);

        dataset.addSeries(series1);

        JFreeChart scatterPlot = ChartFactory.createScatterPlot(
                "VI Characteristics graph", // Chart title
                "Voltage", // X-Axis Label
                "Current", // Y-Axis Label
                dataset // Dataset for the Chart
        );
        return scatterPlot;
    }

    private static void closeProgram(){
        System.out.println("File saved");
        window.close();
    }
}

Solution

  • Your question is very broad, but the basic approach is to update the underlying dataset—the listening chart will update itself in response. In the variation below, the Add button handler updates the class attribute series to add the values from a pair of Spinner instances.

    series.add(xSpin.getValue(), ySpin.getValue());
    

    Several related examples are seen here. Also consider adding a ChartMouseListenerFX, seen here, which will allow you to select points for editing. For reference, the pure JavaFX dynamic BarChart shown here employs the same concept: the animation's KeyFrame handler updates the series, and the listening chart updates itself in response.

    series.getData().get(i).setYValue(pole[i]);
    

    how would I do this in terms of adding the points via a text field?

    In this example, the easiest way is to invoke setEditable() on the spinners.

    xSpin.setEditable(true);
    ySpin.setEditable(true);
    

    Scatter Plot

    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Spinner;
    import javafx.scene.control.ToolBar;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.fx.ChartViewer;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    
    /**
     * @see https://stackoverflow.com/q/74182275/230513
     */
    public class ScatterAdd extends Application {
    
        private final XYSeries series = new XYSeries("Voltage");
    
        private JFreeChart createChart() {
            XYSeriesCollection dataset = new XYSeriesCollection();
            series.add(10, 35);
            series.add(11, 37);
            series.add(12, 41);
            series.add(12, 39);
            series.add(13, 44);
            series.add(14, 51);
            series.add(15, 52);
            series.add(15, 54);
            series.add(16, 57);
            series.add(17, 62);
            series.add(17, 66);
            series.add(18, 70);
            dataset.addSeries(series);
            JFreeChart scatterPlot = ChartFactory.createScatterPlot(
                "VI Characteristics", "Voltage", "Current", dataset
            );
            return scatterPlot;
        }
    
        @Override
        public void start(Stage stage) {
            stage.setTitle("ScatterAdd");
            var xSpin = new Spinner<Number>(1, 100, 19, 1);
            var ySpin = new Spinner<Number>(1, 100, 67, 1);
            var button = new Button("Add");
            button.setOnAction(new EventHandler<ActionEvent>() {
    
                @Override
                public void handle(ActionEvent event) {
                    series.add(xSpin.getValue(), ySpin.getValue());
                }
            });
            var enter = new ToolBar(xSpin, ySpin, button);
            BorderPane root = new BorderPane();
            ChartViewer chartViewer = new ChartViewer(createChart());
            root.setCenter(chartViewer);
            root.setBottom(enter);
            BorderPane.setAlignment(enter, Pos.CENTER);
            Scene scene = new Scene(root, 640, 480);
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
    }