ZetCode

JavaFX 图表

最后修改于 2023 年 10 月 18 日

在本 JavaFX 教程中,我们将使用图表。 在 JavaFX 中,只需添加几行代码即可构建图表。

在下面的示例中,我们创建一个折线图、一个面积图、一个散点图、一个柱状图和一个饼图。

JavaFX 折线图

折线图是一种基本类型的图表,它将信息显示为由直线段连接的一系列数据点。 JavaFX 中的折线图使用 javafx.scene.chart.LineChart 创建。

com/zetcode/LineChartEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;


public class LineChartEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        var root = new HBox();

        var scene = new Scene(root, 450, 330);

        var xAxis = new NumberAxis();
        xAxis.setLabel("Age");

        var yAxis = new NumberAxis();
        yAxis.setLabel("Salary (€)");

        var lineChart = new LineChart<>(xAxis, yAxis);
        lineChart.setTitle("Average salary per age");

        var data = new XYChart.Series<Number, Number>();
        data.setName("2016");

        data.getData().add(new XYChart.Data<>(18, 567));
        data.getData().add(new XYChart.Data<>(20, 612));
        data.getData().add(new XYChart.Data<>(25, 800));
        data.getData().add(new XYChart.Data<>(30, 980));
        data.getData().add(new XYChart.Data<>(40, 1410));
        data.getData().add(new XYChart.Data<>(50, 2350));

        lineChart.getData().add(data);

        root.getChildren().add(lineChart);

        stage.setTitle("LineChart");
        stage.setScene(scene);
        stage.show();
    }

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

在这个例子中,我们有一个显示每一年龄段平均工资的折线图。

var xAxis = new NumberAxis();
xAxis.setLabel("Age");

var yAxis = new NumberAxis();
yAxis.setLabel("Salary (€)");

使用 NumberAxis 创建两个轴。 setLabel 方法为轴设置描述。

var lineChart = new LineChart<>(xAxis, yAxis);
lineChart.setTitle("Average salary per age");

LineChart 创建一个折线图。 setTitle 方法为图表设置标题。

var data = new XYChart.Series<Number, Number>();
data.setName("2016");

XYChart.Series 为图表提供数据系列。 数据系列是数据点列表。 每个数据点包含一个 x 值和一个 y 值。 setName 方法给一个系列命名。(一个图表中可能有多个系列。)

data.getData().add(new XYChart.Data<>(18, 567));
data.getData().add(new XYChart.Data<>(20, 612));
...

我们将数据添加到数据系列中。 XYChart.Data 是一个包含 2 轴图表数据的单个数据项。

lineChart.getData().add(data);

数据被插入到图表中。

LineChart
图:折线图

JavaFX 面积图

面积图以图形方式显示随时间变化的数据。

com/zetcode/AreaChartEx.java
package com.zetcode;

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


public class AreaChartEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        var root = new HBox();
        var scene = new Scene(root, 490, 350);

        var xAxis = new CategoryAxis();
        xAxis.setLabel("Time");

        var yAxis = new NumberAxis();
        yAxis.setLabel("Thousand bbl/d");

        var areaChart = new AreaChart<>(xAxis, yAxis);
        areaChart.setTitle("Oil consumption");

        var data = new XYChart.Series<String, Number>();

        data.getData().add(new XYChart.Data<>("2004", 82502));
        data.getData().add(new XYChart.Data<>("2005", 84026));
        data.getData().add(new XYChart.Data<>("2006", 85007));
        data.getData().add(new XYChart.Data<>("2007", 86216));
        data.getData().add(new XYChart.Data<>("2008", 85559));
        data.getData().add(new XYChart.Data<>("2009", 84491));
        data.getData().add(new XYChart.Data<>("2010", 87672));
        data.getData().add(new XYChart.Data<>("2011", 88575));
        data.getData().add(new XYChart.Data<>("2012", 89837));
        data.getData().add(new XYChart.Data<>("2013", 90701));

        areaChart.getData().add(data);
        areaChart.setLegendVisible(false);

        root.getChildren().add(areaChart);

        stage.setTitle("AreaChart");
        stage.setScene(scene);
        stage.show();
    }

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

本例展示了一个显示世界原油年消耗量的面积图。

var areaChart = new AreaChart<>(xAxis, yAxis);
areaChart.setTitle("Oil consumption");

使用 AreaChart 创建一个面积图。

var xAxis = new CategoryAxis();
xAxis.setLabel("Time");

CategoryAxis 适用于字符串类别。 我们在这个轴上显示年份字符串。

AreaChart
图:面积图

JavaFX 散点图

散点图是在水平轴和垂直轴上绘制的一组点。

com/zetcode/ScatterChartEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;


