This discussion is archived
5 Replies Latest reply: Feb 10, 2013 5:09 PM by James_D RSS

AreaChart, change the axis range

990250 Newbie
Currently Being Moderated
Hello, I'm new to Java FX, and I'm having some issues with Charts.

I will detail what I have done to see if it makes sense to work this way or not.

1) I create a javaFX aplication
2) I create a GUI with JavaFx Scene Builder.
3) this GUI contains an AreaChartNxN
4) I have a routine computing a data vector of 8760 values, (I want to plot the data in ranges of 24, i.e. data[0..24] or data[24..48] etc...)


Problem:
When I load a Serie<X,Y> where X goes from i.e. 1024 to 1048, the X axis of the AreaChart still has its origin in Zero, making the plot unusable (the Data sees too small)

So I google for the answer, an I find that, once created, a Chart cannot modify its Axis bounds (WTF??!! seriously?)

All the documentation explains is to create a new AreaChart in a new scene, by doing this, the boundaries are ok but the data serie does not appear.

What I Want:
I Want my plot in my UI with the boundaries in range.
I think, what I should do is to create a new AreaChart object every time, and somehow load it into my javaFX GUI, but I don't know how to do this. in Swing I used to load Plots in JPanels but in javaFX I don't know how to do it.

This is what I have for now:


+public void addSerie(AreaChart ac, XYChart.Series serie, String title, String xlabel, String ylabel, int xmin, int xmax) {+

ac.getXAxis().setAutoRanging(true);
ac.setTitle(title);
ac.getData().add(serie);
ac.getXAxis().setLabel(xlabel);
ac.getYAxis().setLabel(ylabel);

+}+

Any advice would be appreciated.
  • 1. Re: AreaChart, change the axis range
    James_D Guru
    Currently Being Moderated
    The NumberAxis (I assume you're using a number axis) has a bunch of methods that should help:
    yAxis.setForceZeroInRange(false);
    should do the trick, but if you need more control you can do
    yAxis.setAutoRange(false);
    yAxis.setLowerBound(...);
    yAxis.setUpperBound(...);
    I don't think you'd need to create a new chart every time, but even if you do it's not hard. The exact code depends on the Parent that contains the chart. Probably the easiest is if your chart sits in a BorderPane. Then all you'd need is something like
    borderPane.setCenter(newChart);
  • 2. Re: AreaChart, change the axis range
    bouye Journeyer
    Currently Being Moderated
    I have no issue changing the bounds by using setLowerBound() and setUpperBound() on the X axis event is 0 is not within bounds.
  • 3. Re: AreaChart, change the axis range
    James_D Guru
    Currently Being Moderated
    Sorry; I missed that the issue was on the x axis. Doesn't the code I posted work equally well for the x axis as the y axis?
  • 4. Re: AreaChart, change the axis range
    James_D Guru
    Currently Being Moderated
    import java.util.Random;
    
    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.chart.AreaChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart.Data;
    import javafx.scene.chart.XYChart.Series;
    import javafx.scene.control.Button;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    
    public class AreaChartTest extends Application {
    
      private int sequence = 0;
    
      @Override
      public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        final AreaChart<Number, Number> chart = new AreaChart<>(xAxis, yAxis);
        final Button button = new Button("Next series");
    
        xAxis.setForceZeroInRange(false);
        chart.setAnimated(false);
    
        button.setOnAction(new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            chart.getData().clear();
            chart.getData().add(createSeries());
          }
        });
    
        root.setCenter(chart);
        root.setBottom(button);
    
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
      }
    
      private Series<Number, Number> createSeries() {
        final Random rng = new Random();
        Series<Number, Number> series = new Series<>();
        sequence++;
        series.setName("Data " + sequence);
        for (int x = sequence * 24; x < (sequence + 1) * 24; x += 3) {
          series.getData().add(new Data<Number, Number>(x, rng.nextInt(80) + 10));
        }
        return series;
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    }
  • 5. Re: AreaChart, change the axis range
    James_D Guru
    Currently Being Moderated
    Another solution, perhaps closer to the exact problem you're seeking to solve:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    import javafx.application.Application;
    import javafx.beans.property.IntegerProperty;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.geometry.Orientation;
    import javafx.scene.Scene;
    import javafx.scene.chart.AreaChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart.Data;
    import javafx.scene.chart.XYChart.Series;
    import javafx.scene.control.Button;
    import javafx.scene.control.ScrollBar;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    
    public class AreaChartTest extends Application {
    
      @Override
      public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        final AreaChart<Number, Number> chart = new AreaChart<>(xAxis, yAxis);
    
        xAxis.setForceZeroInRange(false);
        chart.setAnimated(false);
    
        final Series<Number, Number> series = new Series<>();
        chart.getData().add(series);
    
        // build data:
        final List<Data<Number, Number>> allData = new ArrayList<Data<Number, Number>>();
        final Random rng = new Random();
        for (int x = 0; x < 8760; x++) {
          allData.add(new Data<Number, Number>(x, rng.nextInt(80)));
        }
    
        // Property for the index of the individual screens (each one is 24 data
        // points wide)
        final IntegerProperty chartPortionIndex = new SimpleIntegerProperty(-1);
        // Update data when this index changes
        chartPortionIndex.addListener(new ChangeListener<Number>() {
          @Override
          public void changed(ObservableValue<? extends Number> observable,
              Number oldValue, Number newValue) {
            series.setData(FXCollections.observableArrayList(allData.subList(
                newValue.intValue() * 24, newValue.intValue() * 24 + 23)));
            series.setName("Data section " + newValue);
          }
        });
    
        chartPortionIndex.set(0);
    
        // Scroller for scrolling through the data set
        ScrollBar scrollBar = new ScrollBar();
        scrollBar.setOrientation(Orientation.HORIZONTAL);
        scrollBar.setMin(0);
        scrollBar.setMax(8760 / 24 - 1);
        scrollBar.setUnitIncrement(1);
    
        // bind the index to the scroller value:
        chartPortionIndex.bind(scrollBar.valueProperty());
    
        root.setCenter(chart);
        root.setBottom(scrollBar);
    
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    }
    Edited by: James_D on Feb 10, 2013 5:09 PM (Changed UI to use scroll bar)

Legend

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