java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > JavaFX图表组件实现数据可视化

Java使用JavaFX图表组件实现数据可视化的方法

作者:WL_Aurora

这段文章详细介绍了使用JavaFX绘制三种图表的方法,包括折线图、柱图和饼图的实战代码实现,并展示了如何在JavaFX中整合这些图表,示原始数据,需要的朋友可以参考下

一、最终效果预览

运行程序后,展示三种图表:折线图展示成绩趋势、柱状图对比各科分数、饼图展示成绩占比:

左侧折线图展示某学生五次考试的成绩变化趋势,右侧柱状图对比各科平均分,下方饼图展示成绩等级分布。

二、JavaFX Charts 概述

JavaFX 提供了丰富的图表组件,全部位于 javafx.scene.chart 包下:

图表类型类名适用场景
折线图LineChart展示数据随时间变化的趋势
柱状图BarChart对比不同类别的数据大小
饼图PieChart展示各部分占总体的比例
散点图ScatterChart展示两个变量之间的相关性
面积图AreaChart强调数量随时间变化的累积效果
气泡图BubbleChart三维数据的可视化

2.1 核心概念:XYChart.Series

所有 XY 轴图表(折线图、柱状图等)都使用 XYChart.Series 来组织数据:

XYChart.Series<String, Number> series = new XYChart.Series<>();
series.setName("系列名称");
series.getData().add(new XYChart.Data<>("X轴标签", 数值));

三、折线图(LineChart)实战

3.1 代码实现

import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;

// 创建坐标轴
NumberAxis xAxis = new NumberAxis(1, 5, 1);  // 起始、结束、步长
xAxis.setLabel("考试次数");
NumberAxis yAxis = new NumberAxis(0, 100, 10);
yAxis.setLabel("分数");

// 创建折线图
LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
lineChart.setTitle("成绩变化趋势");

// 创建数据系列
XYChart.Series<Number, Number> series = new XYChart.Series<>();
series.setName("数学成绩");
series.getData().add(new XYChart.Data<>(1, 65));
series.getData().add(new XYChart.Data<>(2, 72));
series.getData().add(new XYChart.Data<>(3, 85));
series.getData().add(new XYChart.Data<>(4, 90));
series.getData().add(new XYChart.Data<>(5, 95));

lineChart.getData().add(series);

四、柱状图(BarChart)实战

4.1 代码实现

import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;

// 创建坐标轴
CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("科目");
NumberAxis yAxis = new NumberAxis(0, 100, 10);
yAxis.setLabel("平均分");

// 创建柱状图
BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);
barChart.setTitle("各科成绩对比");

// 创建数据系列
XYChart.Series<String, Number> series = new XYChart.Series<>();
series.setName("期中考试");
series.getData().add(new XYChart.Data<>("语文", 88));
series.getData().add(new XYChart.Data<>("数学", 95));
series.getData().add(new XYChart.Data<>("英语", 82));
series.getData().add(new XYChart.Data<>("物理", 76));
series.getData().add(new XYChart.Data<>("化学", 91));

barChart.getData().add(series);

4.2 多系列柱状图

// 添加第二个系列进行对比
XYChart.Series<String, Number> series2 = new XYChart.Series<>();
series2.setName("期末考试");
series2.getData().add(new XYChart.Data<>("语文", 92));
series2.getData().add(new XYChart.Data<>("数学", 98));
series2.getData().add(new XYChart.Data<>("英语", 85));
series2.getData().add(new XYChart.Data<>("物理", 80));
series2.getData().add(new XYChart.Data<>("化学", 94));

barChart.getData().add(series2);

五、饼图(PieChart)实战

5.1 代码实现

import javafx.scene.chart.PieChart;

// 创建饼图
PieChart pieChart = new PieChart();
pieChart.setTitle("成绩等级分布");

// 添加数据
pieChart.getData().addAll(
    new PieChart.Data("优秀(90-100)", 35),
    new PieChart.Data("良好(80-89)", 30),
    new PieChart.Data("中等(70-79)", 20),
    new PieChart.Data("及格(60-69)", 10),
    new PieChart.Data("不及格(<60)", 5)
);

// 设置显示百分比
pieChart.setClockwise(true);
pieChart.setLabelLineLength(20);
pieChart.setLabelsVisible(true);

六、完整综合示例

