在JavaFX中创建统计图,主要依靠javafx.scene.chart包提供的丰富组件,通过这些组件,开发者可以轻松构建柱状图、折线图、饼图、散点图等多种类型的统计图表,满足数据可视化的不同需求,下面将从基础设置、常用图表类型实现、数据绑定及高级定制等方面,详细介绍JavaFX统计图的制作方法。

基础环境与图表容器
在开始绘制统计图前,需确保项目中已包含JavaFX库,以Maven项目为例,需在pom.xml中添加依赖:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17</version>
</dependency>
所有JavaFX图表都继承自Chart基类,使用时需先创建图表容器,创建一个柱状图:
BarChart<String, Number> barChart = new BarChart<>(new CategoryAxis(), new NumberAxis());
barChart.setTitle("销售数据统计");
barChart.setPrefSize(800, 600);
这里CategoryAxis用于分类轴(如月份),NumberAxis用于数值轴(如销售额),通过setPrefSize()可设置图表默认尺寸。
常用图表类型实现
柱状图(BarChart)
柱状图适用于分类数据的比较,需准备XYChart.Series数据系列,每个系列包含多个XYChart.Data数据点:
XYChart.Series<String, Number> series1 = new XYChart.Series<>();
series1.setName("产品A");
series1.getData().addAll(
new XYChart.Data<>("一月", 120),
new XYChart.Data<>("二月", 150),
new XYChart.Data<>("三月", 180)
);
XYChart.Series<String, Number> series2 = new XYChart.Series<>();
series2.setName("产品B");
series2.getData().addAll(
new XYChart.Data<>("一月", 90),
new XYChart.Data<>("二月", 110),
new XYChart.Data<>("三月", 140)
);
barChart.getData().addAll(series1, series2);
每个XYChart.Data对象对应一个柱形,series定义不同的数据系列(如不同产品)。
折线图(LineChart)
折线图适合展示数据趋势变化,其数据结构与柱状图类似,只需将BarChart替换为LineChart:
LineChart<String, Number> lineChart = new LineChart<>(new CategoryAxis(), new NumberAxis());
lineChart.setTitle("用户增长趋势");
XYChart.Series<String, Number> series = new XYChart.Series<>();
series.setName("新增用户");
series.getData().addAll(
new XYChart.Data<>("Q1", 500),
new XYChart.Data<>("Q2", 750),
new XYChart.Data<>("Q3", 1200),
new XYChart.Data<>("Q4", 1800)
);
lineChart.getData().add(series);
通过setCreateSymbols(true)可显示数据点标记,setStrokeWidth()可调整线条粗细。

饼图(PieChart)
饼图用于展示数据的占比关系,其数据结构相对简单,直接使用PieChart.Data:
PieChart pieChart = new PieChart();
pieChart.setTitle("市场份额分布");
pieChart.getData().addAll(
new PieChart.Data("公司A", 35),
new PieChart.Data("公司B", 25),
new PieChart.Data("公司C", 20),
new PieChart.Data("其他", 20)
);
可通过setLabelLineLength()设置标签线长度,setStartAngle()调整起始角度。
动态数据绑定与更新
实际应用中,数据往往需要动态更新,JavaFX支持通过ObservableList实现数据与图表的双向绑定:
ObservableList<XYChart.Data<String, Number>> data = FXCollections.observableArrayList();
data.addAll(
new XYChart.Data<>("一月", 100),
new XYChart.Data<>("二月", 200)
);
XYChart.Series<String, Number> series = new XYChart.Series<>();
series.setData(data);
barChart.getData().add(series);
// 动态更新数据
data.add(new XYChart.Data<>("三月", 150));
data.get(0).setYValue(120); // 修改第一个数据点的值
当ObservableList中的数据发生变化时,图表会自动刷新,无需手动重绘。
高级定制与交互
样式美化
通过CSS可对图表进行深度定制,修改柱状图颜色:
series1.getNode().setStyle("-fx-bar-fill: #ff6b6b;");
或外部CSS文件:
.chart-bar { -fx-bar-fill: #4ecdc4; }
.chart-series-line { -fx-stroke: #45b7d1; }
交互功能
JavaFX图表支持丰富的交互事件,如点击数据点获取详情:

pieChart.getData().forEach(data -> {
data.getNode().setOnMouseClicked(event -> {
System.out.println("名称: " + data.getName() + ", 数值: " + data.getPieValue());
});
});
还可通过Chart的setAnimated(true)启用动画效果,提升用户体验。
多坐标轴与复合图表
对于复杂数据,可使用NumberAxis的side属性设置双Y轴:
NumberAxis axisLeft = new NumberAxis("销售额", 0, 200, 50);
NumberAxis axisRight = new NumberAxis("利润率", 0, 100, 20);
axisRight.setSide(Side.RIGHT);
LineChart<String, Number> combinedChart = new LineChart<>(new CategoryAxis(), axisLeft);
combinedChart.getYAxis().setLabel("左侧Y轴");
combinedChart.getYAxis().setSide(Side.LEFT);
combinedChart.setSecondaryAxis(axisRight);
完整示例与最佳实践
以下是一个完整的柱状图示例,整合了上述关键功能:
public class ChartDemo extends Application {
@Override
public void start(Stage stage) {
CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);
barChart.setTitle("月度销售统计");
XYChart.Series<String, Number> series = new XYChart.Series<>();
series.setName("2023年");
ObservableList<XYChart.Data<String, Number>> data = FXCollections.observableArrayList(
new XYChart.Data<>("1月", 120),
new XYChart.Data<>("2月", 150),
new XYChart.Data<>("3月", 180)
);
series.setData(data);
barChart.getData().add(series);
series.getNode().setStyle("-fx-bar-fill: #ff9f43;");
Scene scene = new Scene(barChart, 800, 600);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
最佳实践建议:
- 数据与视图分离:使用
ObservableList管理数据,避免直接操作图表节点。 - 合理使用线程:大数据量更新时,通过
Platform.runAsync()避免阻塞UI线程。 - 国际化支持:通过
ResourceBundle管理图表标题、标签等文本内容。
通过以上方法,开发者可以高效构建功能完善、视觉美观的JavaFX统计图,满足各类数据可视化场景的需求。




