public class ScatterChartEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        var root = new HBox();

        var xAxis = new CategoryAxis();
        var yAxis = new NumberAxis("USD/kg", 30, 50, 2);

        var scatterChart = new ScatterChart<>(xAxis, yAxis);

        var data = new XYChart.Series<String, Number>();

        data.getData().add(new XYChart.Data<>("Mar 14", 43));
        data.getData().add(new XYChart.Data<>("Nov 14", 38.5));
        data.getData().add(new XYChart.Data<>("Jan 15", 41.8));
        data.getData().add(new XYChart.Data<>("Mar 15", 37));
        data.getData().add(new XYChart.Data<>("Dec 15", 33.7));
        data.getData().add(new XYChart.Data<>("Feb 16", 39.8));

        scatterChart.getData().add(data);
        scatterChart.setLegendVisible(false);

        var scene = new Scene(root, 450, 330);
        root.getChildren().add(scatterChart);

        stage.setTitle("Gold price");
        stage.setScene(scene);
        stage.show();
    }

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

在本例中,我们使用 ScatterChart 来显示金价。

var xAxis = new CategoryAxis();

x 轴是 CategoryAxis,用于显示日期。

var yAxis = new NumberAxis("USD/kg", 30, 50, 2);

y 轴是 NumberAxis,用于显示金价。 构造函数的参数是:轴标签、下限、上限和刻度单位。

var data = new XYChart.Series<String, Number>();

data.getData().add(new XYChart.Data<>("Mar 14", 43));
...

使用 XYChart.Series 创建一系列数据,并使用 XYChart.Data 创建其数据项。

ScatterChart
图:散点图

JavaFX 柱状图

条形图使用矩形条呈现分组数据,条的长度与它们表示的值成比例。 这些条可以垂直或水平绘制。

com/zetcode/BarChartEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;


public class BarChartEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        var root = new HBox();

        var scene = new Scene(root, 480, 330);
        var xAxis = new CategoryAxis();

        var yAxis = new NumberAxis();
        yAxis.setLabel("Gold medals");

        var barChart = new BarChart<>(xAxis, yAxis);
        barChart.setTitle("Olympic gold medals in London");

        var data = new XYChart.Series<String, Number>();

        data.getData().add(new XYChart.Data<>("USA", 46));
        data.getData().add(new XYChart.Data<>("China", 38));
        data.getData().add(new XYChart.Data<>("UK", 29));
        data.getData().add(new XYChart.Data<>("Russia", 22));
        data.getData().add(new XYChart.Data<>("South Korea", 13));
        data.getData().add(new XYChart.Data<>("Germany", 11));

        barChart.getData().add(data);
        barChart.setLegendVisible(false);

        root.getChildren().add(barChart);

        stage.setTitle("BarChart");
        stage.setScene(scene);
        stage.show();

    }

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

在本例中,我们使用柱状图来显示 2012 年伦敦奥运会上每个国家的奥运金牌数量。

var barChart = new BarChart(xAxis, yAxis);

使用 BarChart 创建一个柱状图。

AreaChart
图:面积图

JavaFX 饼图

饼图是一个圆形图表,被分成切片以说明数值比例。

com/zetcode/PieChartEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;


public class PieChartEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        var root = new HBox();

        var scene = new Scene(root, 450, 330);

        ObservableList<PieChart.Data> pieChartData
                = FXCollections.observableArrayList(
                new PieChart.Data("Apache", 52),
                new PieChart.Data("Nginx", 31),
                new PieChart.Data("IIS", 12),
                new PieChart.Data("LiteSpeed", 2),
                new PieChart.Data("Google server", 1),
                new PieChart.Data("Others", 2));

        var pieChart = new PieChart(pieChartData);
        pieChart.setTitle("Web servers market share (2016)");

        root.getChildren().add(pieChart);

        stage.setTitle("PieChart");
        stage.setScene(scene);
        stage.show();
    }

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

本例使用饼图来显示 Web 服务器的市场份额。

ObservableList<PieChart.Data> pieChartData
        = FXCollections.observableArrayList(
                new PieChart.Data("Apache", 52),
                new PieChart.Data("Nginx", 31),
                new PieChart.Data("IIS", 12),
                new PieChart.Data("LiteSpeed", 2),
                new PieChart.Data("Google server", 1),
                new PieChart.Data("Others", 2));

饼图数据项使用 PieChart.Data 创建。

var pieChart = new PieChart(pieChartData);

使用 PieChart 类创建一个饼图。

PieChart
图:饼图

在本章中,我们创建了一个 LineChart、一个 AreaChart、一个 ScatterChart、一个 BarChart 和一个 PieChartJFreechart 教程 展示了如何在流行的 JFreechart 库中创建图表。