javafx.scene.chart (JavaFX 13)

Module javafx.controls

# Package javafx.scene.chart

The JavaFX User Interface provides a set of chart components that are a very convenient way for data visualization. Application developers can make use of these off-the-rack graphical charts provided by the JavaFX runtime, to visualize a wide variety of data.

Commom types of charts such as `Bar`, `Line`, `Area`, `Pie`, `Scatter` and `Bubble` charts are provided. These charts are easy to create and are customizable. JavaFX Charts API is a visual centric API rather than model centric.

JavaFX charts supports animation of chart components as well as auto ranging of chart Axis. In addition, as with other JavaFX UI controls, chart visual components can be styled via CSS. Thus, there are several public visual properties that can be styled via CSS. An example is provided later in the document.

Below is a table listing the existing Chart types and a brief summary of their intended use.

Table of Chart Types
Chart | Summary
--- | ---
`LineChart` | Plots line between the data points in a series. Used usually to view data trends over time.
`AreaChart` | Plots the area between the line that connects the data points and the axis. Good for comparing cumulated totals over time.
`BarChart` | Plots rectangular bars with heights indicating data values they represent, and corresponding to the categories they belongs to. Used for displaying discontinuous / discrete data
`PieChart` | Plots circular chart divided into segments with each segment representing a value as a proportion of the total. It looks like a Pie and hence the name
`BubbleChart` | Plots bubbles for data points in a series. Each plotted entity depicts three parameters in a 2D chart and hence a unique chart type.
`ScatterChart` | Plots symbols for the data points in a series. This type of chart is useful in viewing distribution of data and its corelation, if there is any clustering.

The `Chart` is the baseclass for all charts. It is responsible for drawing the background, frame, title and legend. It can be extended to create custom chart types. The `XYChart` is the baseclass for all two axis charts and it extends from Chart class. It is mostly responsible for drawing the two axis and the background of the chart plot. Most charts extend from XYChart class except for PieChart which extends from Chart class as it is not a two axis chart.

The `javafx.scene.chart` package includes axis classes that can be used when creating two axis charts. `Axis` is the abstract base class of all chart axis. `CategoryAxis` plots string categories where each value is a unique category along the axis. `NumberAxis` plots a range of numbers with major tick marks every tickUnit.

For Example BarChart plots data from a sequence of `XYChart.Series` objects. Each series contains `XYChart.Data` objects.

        // add data
        XYChart.Series<String,Number> series1 = new XYChart.Series<String,Number>();
        series1.setName("Data Series 1");
        series1.getData().add(new XYChart.Data<String,Number>("2007", 567));

We can define more series objects similarly. Following code snippet shows how to create a BarChart with 3 categories and its X and Y axis:

        static String[] years = {"2007", "2008", "2009"};
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChart<String,Number> bc = new BarChart<String,Number>(xAxis, yAxis);
        xAxis.setCategories(FXCollections.<String>observableArrayList(Arrays.asList(years)));
        bc.getData().addAll(series1, series2, series3);

