JavaFX AreaChart and StackedAreaChart Tutorial

1- JavaFX AreaChart

JavaFX AreaChart similar to line charts, it presents data as a series of points connected by straight lines. However, the area between the axis and the line is painted with color. Each series of data is painted with a different color.
For examle: the data below describes the monthly income in 2014 and 2015.
  2014 2015
1 400 2000
3 1000 1500
4 1500 1300
5 800 1200
7 500 1400
8 1800 1080
10 1500 2050
12 1300 2005
You can use AreaChart to draw the chart from the data above. Let's see the illustration below:
X-axis shows the months of the year, the Y axis represents your revenue.
Create X-axis includes 12 tick marks.
// NumberAxis(double lowerBound, double upperBound, double tickUnit) {
NumberAxis xAxis = new NumberAxis(1, 12, 1);

// Or
NumberAxis xAxis = new NumberAxis();

// Using methods:
xAxis.setLowerBound(1);
xAxis.setUpperBound(12);
xAxis.setTickUnit(1);

2- AreaChart example

AreaChartDemo.java
package org.o7planning.javafx.areachart;

import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class AreaChartDemo extends Application {

    @Override
    public void start(Stage stage) {

        final NumberAxis xAxis = new NumberAxis(1, 12, 1);
        final NumberAxis yAxis = new NumberAxis();
        final AreaChart<Number, Number> areaChart = new AreaChart<Number, Number>(xAxis, yAxis);
        areaChart.setTitle("Revenue");
        
        areaChart.setLegendSide(Side.LEFT);

        // Series data of 2014
        XYChart.Series<Number, Number> series2014 = new XYChart.Series<Number, Number>();

        
        series2014.setName("2014");
        
        
        series2014.getData().add(new XYChart.Data<Number, Number>(1, 400));
        series2014.getData().add(new XYChart.Data<Number, Number>(3, 1000));
        series2014.getData().add(new XYChart.Data<Number, Number>(4, 1500));
        series2014.getData().add(new XYChart.Data<Number, Number>(5, 800));
        series2014.getData().add(new XYChart.Data<Number, Number>(7, 500));
        series2014.getData().add(new XYChart.Data<Number, Number>(8, 1800));
        series2014.getData().add(new XYChart.Data<Number, Number>(10, 1500));
        series2014.getData().add(new XYChart.Data<Number, Number>(12, 1300));

        // Series data of 2015
        XYChart.Series<Number, Number> series2015 = new XYChart.Series<Number, Number>();
        series2015.setName("2015");
        series2015.getData().add(new XYChart.Data<Number, Number>(1, 2000));
        series2015.getData().add(new XYChart.Data<Number, Number>(3, 1500));
        series2015.getData().add(new XYChart.Data<Number, Number>(4, 1300));
        series2015.getData().add(new XYChart.Data<Number, Number>(5, 1200));
        series2015.getData().add(new XYChart.Data<Number, Number>(7, 1400));
        series2015.getData().add(new XYChart.Data<Number, Number>(8, 1080));
        series2015.getData().add(new XYChart.Data<Number, Number>(10, 2050));
        series2015.getData().add(new XYChart.Data<Number, Number>(12, 2005));

        stage.setTitle("AreaChart (o7planning.org)");
        Scene scene = new Scene(areaChart, 400, 300);
        areaChart.getData().addAll(series2014, series2015);
        stage.setScene(scene);
        stage.show();
    }

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

3- Customize BarChart

Sử dụng phương thức setCreateSymbols(false) để ẩn các Symbols
Using setCreateSymbols(false) method to hide Symbols
Using setOpacity(value) method to set opacity for chart, the parameter value can get value from 0 to 1.

4- Applying styles to BarChart

Create a style.css file located in the same package with your class.
style.css
.default-color0.chart-area-symbol { -fx-background-color: #e9967a, #ffa07a; }
.default-color1.chart-area-symbol { -fx-background-color: #dda0dd, #d8bfd855; }

.default-color0.chart-series-area-line { -fx-stroke: #e9967a; }
.default-color1.chart-series-area-line { -fx-stroke: #dda0dd; }

.default-color0.chart-series-area-fill { -fx-fill: #ffa07a55; }
.default-color1.chart-series-area-fill { -fx-fill: #d8bfd855; }
Using scene.getStylesheets().add(cssSource)  to add stylesheet file to the Scene.
// Add stylesheet to the Scene.
scene.getStylesheets().add("org/o7planning/javafx/areachart/style.css");
View full example:
CssAreaChartDemo.java
package org.o7planning.javafx.areachart;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

public class CssAreaChartDemo extends Application {

    @Override
    public void start(Stage stage) {

        final NumberAxis xAxis = new NumberAxis(1, 12, 1);
        final NumberAxis yAxis = new NumberAxis();
        final AreaChart<Number, Number> areaChart = new AreaChart<Number, Number>(xAxis, yAxis);
        areaChart.setTitle("Revenue");
     

        // Series data of 2014
        XYChart.Series<Number, Number> series2014 = new XYChart.Series<Number, Number>();

       
        series2014.setName("2014");
       
       
        series2014.getData().add(new XYChart.Data<Number, Number>(1, 400));
        series2014.getData().add(new XYChart.Data<Number, Number>(3, 1000));
        series2014.getData().add(new XYChart.Data<Number, Number>(4, 1500));
        series2014.getData().add(new XYChart.Data<Number, Number>(5, 800));
        series2014.getData().add(new XYChart.Data<Number, Number>(7, 500));
        series2014.getData().add(new XYChart.Data<Number, Number>(8, 1800));
        series2014.getData().add(new XYChart.Data<Number, Number>(10, 1500));
        series2014.getData().add(new XYChart.Data<Number, Number>(12, 1300));

        // Series data of 2015
        XYChart.Series<Number, Number> series2015 = new XYChart.Series<Number, Number>();
        series2015.setName("2015");
        series2015.getData().add(new XYChart.Data<Number, Number>(1, 2000));
        series2015.getData().add(new XYChart.Data<Number, Number>(3, 1500));
        series2015.getData().add(new XYChart.Data<Number, Number>(4, 1300));
        series2015.getData().add(new XYChart.Data<Number, Number>(5, 1200));
        series2015.getData().add(new XYChart.Data<Number, Number>(7, 1400));
        series2015.getData().add(new XYChart.Data<Number, Number>(8, 1080));
        series2015.getData().add(new XYChart.Data<Number, Number>(10, 2050));
        series2015.getData().add(new XYChart.Data<Number, Number>(12, 2005)); 
         

        stage.setTitle("AreaChart (o7planning.org)");
        Scene scene = new Scene(areaChart, 400, 300);
       
        // Add stylesheet to the Scene. .
        scene.getStylesheets().add("org/o7planning/javafx/areachart/style.css");
               
               
        areaChart.getData().addAll(series2014, series2015);
        stage.setScene(scene);
        stage.show();
    }

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

5- Manage animation when data changes

When data changes, you can update to redraw the chart. JavaFX allows you create animated effects redraw the chart with new data.
// Changing random data after every 1 second.
Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
   @Override
   public void handle(ActionEvent actionEvent) {
       for (XYChart.Series<Number, Number> series : areaChart.getData()) {
           for (XYChart.Data<Number, Number> data : series.getData()) {
               Number yValue = data.getYValue();
               Number randomValue = yValue.doubleValue() * (0.5 + Math.random());
               data.setYValue(randomValue);
           }
       }
   }
}));
// Repeat indefinitely until stop() method is called.
timeline.setCycleCount(Animation.INDEFINITE);
timeline.setAutoReverse(true);
timeline.play();
View full example:
AnimationAreaChartDemo.java
package org.o7planning.javafx.areachart;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
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;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AnimationAreaChartDemo extends Application {

   @Override
   public void start(Stage stage) {

       final NumberAxis xAxis = new NumberAxis(1, 12, 1);
       final NumberAxis yAxis = new NumberAxis();
       final AreaChart<Number, Number> areaChart = new AreaChart<Number, Number>(xAxis, yAxis);
       areaChart.setTitle("Revenue");

       // Series data of 2014
       XYChart.Series<Number, Number> series2014 = new XYChart.Series<Number, Number>();

       series2014.setName("2014");

       series2014.getData().add(new XYChart.Data<Number, Number>(1, 400));
       series2014.getData().add(new XYChart.Data<Number, Number>(3, 1000));
       series2014.getData().add(new XYChart.Data<Number, Number>(4, 1500));
       series2014.getData().add(new XYChart.Data<Number, Number>(5, 800));
       series2014.getData().add(new XYChart.Data<Number, Number>(7, 500));
       series2014.getData().add(new XYChart.Data<Number, Number>(8, 1800));
       series2014.getData().add(new XYChart.Data<Number, Number>(10, 1500));
       series2014.getData().add(new XYChart.Data<Number, Number>(12, 1300));

       // Series data of 2015
       XYChart.Series<Number, Number> series2015 = new XYChart.Series<Number, Number>();
       series2015.setName("2015");
       series2015.getData().add(new XYChart.Data<Number, Number>(1, 2000));
       series2015.getData().add(new XYChart.Data<Number, Number>(3, 1500));
       series2015.getData().add(new XYChart.Data<Number, Number>(4, 1300));
       series2015.getData().add(new XYChart.Data<Number, Number>(5, 1200));
       series2015.getData().add(new XYChart.Data<Number, Number>(7, 1400));
       series2015.getData().add(new XYChart.Data<Number, Number>(8, 1080));
       series2015.getData().add(new XYChart.Data<Number, Number>(10, 2050));
       series2015.getData().add(new XYChart.Data<Number, Number>(12, 2005));

       // Changing random data after every 1 second.
       Timeline timeline = new Timeline();
       timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent actionEvent) {
               for (XYChart.Series<Number, Number> series : areaChart.getData()) {
                   for (XYChart.Data<Number, Number> data : series.getData()) {
                       Number yValue = data.getYValue();
                       Number randomValue = yValue.doubleValue() * (0.5 + Math.random());
                       data.setYValue(randomValue);
                   }
               }
           }
       }));
       // Repeat indefinitely until stop() method is called.
       timeline.setCycleCount(Animation.INDEFINITE);
       timeline.setAutoReverse(true);
       timeline.play();

       stage.setTitle("AreaChart (o7planning.org)");
       Scene scene = new Scene(areaChart, 400, 300);
       areaChart.getData().addAll(series2014, series2015);
       stage.setScene(scene);
       stage.show();
   }

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

}

6- JavaFX StackedAreaChart

  • TODO

7- AreaChart and Events