本文目录导读:

- 方案一:使用 JFreeChart(最经典、功能最全)
- 方案二:使用 JavaFX + 内置图表(现代化、交互流畅)
- 方案三:后端生成图表并返回给前端(Web应用场景)
- 方案四:导出为图片/SVG(生成报表场景)
- 总结:选择哪个方案?
在 Java 中实现数据可视化,通常不直接使用 Java 的图形库(如 Swing 或 JavaFX)从零开始绘制复杂的图表(虽然可以),而是更推荐使用成熟的第三方开源库,这些库封装了底层绘制逻辑,提供了丰富的图表类型(折线图、柱状图、饼图、散点图等),且配置简单。
以下是几种主流的实现方案,按推荐程度排序:
使用 JFreeChart(最经典、功能最全)
适用场景: 桌面应用(Swing)、Java EE 后端生成图片、学术图表、需要高度定制的复杂图表。
核心步骤:
-
添加依赖: (Maven)
<dependency> <groupId>org.jfree</groupId> <artifactId>jfreechart</artifactId> <version>1.5.3</version> </dependency> -
编写代码(创建折线图示例):
import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.category.DefaultCategoryDataset; import javax.swing.*; public class JFreeChartDemo { public static void main(String[] args) { // 1. 创建数据集 DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(120, "销售额", "一月"); dataset.addValue(150, "销售额", "二月"); dataset.addValue(180, "销售额", "三月"); dataset.addValue(160, "销售额", "四月"); // 2. 创建图表对象 (JFreeChart) JFreeChart chart = ChartFactory.createLineChart( "月度销售额趋势", // 图表标题 "月份", // X轴标签 "销售额 (万元)", // Y轴标签 dataset, // 数据集 PlotOrientation.VERTICAL, true, // 显示图例 true, // 显示工具提示 false // 生成URL ); // 3. 将图表放入 Swing 窗口 (ChartPanel 实现了 JPanel) ChartPanel chartPanel = new ChartPanel(chart); JFrame frame = new JFrame("JFreeChart Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(chartPanel); frame.pack(); frame.setVisible(true); } }
优点: 功能强大,支持几乎所有图表类型;文档丰富,案例多。 缺点: 界面风格有点“老派”;默认样式不够现代;不支持HTML5(需转为图片)。
使用 JavaFX + 内置图表(现代化、交互流畅)
适用场景: JavaFX 桌面应用程序、需要现代 UI 和流畅交互(缩放、动画)。
核心步骤:
-
项目设置: 确保项目支持 JavaFX(JDK 11+ 需要额外导入
javafx.controls和javafx.swing或使用启动器)。 -
编写 FXML 或纯代码(以纯代码为例):
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.stage.Stage; public class JavaFXChartDemo extends Application { @Override public void start(Stage stage) { // 1. 定义坐标轴 CategoryAxis xAxis = new CategoryAxis(); NumberAxis yAxis = new NumberAxis(); xAxis.setLabel("月份"); yAxis.setLabel("销售额 (万元)"); // 2. 创建折线图 LineChart<String, Number> lineChart = new LineChart<>(xAxis, yAxis); lineChart.setTitle("月度销售额趋势"); // 3. 创建数据系列 XYChart.Series<String, Number> series = new XYChart.Series<>(); series.setName("销售额"); series.getData().add(new XYChart.Data<>("一月", 120)); series.getData().add(new XYChart.Data<>("二月", 150)); series.getData().add(new XYChart.Data<>("三月", 180)); series.getData().add(new XYChart.Data<>("四月", 160)); // 4. 添加数据到图表 lineChart.getData().add(series); // 5. 显示 Scene scene = new Scene(lineChart, 800, 600); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
优点: 界面现代、高DPI支持好、支持CSS自定义皮肤、动画和交互(缩放、悬停提示)是内置的。 缺点: 只适用于 JavaFX 应用;学习曲线比 JFreeChart 稍高。
后端生成图表并返回给前端(Web应用场景)
适用场景: 后端(Spring Boot / Servlet)处理数据,前端(HTML/JS)展示。 这是目前企业级微服务架构下的主流选择!
推荐组合: Java 后端 + ECharts(百度)/ Highcharts / Chart.js
核心逻辑: Java 负责处理数据,然后通过 REST API 返回 JSON 格式 的数据,前端使用 JavaScript 库绘制图表。
Java 后端处理数据并返回 JSON(Spring Boot 示例):**
@RestController
public class ChartController {
@GetMapping("/api/sales")
public Map<String, Object> getSalesData() {
// 1. 从数据库或服务获取数据
List<String> categories = Arrays.asList("一月", "二月", "三月", "四月");
List<Integer> values = Arrays.asList(120, 150, 180, 160);
// 2. 构造 ECharts 需要的数据格式
Map<String, Object> result = new HashMap<>();
result.put("categories", categories);
result.put("values", values);
return result; // 自动序列化为 JSON
}
}
前端(HTML + ECharts)接收数据并绘制:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width: 600px;height:400px;"></div>
<script>
fetch('/api/sales') // 调用后端接口
.then(response => response.json())
.then(data => {
// 初始化 ECharts
var chart = echarts.init(document.getElementById('main'));
// 配置图表
chart.setOption({
title: { text: '月度销售额趋势' },
xAxis: { type: 'category', data: data.categories },
yAxis: { type: 'value' },
series: [{
data: data.values,
type: 'line' // 折线图
}]
});
});
</script>
</body>
</html>
优点:
- 前后端分离,架构清晰。
- 前端库(ECharts)功能极其强大,图表美观、交互丰富,支持大屏。
- 后端只负责纯粹的数据,无图表渲染压力。
缺点: 需要一定的前端知识。
导出为图片/SVG(生成报表场景)
适用场景: 生成 PDF/Word 报告、邮件附件中的图表图片。
方法: 使用 JFreeChart 或 Batik(SVG)生成图片流,然后输出给客户端。
// 假设已有 JFreeChart chart 对象
BufferedImage bufferedImage = chart.createBufferedImage(600, 400);
ImageIO.write(bufferedImage, "png", new File("chart.png"));
选择哪个方案?
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 桌面应用 (Swing) | JFreeChart | 稳定、简单、文档多。 |
| 桌面应用 (JavaFX) | JavaFX Charts | 界面现代,原生支持。 |
| Web 应用 / 大屏 / 微服务 | Java 后端 + ECharts (/Highcharts) | 最主流,性能好,UI 漂亮,前后端分离标准做法。 |
| 生成图片/报表 | JFreeChart 输出 BufferedImage | 纯后端处理,无需前端参与。 |
新手入门建议: 可以先从 方案三(Java后端 + ECharts) 学起,因为它符合当前企业级开发的主流趋势,ECharts 的配置非常直观,与 Java 配合良好的代价最低,如果做纯桌面开发,则首选 JFreeChart 或 JavaFX Charts。