José Aparecido
José Aparecido

Reputation: 9

Multiple lineChart series with JavaX and FXML

I'm trying to adapt a Chart model (lineChart) with JavaFX, at first based on this link model: https://docs.oracle.com/javafx/2/charts/line-chart.htm

My problem is showing the X-Axis values (Months in my case)

I've tried to make it more dynamic, based on these other links, but it still didn't work ... //JavaFX Adding multiple XYChart.Series to LineChart without explicating declaring each series //How to plot multiple series with javafx line chart which is in array list

Finally, based on this link, I was able to build a dynamic graph, which creates series to represent Month / Year of a collection movement: //Is it possible to create an array of XYChart.Series on JavaFX?

I have a "small" detail that I couldn't solve yet, the models are created "scene" directly, without XML, this way it works normal.

But I would like to create with XML (I am using the Scene Builder to assemble the XML), to put more details on the screen, such as a TableView, etc.

As I mentioned above, the problem is that when I use the graph with XML, it does not show the values of the X Axis (Months in my case) it is "all in one column" ...

I hope you managed to explain ... I will leave the example that trying to adapt here, any help, thank you in advance.

I'll leave the sample program (simpler, not the one that assembles dynamically, to try to illustrate better).

"Scene" call class

import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    public class LineChartExemplo extends Application {
        @Override
        public void start(Stage stage) throws Exception {
            Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

            Scene scene = new Scene(root);

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

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

FXML file

<?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.chart.CategoryAxis?>
    <?import javafx.scene.chart.LineChart?>
    <?import javafx.scene.chart.NumberAxis?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.AnchorPane?>

    <AnchorPane id="AnchorPane" prefHeight="579.0" prefWidth="918.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.171" fx:controller="linechartexemplo.FXMLDocumentController">
        <children>
            <Button fx:id="button" layoutX="14.0" layoutY="14.0" onAction="#handleButtonAction" text="Visualizar Gráfico" />
            <Label fx:id="label" layoutX="135.0" layoutY="14.0" minHeight="16" minWidth="69" prefHeight="25.0" prefWidth="710.0" />
          <LineChart fx:id="lineChart" layoutX="14.0" layoutY="52.0" prefHeight="512.0" prefWidth="887.0" title="Exemplo Gŕafico">
            <xAxis>
              <CategoryAxis side="BOTTOM" />
            </xAxis>
            <yAxis>
              <NumberAxis side="LEFT" />
            </yAxis>
          </LineChart>
        </children>
    </AnchorPane>

Controller class

import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.chart.CategoryAxis;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.control.Label;

    public class FXMLDocumentController implements Initializable {
        @FXML private Label label;

        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        //final LineChart<String,Number> lineChart = new LineChart<String,Number>(xAxis,yAxis);
        //@FXML private LineChart<String, Number> lineChart;
        @FXML private LineChart<String, Number> lineChart = new LineChart<String,Number>(xAxis,yAxis);


        @FXML
        private void handleButtonAction(ActionEvent event) {
            label.setText("Teste Gráfico...");
            visualizaGrafico();
        }

        @Override
        public void initialize(URL url, ResourceBundle rb) {

        }    

        private void visualizaGrafico(){
            lineChart.setTitle("Exemplo Gráfico");
            yAxis.setLabel("Valores");
            xAxis.setLabel("Meses");

            XYChart.Series series = new XYChart.Series();
            series.setName("Ano: 2018");
            series.getData().add(new XYChart.Data("Jan", 23));
            series.getData().add(new XYChart.Data("Feb", 14));
            series.getData().add(new XYChart.Data("Mar", 15));
            series.getData().add(new XYChart.Data("Apr", 24));
            series.getData().add(new XYChart.Data("May", 34));
            series.getData().add(new XYChart.Data("Jun", 36));
            series.getData().add(new XYChart.Data("Jul", 22));
            series.getData().add(new XYChart.Data("Aug", 45));
            series.getData().add(new XYChart.Data("Sep", 43));
            series.getData().add(new XYChart.Data("Oct", 17));
            series.getData().add(new XYChart.Data("Nov", 29));
            series.getData().add(new XYChart.Data("Dec", 25));

            XYChart.Series series2 = new XYChart.Series();
            series2.setName("Ano: 2019");
            series2.getData().add(new XYChart.Data("Jan", 28));
            series2.getData().add(new XYChart.Data("Feb", 17));
            series2.getData().add(new XYChart.Data("Mar", 19));
            series2.getData().add(new XYChart.Data("Apr", 14));
            series2.getData().add(new XYChart.Data("May", 20));
            series2.getData().add(new XYChart.Data("Jun", 42));
            series2.getData().add(new XYChart.Data("Jul", 27));
            series2.getData().add(new XYChart.Data("Aug", 48));
            series2.getData().add(new XYChart.Data("Sep", 47));
            series2.getData().add(new XYChart.Data("Oct", 19));
            series2.getData().add(new XYChart.Data("Nov", 39));
            series2.getData().add(new XYChart.Data("Dec", 29));

            lineChart.getData().addAll(series, series2);
        }
    }

Print the chart to better illustrate. enter image description here

Graph without using XML (OK with Database) enter image description here

Upvotes: 0

Views: 1656

Answers (2)

Jos&#233; Aparecido
Jos&#233; Aparecido

Reputation: 9

I'll put the solution code here, it can be useful for other people later.

I'm using SQL Server for Database (2012) and NetBeanas to develop ...

Class to start the scene

package graficos;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Graficos extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLGraficos.fxml"));

        Scene scene = new Scene(root);

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

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

FXMLGraficos File

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.chart.BarChart?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.chart.PieChart?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.effect.DropShadow?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="701.0" prefWidth="1407.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="graficos.FXMLGraficosController">
   <children>
      <AnchorPane layoutX="7.0" layoutY="152.0" prefHeight="254.0" prefWidth="361.0" style="-fx-background-color: #F5F5F5;">
         <children>
            <PieChart fx:id="pieChart" layoutX="7.0" prefHeight="254.0" prefWidth="355.0" title="Gráfico Movimento" />
         </children>
         <effect>
            <DropShadow />
         </effect>
      </AnchorPane>
      <AnchorPane layoutX="6.0" layoutY="14.0" prefHeight="131.0" prefWidth="363.0" style="-fx-background-color: #F5F5F5;">
         <effect>
            <DropShadow />
         </effect>
         <children>
            <DatePicker fx:id="dtpInicial" layoutX="5.0" layoutY="43.0" prefHeight="25.0" prefWidth="106.0" />
            <Label layoutX="5.0" layoutY="24.0" text="Data Inicial:" />
            <DatePicker fx:id="dtpFinal" layoutX="124.0" layoutY="43.0" prefHeight="25.0" prefWidth="106.0" />
            <Label layoutX="124.0" layoutY="24.0" text="Data Final:" />
            <Button fx:id="btnOK" layoutX="247.0" layoutY="43.0" mnemonicParsing="false" onAction="#verificaData" prefHeight="34.0" prefWidth="61.0" text="OK" />
            <Label fx:id="lblData" layoutX="12.0" layoutY="86.0" prefHeight="26.0" prefWidth="296.0" text="-" />
         </children>
      </AnchorPane>
      <AnchorPane layoutX="7.0" layoutY="417.0" prefHeight="271.0" prefWidth="363.0" style="-fx-background-color: #F5F5F5;">
         <effect>
            <DropShadow />
         </effect>
         <children>
            <BarChart fx:id="barChart" prefHeight="271.0" prefWidth="363.0" title="Gráfico Movimento">
              <xAxis>
                <CategoryAxis side="BOTTOM" />
              </xAxis>
              <yAxis>
                <NumberAxis side="LEFT" />
              </yAxis>
            </BarChart>
         </children>
      </AnchorPane>
      <AnchorPane layoutX="379.0" layoutY="153.0" prefHeight="535.0" prefWidth="975.0" style="-fx-background-color: #F5F5F5;">
         <effect>
            <DropShadow />
         </effect>
         <children>
            <LineChart fx:id="lineChart" layoutX="-2.0" prefHeight="535.0" prefWidth="968.0">
              <xAxis>
                <CategoryAxis side="BOTTOM" fx:id="xAxis" />
              </xAxis>
              <yAxis>
                <NumberAxis fx:id="yAxis" side="LEFT" />
              </yAxis>
            </LineChart>
         </children>
      </AnchorPane>
      <AnchorPane layoutX="379.0" layoutY="14.0" prefHeight="131.0" prefWidth="975.0" style="-fx-background-color: #F5F5F5;">
         <effect>
            <DropShadow />
         </effect>
         <children>
            <TableView prefHeight="131.0" prefWidth="975.0">
               <columns>
                  <TableColumn prefWidth="62.0" text="Janeiro" />
                  <TableColumn prefWidth="72.0" text="Fevereiro" />
                  <TableColumn prefWidth="79.0" text="Março" />
                  <TableColumn prefWidth="79.0" text="Abril" />
                  <TableColumn prefWidth="76.0" text="Maio" />
                  <TableColumn prefWidth="87.0" text="Junho" />
                  <TableColumn prefWidth="89.0" text="Julho" />
                  <TableColumn prefWidth="87.0" text="Agosto" />
                  <TableColumn prefWidth="83.0" text="Setembro" />
                  <TableColumn minWidth="0.0" prefWidth="81.0" text="Outubro" />
                  <TableColumn minWidth="0.0" prefWidth="79.0" text="Novembro" />
                  <TableColumn prefWidth="115.0" text="Dezembro" />
               </columns>
            </TableView>
         </children>
      </AnchorPane>
   </children>
</AnchorPane>

FXMLGraficosController class

package graficos;

import Utilitarios.ConexaoBD;
import java.net.URL;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.stream.Stream;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javax.swing.JOptionPane;

public class FXMLGraficosController implements Initializable {
    @FXML private DatePicker dtpInicial;
    @FXML private DatePicker dtpFinal;
    @FXML private Button btnOK;
    @FXML private PieChart pieChart;
    @FXML private BarChart<String, Double> barChart;
    @FXML private LineChart<String, Number> lineChart;
    @FXML private Label lblData;

    ObservableList<PieChart.Data> pieChartData;
    ObservableList<PieChart.Data> lineChartData;
    //ArrayList<Integer> cell = new ArrayList<Integer>();
    //ArrayList<String> name  = new ArrayList<String>();

    ConexaoBD connBD;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        connBD = new ConexaoBD();
        dtpInicial.setValue(LocalDate.now());
        dtpFinal.setValue(LocalDate.now());
    }    

    public void verificaData(javafx.event.ActionEvent event){
        //String sData = dtpInicial.getValue().format(DateTimeFormatter.ofPattern("yyyy-mm-dd"));
        java.sql.Date dDataIni = java.sql.Date.valueOf(dtpInicial.getValue());
        java.sql.Date dDataFim = java.sql.Date.valueOf(dtpFinal.getValue());

        String sDataIni = formataDataStr(dDataIni,1);
        String sDataFim = formataDataStr(dDataFim,1);

        lblData.setText("Período : " + sDataIni + " à " + sDataFim);

        graficoPizza(sDataIni, sDataFim);
        graficoLinhas(sDataIni, sDataFim);
    }

    public void graficoPizza(String sDataIni, String sDataFim){
        String strSQL = null;
        strSQL = " SELECT 'Boleto' AS Doacao, 'Valor' =  COUNT(*)" +
                 " FROM BOLETO B " +
                 " WHERE B.BOLDATAVEN BETWEEN '"+sDataIni+"' AND '"+sDataFim+"' ";

        strSQL = strSQL + " UNION ALL";
        strSQL = strSQL + " SELECT 'Recibo' AS Doacao, 'Valor' =  COUNT(*)" +
                          " FROM RECIBO R " +
                          " WHERE R.RECDATAVEN BETWEEN '"+sDataIni+"' AND '"+sDataFim+"' ";

        strSQL = strSQL + " UNION ALL";
        strSQL = strSQL + " SELECT 'Debito' AS Doacao, 'Valor' =  COUNT(*)" +
                          " FROM DEBITO D " +
                          " WHERE D.DEBDATAVEN BETWEEN '"+sDataIni+"' AND '"+sDataFim+"' ";

        pieChartData = FXCollections.observableArrayList();

        try {
            connBD.conectaBD();
        } catch (ClassNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao Conectar Banco de Dados - ERRO :" + ex.getMessage());
        }

        try {
            connBD.executaSQL(strSQL); //Conecta no Banco conforme Parametro passado
            if (connBD.rs.isBeforeFirst()){
                while (connBD.rs.next()){
                    pieChartData.add(new PieChart.Data(connBD.rs.getString("Doacao"), connBD.rs.getInt("Valor")));
                    //name.add(connBD.rs.getString("Doacao"));
                    //cell.add(connBD.rs.getInt("Valor"));
                    System.out.println(connBD.rs.getString("Doacao") + " - " +connBD.rs.getString("Valor"));
                }
            }

            pieChart.setData(pieChartData);

            connBD.desconectaBD();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao Carregar Dados para Alteração!\n" + ex.getMessage());
        }
    }

    public void graficoLinhas(String sDataIni, String sDataFim){
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis   = new NumberAxis();

        xAxis.setLabel("Meses");       
        yAxis.setLabel("Valores");  

        lineChart.getData().clear();
        ArrayList arrayAno = new ArrayList();

        String sSQL =  null;
        sSQL =   montaStrSQL(sDataIni, sDataFim);

        try {
            connBD.conectaBD();
        } catch (ClassNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao Conectar Banco de Dados - ERRO :" + ex.getMessage());
        }

        try {

            connBD.executaSQL(sSQL); //Conecta no Banco conforme Parametro passado
            if (connBD.rs.isBeforeFirst()){
                try {
                    connBD.rs.beforeFirst();
                    while (connBD.rs.next()){
                        if(!arrayAno.contains(connBD.rs.getString("Ano"))){
                            arrayAno.add(connBD.rs.getString("Ano"));
                            System.out.println(connBD.rs.getString("Ano"));
                        }
                    }
                    connBD.rs.beforeFirst();
                } catch (SQLException ex) {
                    JOptionPane.showMessageDialog(null, "Erro ao Carregar Dados para Alteração!\n" + ex.getMessage());
                }

                XYChart.Series<String, Number>[] seriesArray = Stream.<XYChart.Series<String, Number>>generate(XYChart.Series::new).limit(arrayAno.size()).toArray(XYChart.Series[]::new);

                for (int i = 0; i < arrayAno.size(); i++) {
                    try {
                        while (connBD.rs.next() && connBD.rs.getString("Ano").equals(arrayAno.get(i).toString())){
                            seriesArray[i].getData().add(new XYChart.Data(retornaMes(connBD.rs.getInt("Mes")), connBD.rs.getInt("Qtde")));
                            System.out.println(connBD.rs.getString("Ano") + " - " + connBD.rs.getString("Mes") + " - " + connBD.rs.getString("Qtde"));
                        }
                        seriesArray[i].setName("Ano: " + arrayAno.get(i).toString());
                        lineChart.getData().add(seriesArray[i]);

                        if (!connBD.rs.isLast())
                            connBD.rs.previous();

                    } catch (SQLException ex) {
                        JOptionPane.showMessageDialog(null, "Erro ao Carregar Dados para Alteração!\n" + ex.getMessage());
                    }
                }
            }
            connBD.desconectaBD();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao Carregar Dados para Alteração!\n" + ex.getMessage());
        }
    }

    private String montaStrSQL(String sDataI, String sDataF){
        String strSQL = null;
        strSQL = "SELECT ANO, MES, SUM(QTDE) AS QTDE FROM (";

        strSQL = strSQL + " SELECT 'Ano' = YEAR(B.BOLDATAVEN), 'Mes' = MONTH(B.BOLDATAVEN), 'Qtde' =  COUNT(*)" +
                          " FROM BOLETO B " +
                          " WHERE B.BOLDATAVEN BETWEEN '"+sDataI+"' AND '"+sDataF+"' ";

        strSQL = strSQL + " GROUP BY YEAR(B.BOLDATAVEN), MONTH(B.BOLDATAVEN)";
        strSQL = strSQL + " UNION ALL";

        strSQL = strSQL + " SELECT 'Ano' = YEAR(R.RECDATAVEN), 'Mes' = MONTH(R.RECDATAVEN), 'Qtde' =  COUNT(*)" +
                          " FROM RECIBO R " +
                          " WHERE R.RECDATAVEN BETWEEN '"+sDataI+"' AND '"+sDataF+"' ";

        strSQL = strSQL + " GROUP BY YEAR(R.RECDATAVEN), MONTH(R.RECDATAVEN)";
        strSQL = strSQL + " UNION ALL";
        strSQL = strSQL + " SELECT 'Ano' = YEAR(D.DEBDATAVEN), 'Mes' = MONTH(D.DEBDATAVEN), 'Qtde' =  COUNT(*)" +
                          " FROM DEBITO D " +
                          " WHERE D.DEBDATAVEN BETWEEN '"+sDataI+"' AND '"+sDataF+"' ";
        strSQL = strSQL + " GROUP BY YEAR(D.DEBDATAVEN), MONTH(D.DEBDATAVEN)";

        strSQL = strSQL + ")Resultado";
        strSQL = strSQL + " GROUP BY Resultado.ANO, Resultado.MES" ;
        strSQL = strSQL + " ORDER BY Resultado.ANO, Resultado.MES" ;

        return strSQL;
    }

    private String retornaMes(int iMes){
        String sMes = null;

        if (iMes == 1) sMes = "Jan";
        else if (iMes == 2) sMes  = "Fev";
        else if (iMes == 3) sMes  = "Mar";
        else if (iMes == 4) sMes  = "Abr";
        else if (iMes == 5) sMes  = "Mai";
        else if (iMes == 6) sMes  = "Jun";
        else if (iMes == 7) sMes  = "Jul";
        else if (iMes == 8) sMes  = "Ago";
        else if (iMes == 9) sMes  = "Set";
        else if (iMes == 10) sMes = "Out";
        else if (iMes == 11) sMes = "Nov";
        else if (iMes == 12) sMes = "Dez";

        return sMes;
    }

    public String formataDataStr(Date dData, int iOpc){
        if (dData != null){
          //JOptionPane.showMessageDialog(null, "Validando Data...");
          SimpleDateFormat sdf;

          switch (iOpc) {
            case 1:
              sdf = new SimpleDateFormat("yyyy-MM-dd");
              break;
            case 2:
              sdf = new SimpleDateFormat("dd-MM-yyyy");
              break;
            default:
              sdf = new SimpleDateFormat("dd/MM/yyyy");
              break;
          }

          String sDataFormat = sdf.format(dData);
          return sDataFormat;
        } else {
          //JOptionPane.showMessageDialog(null, "Retorno data vazio...");
          return "";
        }
    }
}

BD class

package Utilitarios;
import java.sql.*;
import javax.swing.JOptionPane;

public class ConexaoBD {
    public Connection conn = null;
    public Statement stm   = null;
    public ResultSet rs    = null;

    private final String driverDB = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; //Nome do Driver conforme o BD a ser utilizado
    private final String strDB    = "jdbc:sqlserver://"; //String para montar Url Banco
    private final String strIP    = "XXX.X.XX.XX";       //IP do Servidor
    private final String portaDB  = ":1433;";            //Porta  para montar Url Banco
    private String nomeDB         = "yourBD";            /Nome do Banco de Dados
    private String usuarioDB      = "youUSer";           //**
    private String senhaDB        = "yourPassword";      //**
    private String connectionUrl  = null;

    public void conectaBD() throws ClassNotFoundException{ //Inicia Construtor
        try {
            try {
                Class.forName(driverDB);
                connectionUrl = strDB + strIP + portaDB + "databaseName=" + nomeDB + ";user=" + usuarioDB + ";password=" + senhaDB;
                conn = DriverManager.getConnection(connectionUrl);
                stm  = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(null, "Erro ao Carregar Arquivo Configurações BD (ConexaoBD: conectaBD()):\n"+ex.getMessage());
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, "Erro Conexão BD - IP:\n"+ex.getMessage());
        }
    }

    public void desconectaBD(){
        try {
            conn.close();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao Desconectar Banco de Dados (ConexaoBD: desconectaBD())\n"+ex.getMessage());
        }
    }

    public void executaSQL(String strSQL){
        try {
            rs  = stm.executeQuery(strSQL);
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro na Execução SQL (ConexaoBD: executaSQL())\n Erro: "+ex.getMessage() );
        }
    }
}

And the print of the execution ... now I can continue with the part of filling in the tablewiews, etc ...

Thank you all! enter image description here

Upvotes: 0

James_D
James_D

Reputation: 209319

It looks like there is a bug somewhere that prevents this working properly when the chart is animated. Turn off animation in the chart with

@Override
public void initialize(URL url, ResourceBundle rb) {
    lineChart.setAnimated(false);
}  

There are additional issues with your code:

Never initialize fields annotated @FXML in your controller. The objects these fields are supposed to refer to are created according to the FXML code by the FXMLLoader, and are initialized in the controller by injection.

It's also unclear why you are creating a second set of axes in the controller, when you have already defined the axes in the FXML file.

Replace this code:

    final CategoryAxis xAxis = new CategoryAxis();
    final NumberAxis yAxis = new NumberAxis();
    @FXML private LineChart<String, Number> lineChart = new LineChart<String,Number>(xAxis,yAxis);

with

    @FXML private CategoryAxis xAxis ;
    @FXML private NumberAxis yAxis ;
    @FXML private LineChart<String, Number> lineChart ;

and add fx:ids to the axes in the FXML file so that they are properly injected into the controller:

      <LineChart fx:id="lineChart" layoutX="14.0" layoutY="52.0" prefHeight="512.0" prefWidth="887.0" title="Exemplo Gŕafico">
        <xAxis>
          <CategoryAxis fx:id="xAxis" side="BOTTOM" />
        </xAxis>
        <yAxis>
          <NumberAxis fx:id="yAxis" side="LEFT" />
        </yAxis>
      </LineChart>

Upvotes: 3

Related Questions