This discussion is archived
5 Replies Latest reply: Nov 7, 2012 12:14 PM by David Grieve RSS

Creating a table within the actual Chart

972913 Newbie
Currently Being Moderated
Hello i'm trying to create a connected table to my line chart.

The chart shows information for each day: Monday, tuesday, wednesday (ect ect).

Under each day (point) i want to show information for that day in a table.

is this possible ? and if so how?
  • 1. Re: Creating a table within the actual Chart
    jsmith Guru
    Currently Being Moderated
    Well FWIW, here's my attempt.
    The tables render strange and the CSS handling is unfathomable and spits out copious warnings when run (perhaps David Grieve knows why).
    But anyway, maybe it will help you.
    Or somebody else may have a better idea - perhaps using the node.lookupAll function on the Graph or some other means.
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.scene.*;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.chart.XYChart.Data;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.stage.Stage;
    
    public class LineChartWithTables extends Application {
      @Override public void start(Stage stage) {
        stage.setTitle("Line Chart Sample");
        //defining the axes
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Number of Month");
        //creating the chart
        final LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
    
        lineChart.setTitle("Stock Monitoring, 2010");
        //defining a series
        XYChart.Series series = new XYChart.Series();
        series.setName("My portfolio");
        //populating the series with data
        series.getData().add(createData(1, 23));
        series.getData().add(createData(2, 14));
        series.getData().add(createData(3, 15));
        series.getData().add(createData(4, 24));
        series.getData().add(createData(5, 34));
        series.getData().add(createData(6, 36));
        series.getData().add(createData(7, 22));
        series.getData().add(createData(8, 45));
        series.getData().add(createData(9, 43));
        series.getData().add(createData(10, 17));
        series.getData().add(createData(11, 29));
        series.getData().add(createData(12, 25));
    
        Scene scene = new Scene(lineChart, 800, 600);
        lineChart.getData().add(series);
    
        stage.setScene(scene);
        stage.show();
      }
    
      private Data createData(int x, int y) {
        Data data = new XYChart.Data(x, y);
        data.setNode(createTableView(data));
        
        return data;
      }
    
      private TableView createTableView(Data data) {
        TableView<Data> table = new TableView<>();
        TableColumn xCol = new TableColumn("X");
        xCol.setCellValueFactory(new PropertyValueFactory("XValue"));
        TableColumn yCol = new TableColumn("Y");
        yCol.setCellValueFactory(new PropertyValueFactory("YValue"));
        
        table.getColumns().setAll(xCol, yCol);
        table.setItems(FXCollections.observableArrayList(data));
        table.setStyle("-fx-skin: \"com.sun.javafx.scene.control.skin.TableViewSkin\"; -fx-background-color: #f9d900, aliceblue;"); // no idea why this line with the TableViewSkin is needed and it doesn't fix css issues with the table anyway. . .
        table.setPrefSize(65, 55);
    
        return table;
      }
      
      public static void main(String[] args) { launch(args); }
    }
  • 2. Re: Creating a table within the actual Chart
    972913 Newbie
    Currently Being Moderated
    First of all THANK you for your hard work however this wasnt exactly what i ment :)

    all i want is basicly the information displayed under the graph you know where it says "my portfolio" instead of having that simply have a table view that gives information!
  • 3. Re: Creating a table within the actual Chart
    David Grieve Pro
    Currently Being Moderated
    First of all, I think John's chart with tables a nodes is pretty cool. The reason the CSS errors are being logged and the reason he had to add the style with -fx-skin is that the node in the chart (the TableView) isn't part of the scene graph in the same way that other nodes are. Normally, if you followed the parent chain of a node in the scene, you'd get to a parent with a "root" style class. But the TableView in this code is not a descendant of the "root" node. Rather, it is an element in the ObservableList. A quick fix is to add the style "-fx-table-cell-border-color: aliceblue;" to the inline style on the TableView. Adding the style class "root" to the TableView should also work, but I didn't try that.

    Here's John's code again with a TableView below the chart. Notice that the chart and the TableView use the same data, which is what I think you are after.
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.*;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.chart.XYChart.Data;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
     
    public class Main extends Application {
        
      @Override public void start(Stage stage) {
        stage.setTitle("Line Chart Sample");
        //defining the axes
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Number of Month");
        //creating the chart
        final LineChart<Number, Number> lineChart = new LineChart(xAxis, yAxis);
     
        lineChart.setTitle("Stock Monitoring, 2010");
        //defining a series
        XYChart.Series series = new XYChart.Series();
        series.setName("My portfolio");
        //populating the series with data
        series.getData().add(createData(1, 23));
        series.getData().add(createData(2, 14));
        series.getData().add(createData(3, 15));
        series.getData().add(createData(4, 24));
        series.getData().add(createData(5, 34));
        series.getData().add(createData(6, 36));
        series.getData().add(createData(7, 22));
        series.getData().add(createData(8, 45));
        series.getData().add(createData(9, 43));
        series.getData().add(createData(10, 17));
        series.getData().add(createData(11, 29));
        series.getData().add(createData(12, 25));
     
        VBox vbox = new VBox(5);
        vbox.getChildren().addAll(lineChart, createTableView(series.getData()));
        
        Scene scene = new Scene(vbox, 800, 600);
    //    Scene scene = new Scene(lineChart, 800, 600);
        lineChart.getData().add(series);
     
        stage.setScene(scene);
        stage.show();
      }
     
      private Data createData(int x, int y) {
        Data data = new XYChart.Data(x, y);
    //    data.setNode(createTableView(data));
        
        return data;
      }
     
    //  private TableView createTableView(Data data) {
      private TableView createTableView(ObservableList data) {//Data data) {
        TableView<Data> table = new TableView();
        TableColumn xCol = new TableColumn("X");
        xCol.setCellValueFactory(new PropertyValueFactory("XValue"));
        TableColumn yCol = new TableColumn("Y");
        yCol.setCellValueFactory(new PropertyValueFactory("YValue"));
        
        table.getColumns().setAll(xCol, yCol);
    //    table.setItems(FXCollections.observableArrayList(data));
        table.setItems(data);
    //    table.setStyle("-fx-skin: \"com.sun.javafx.scene.control.skin.TableViewSkin\"; -fx-table-cell-border-color: aliceblue; -fx-background-color: #f9d900, aliceblue;"); // no idea why this line with the TableViewSkin is needed and it doesn't fix css issues with the table anyway. . .
    //    table.setPrefSize(65, 55);
     
        return table;
      }
    
      public static void main(String[] args) { launch(args); }
    }
  • 4. Re: Creating a table within the actual Chart
    jsmith Guru
    Currently Being Moderated
    Thanks for looking at my code and answering the poster's question David.
    I tried adding the root class to my sample and that didn't work.

    I don't think the issue is do with the tables not being part of a normal scene graph, instead it is because the LineGraph code at various times makes a setAll call on the symbol node's styleClass removing the default styleclass (of "table-view") from the TableView, including any pre-existing styles. Because the default styleclass contains the table-view's skin this causes warnings and rendering differences.

    After I added a style class ChangeListener to my createTableView code and ensured the table-view style was always present, everything rendered as I'd expect without any issue.
    private TableView createTableView(Data data) {
      final TableView<Data> table = new TableView<>();
      TableColumn xCol = new TableColumn("X");
      xCol.setCellValueFactory(new PropertyValueFactory("XValue"));
      TableColumn yCol = new TableColumn("Y");
      yCol.setCellValueFactory(new PropertyValueFactory("YValue"));
        
      table.getColumns().setAll(xCol, yCol);
      table.setItems(FXCollections.observableArrayList(data));
      table.getStyleClass().addListener(new ListChangeListener<String>() {
        @Override public void onChanged(Change<? extends String> c) {
          if (!table.getStyleClass().contains("table-view")) {
            table.getStyleClass().add("table-view");
          }
        }
      });
        
      table.setPrefSize(70, 70);
    
      return table;
    }
    As I don't think the LineChart code should remove the existing styles from the custom symbol nodes, I logged http://javafx-jira.kenai.com/browse/RT-26110 "LineChart removes existing styles from custom symbols"
  • 5. Re: Creating a table within the actual Chart
    David Grieve Pro
    Currently Being Moderated
    Excellent! Good find. Thanks for filing the bug.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points