将三种图表整合到一个界面中,并结合 TableView 展示原始数据:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ChartsDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        // ===== 1. 准备数据 =====
        ObservableList<Score> scores = FXCollections.observableArrayList(
            new Score("第一次", 65, 70, 60),
            new Score("第二次", 72, 75, 68),
            new Score("第三次", 85, 82, 78),
            new Score("第四次", 90, 88, 85),
            new Score("第五次", 95, 92, 90)
        );

        // ===== 2. 折线图 =====
        NumberAxis lineX = new NumberAxis(1, 5, 1);
        lineX.setLabel("考试次数");
        NumberAxis lineY = new NumberAxis(0, 100, 10);
        lineY.setLabel("分数");
        LineChart<Number, Number> lineChart = new LineChart<>(lineX, lineY);
        lineChart.setTitle("成绩变化趋势");
        lineChart.setPrefSize(400, 300);

        XYChart.Series<Number, Number> mathSeries = new XYChart.Series<>();
        mathSeries.setName("数学");
        XYChart.Series<Number, Number> englishSeries = new XYChart.Series<>();
        englishSeries.setName("英语");
        XYChart.Series<Number, Number> chineseSeries = new XYChart.Series<>();
        chineseSeries.setName("语文");

        for (int i = 0; i < scores.size(); i++) {
            Score s = scores.get(i);
            mathSeries.getData().add(new XYChart.Data<>(i + 1, s.getMath()));
            englishSeries.getData().add(new XYChart.Data<>(i + 1, s.getEnglish()));
            chineseSeries.getData().add(new XYChart.Data<>(i + 1, s.getChinese()));
        }
        lineChart.getData().addAll(mathSeries, englishSeries, chineseSeries);

        // ===== 3. 柱状图 =====
        CategoryAxis barX = new CategoryAxis();
        barX.setLabel("科目");
        NumberAxis barY = new NumberAxis(0, 100, 10);
        barY.setLabel("平均分");
        BarChart<String, Number> barChart = new BarChart<>(barX, barY);
        barChart.setTitle("各科平均分对比");
        barChart.setPrefSize(400, 300);

        double avgMath = scores.stream().mapToInt(Score::getMath).average().orElse(0);
        double avgEnglish = scores.stream().mapToInt(Score::getEnglish).average().orElse(0);
        double avgChinese = scores.stream().mapToInt(Score::getChinese).average().orElse(0);

        XYChart.Series<String, Number> avgSeries = new XYChart.Series<>();
        avgSeries.setName("平均分");
        avgSeries.getData().add(new XYChart.Data<>("数学", avgMath));
        avgSeries.getData().add(new XYChart.Data<>("英语", avgEnglish));
        avgSeries.getData().add(new XYChart.Data<>("语文", avgChinese));
        barChart.getData().add(avgSeries);

        // ===== 4. 饼图 =====
        PieChart pieChart = new PieChart();
        pieChart.setTitle("成绩等级分布");
        pieChart.setPrefSize(400, 300);
        pieChart.getData().addAll(
            new PieChart.Data("优秀(90+)", 8),
            new PieChart.Data("良好(80-89)", 4),
            new PieChart.Data("中等(70-79)", 2),
            new PieChart.Data("及格(60-69)", 1)
        );

        // ===== 5. TableView 展示原始数据 =====
        TableView<Score> tableView = new TableView<>(scores);
        tableView.setPrefHeight(200);

        TableColumn<Score, String> colExam = new TableColumn<>("考试");
        colExam.setCellValueFactory(new PropertyValueFactory<>("exam"));

        TableColumn<Score, Integer> colMath = new TableColumn<>("数学");
        colMath.setCellValueFactory(new PropertyValueFactory<>("math"));

        TableColumn<Score, Integer> colEnglish = new TableColumn<>("英语");
        colEnglish.setCellValueFactory(new PropertyValueFactory<>("english"));

        TableColumn<Score, Integer> colChinese = new TableColumn<>("语文");
        colChinese.setCellValueFactory(new PropertyValueFactory<>("chinese"));

        tableView.getColumns().addAll(colExam, colMath, colEnglish, colChinese);

        // ===== 6. 布局 =====
        HBox topBox = new HBox(20);
        topBox.getChildren().addAll(lineChart, barChart);

        HBox bottomBox = new HBox(20);
        bottomBox.getChildren().addAll(pieChart, tableView);

        VBox root = new VBox(20);
        root.setPadding(new Insets(20));
        root.getChildren().addAll(topBox, bottomBox);

        Scene scene = new Scene(root, 900, 700);
        primaryStage.setTitle("JavaFX 图表可视化");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // 数据模型
    public static class Score {
        private String exam;
        private int math;
        private int english;
        private int chinese;

        public Score(String exam, int math, int english, int chinese) {
            this.exam = exam;
            this.math = math;
            this.english = english;
            this.chinese = chinese;
        }

        public String getExam() { return exam; }
        public void setExam(String exam) { this.exam = exam; }
        public int getMath() { return math; }
        public void setMath(int math) { this.math = math; }
        public int getEnglish() { return english; }
        public void setEnglish(int english) { this.english = english; }
        public int getChinese() { return chinese; }
        public void setChinese(int chinese) { this.chinese = chinese; }
    }

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

七、常用 API 速查表

7.1 LineChart / BarChart

API说明
new LineChart<>(xAxis, yAxis)创建折线图
new BarChart<>(xAxis, yAxis)创建柱状图
series.setName("名称")设置系列名称(图例显示)
series.getData().add(new XYChart.Data<>(x, y))添加数据点
chart.getData().add(series)将系列添加到图表
chart.setAnimated(false)关闭动画效果

7.2 PieChart

API说明
new PieChart.Data("标签", 数值)创建饼图数据
pieChart.setLabelsVisible(true)显示标签
pieChart.setClockwise(true)顺时针排列
pieChart.setLabelLineLength(20)设置标签线长度

7.3 坐标轴

API说明
new NumberAxis(起始, 结束, 步长)创建数值轴
new CategoryAxis()创建分类轴(字符串)
axis.setLabel("标签")设置轴标签
axis.setAutoRanging(false)关闭自动范围

以上就是Java使用JavaFX图表组件实现数据可视化的方法的详细内容,更多关于JavaFX图表组件实现数据可视化的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文