JavaFX charts lends itself very well for real time or dynamic Charting (like online stocks, web traffic etc) from live data sets. Here is an example of a dynamic chart created with simulated data. A `Timeline` is used to simulate dynamic data for stock price variations over time(hours).

        private XYChart.Series<Number,Number> hourDataSeries;
        private NumberAxis xAxis;
        private Timeline animation;
        private double hours = 0;
        private double timeInHours = 0;
        private double prevY = 10;
        private double y = 10;

        // timeline to add new data every 60th of a second
        animation = new Timeline();
        animation.getKeyFrames().add(new KeyFrame(Duration.millis(1000 / 60), new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
                // 6 minutes data per frame
                for(int count = 0; count < 6; count++) {
                    nextTime();
                    plotTime();
                }
            }
        }));
        animation.setCycleCount(Animation.INDEFINITE);
        xAxis = new NumberAxis(0, 24, 3);
        final NumberAxis yAxis = new NumberAxis(0, 100, 10);
        final LineChart<Number,Number> lc = new LineChart<Number,Number>(xAxis, yAxis);

        lc.setCreateSymbols(false);
        lc.setAnimated(false);
        lc.setLegendVisible(false);
        lc.setTitle("ACME Company Stock");

        xAxis.setLabel("Time");
        xAxis.setForceZeroInRange(false);
        yAxis.setLabel("Share Price");
        yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis, "$", null));

        hourDataSeries = new XYChart.Series<Number,Number>();
        hourDataSeries.setName("Hourly Data");
        hourDataSeries.getData().add(new XYChart.Data<Number,Number>(timeInHours, prevY));
        lc.getData().add(hourDataSeries);

        private void nextTime() {
            if (minutes == 59) {
                hours++;
                minutes = 0;
            } else {
                minutes++;
            }
            timeInHours = hours + ((1d/60d) * minutes);
        }

        private void plotTime() {
            if ((timeInHours % 1) == 0) {
                // change of hour
                double oldY = y;
                y = prevY - 10 + (Math.random() * 20);
                prevY = oldY;
                while (y < 10 || y > 90) y = y - 10 + (Math.random() * 20);
                hourDataSeries.getData().add(new XYChart.Data<Number, Number>(timeInHours, prevY));
                // after 25hours delete old data
                if (timeInHours > 25) hourDataSeries.getData().remove(0);
                // every hour after 24 move range 1 hour
                if (timeInHours > 24) {
                    xAxis.setLowerBound(xAxis.getLowerBound() + 1);
                    xAxis.setUpperBound(xAxis.getUpperBound() + 1);
                }
            }
        }

The start method needs to call animation,.play() to start the simulated dynamic chart.

Please refer to javafx.scene.control package documentation on CSS styling. An example for styling a Chart via CSS is as follows:- to set the chart content background to a certain color:

.chart-content { -fx-background-color: cyan;}

Line Chart line color can be styled as follows:-

.chart-series-line { -fx-stroke: green; -fx-stroke-width: 4px;}

- Class Summary
  Class | Description
  --- | ---
  AreaChart<X,​Y> | AreaChart - Plots the area between the line that connects the data points and the 0 line on the Y axis.
  Axis<T> | Base class for all axes in JavaFX that represents an axis drawn on a chart area.
  Axis.TickMark<T> | TickMark represents the label text, its associated properties for each tick along the Axis.
  BarChart<X,​Y> | A chart that plots bars indicating data values for a category.
  BubbleChart<X,​Y> | Chart type that plots bubbles for the data points in a series.
  CategoryAxis | A axis implementation that will works on string categories where each value as a unique category(tick mark) along the axis.
  Chart | Base class for all charts.
  LineChart<X,​Y> | Line Chart plots a line connecting the data points in a series.
  NumberAxis | An axis class that plots a range of numbers with major tick marks every tickUnit.
  NumberAxis.DefaultFormatter | Default number formatter for NumberAxis, this stays in sync with auto-ranging and formats values appropriately.
  PieChart | Displays a PieChart.
  PieChart.Data | PieChart Data Item, represents one slice in the PieChart
  ScatterChart<X,​Y> | Chart type that plots symbols for the data points in a series.
  StackedAreaChart<X,​Y> | StackedAreaChart is a variation of `AreaChart` that displays trends of the contribution of each value.
  StackedBarChart<X,​Y> | StackedBarChart is a variation of `BarChart` that plots bars indicating data values for a category.
  ValueAxis<T extends Number> | An axis whose data is defined as Numbers.
  XYChart<X,​Y> | Chart base class for all 2 axis charts.
  XYChart.Data<X,​Y> | A single data item with data for 2 axis charts
  XYChart.Series<X,​Y> | A named series of data items

- Enum Summary
  Enum | Description
  --- | ---
  LineChart.SortingPolicy | This enum defines a policy for `LineChart.axisSortingPolicyProperty()`.