0
votes

I have been going through the following tutorial for creating JavaFX graphs https://docs.oracle.com/javafx/2/charts/line-chart.htm

My question is, how can I dynamically create and add new series of data to my LineChart without explicating declaring each series i.e. series1, series2?

When I compile and run my program only a single series has been added.

Here is my code

Main class that creates the LineChart and instantiate 10 different companies.

    public class StockChart extends Application {

    @Override public void start(Stage stage) {

        stage.setTitle("Stock Market");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
         xAxis.setLabel("Time of Day");
         yAxis.setLabel("Price Per Stock");
         LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
        Scene scene  = new Scene(lineChart,800,600); 
        lineChart.setTitle("Stock Exchange");

        String[] timeOfDay = {"8:00AM", "9:00AM", "10:00AM", "161:00AM", "12:00PM",
                              "1:00PM", "2:00PM", "3:00PM", "4:00PM" };
        String[] stockCompany = { "AAPL", "ORCL", "MSFT", "GOOG", "AMZN", "FB", "HPQ", "YHOO", "ADSK", "ATVI"};

        for(int i = 0; i < stockCompany.length; i++) {
          CompanyStockData tmpCompany = new CompanyStockData(lineChart, timeOfDay, stockCompany[i]);
          lineChart.getData().add(tmpCompany.generateStock());
          // lineChart.getData().add(line.generateStock());
          // lineChart.seriesRemoved(line.series);
        }



        stage.setScene(scene);
        stage.show();
    }


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

CompanyStockData Class for generating a new series to be added to LineChart

public class CompanyStockData extends StockChart {
  protected   LineChart<String,Number> lineChart;
  protected   String[] timeOfDay;
  protected  String companyName;
  public  XYChart.Series series = new XYChart.Series();

  public CompanyStockData(LineChart<String,Number> lineChart, String[] timeOfDay, String companyName) {
    this.lineChart = lineChart;
    this.timeOfDay = timeOfDay;
    this.companyName = companyName;
  }

  public XYChart.Series generateStock() {
    series.setName(companyName);
    System.out.println(lineChart);
    for(int i = 0; i < timeOfDay.length; i++) {
      System.out.println(timeOfDay[i]);
      series.getData().add(new XYChart.Data(timeOfDay[i], i*2));
    }
    return series;
  }

  public static void main(String[] args) {

  }

  @Override
  public String toString() {
    return "Company : " + this.companyName +
            " Time Of Day Length " + this.timeOfDay.length;
  }

}
2
All the series appear... however they all have the same values, so you only see the one that is on top. If you generate each one with different values you will see them all. - James_D
Sorry James, I added the question after Eric commented. - corykitchens
Thank you James for the answer, I can't believe I missed that! - corykitchens

2 Answers

1
votes

Your code is putting on chart 10 companies. They are just covered by each other and you are not able to see them all. To fix it I added yAddedValue variable in CompanyStockData class. This variable just moves the company's line a bit higher.

StockChart class

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.stage.Stage;

public class StockChart extends Application {

    @Override public void start(Stage stage) {

        stage.setTitle("Stock Market");

        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();

        xAxis.setLabel("Time of Day");
        yAxis.setLabel("Price Per Stock");

        LineChart<String, Number> lineChart = new LineChart<String,Number>(xAxis,yAxis);

        Scene scene  = new Scene(lineChart,800,600); 

        lineChart.setTitle("Stock Exchange");

        String[] timeOfDay = {"8:00AM", "9:00AM", "10:00AM", "161:00AM", "12:00PM",
                            "1:00PM", "2:00PM", "3:00PM", "4:00PM" };
        String[] stockCompany = { "AAPL", "ORCL", "MSFT", "GOOG", "AMZN", "FB", "HPQ",
                            "YHOO", "ADSK", "ATVI"};

        for(int i = 0; i < stockCompany.length; i++) {
            CompanyStockData tmpCompany = new CompanyStockData(lineChart, timeOfDay, stockCompany[i], i+3);
            lineChart.getData().add(tmpCompany.generateStock());
        }

        stage.setScene(scene);
        stage.show();
    }    

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

CompanyStockData class

import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;

public class CompanyStockData {

    protected LineChart<String,Number> lineChart;
    protected String[] timeOfDay;
    protected String companyName;
    public XYChart.Series series = new XYChart.Series();

    private int yAddedValue;

    public CompanyStockData(LineChart<String,Number> lineChart, String[] timeOfDay, String companyName, int yAddedValue) {
        this.lineChart = lineChart;
        this.timeOfDay = timeOfDay;
        this.companyName = companyName;
        this.yAddedValue = yAddedValue;
    }

    public XYChart.Series generateStock() {
        series.setName(companyName);
        System.out.println(lineChart);

        for(int i = 0; i < timeOfDay.length; i++) {
            System.out.println(timeOfDay[i]);
            series.getData().add(new XYChart.Data(timeOfDay[i], i*2 + yAddedValue));
        }

        return series;
    }

}
0
votes

To not declare series1, series2, series3 ... you can create an ArrayList. In the code bellow I created an ArrayList with all the companies. I also created a MouseClickEvent. When you press a button on your mouse, the company, defined by variavble companysNumber, changes its values.

StockChart class

import java.util.ArrayList;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class StockChart extends Application {

    private int companysNumber = 4;

    @Override public void start(Stage stage) {

        stage.setTitle("Stock Market");

        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();

        xAxis.setLabel("Time of Day");
        yAxis.setLabel("Price Per Stock");

        LineChart<String, Number> lineChart = new LineChart<String,Number>(xAxis,yAxis);

        ArrayList<CompanyStockData> companysLines = new ArrayList<CompanyStockData>();

        Scene scene  = new Scene(lineChart,800,600);

        scene.setOnMousePressed(new javafx.event.EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                companysLines.get(companysNumber).changeStock();
            }
        });

        lineChart.setTitle("Stock Exchange");

        String[] timeOfDay = {"8:00AM", "9:00AM", "10:00AM", "161:00AM", "12:00PM",
                                "1:00PM", "2:00PM", "3:00PM", "4:00PM" };
        String[] stockCompany = { "AAPL", "ORCL", "MSFT", "GOOG", "AMZN", "FB", "HPQ",
                                "YHOO", "ADSK", "ATVI"};

        for(int i = 0; i < stockCompany.length; i++) {
            companysLines.add(new CompanyStockData(lineChart, timeOfDay, stockCompany[i], i+3));
            lineChart.getData().add(companysLines.get(i).generateStock());
        }

        stage.setScene(scene);
        stage.show();
    }

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

CompanyStockData class

import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;

public class CompanyStockData {

    protected LineChart<String, Number> lineChart;
    protected String[] timeOfDay;
    protected String companyName;
    public XYChart.Series<String, Number> series = new XYChart.Series<String, Number>();

    private int yAddedValue;

    public CompanyStockData(LineChart<String, Number> lineChart, String[] timeOfDay, String companyName,
            int yAddedValue) {
        this.lineChart = lineChart;
        this.timeOfDay = timeOfDay;
        this.companyName = companyName;
        this.yAddedValue = yAddedValue;
    }

    public XYChart.Series<String, Number> generateStock() {
        series.setName(companyName);
        System.out.println(lineChart);

        for (int i = 0; i < timeOfDay.length; i++) {
            System.out.println(timeOfDay[i]);
            series.getData().add(new XYChart.Data<String, Number>(timeOfDay[i], i * 2 + yAddedValue));
        }

        return series;
    }

    public void changeStock() {
        yAddedValue++;
        series.getData().clear();
        for (int i = 0; i < timeOfDay.length; i++) {
            System.out.println(timeOfDay[i]);
            series.getData().add(new XYChart.Data<String, Number>(timeOfDay[i], i * 2 + yAddedValue));
        }
    }

}