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;}