Диаграммы: PieChart, BarChart и LineChart
Диаграммы в JavaFX — обычные узлы из пакета javafx.scene.chart, который входит в модуль javafx.controls. Их кладут в окно, как кнопку или таблицу, а данные передают списком. Подписи, легенду, цвета и даже анимацию при появлении JavaFX рисует сам. Сделаем для записной книжки окно «Статистика»: сколько заметок в каждой категории и сколько из них важных.
Окно статистики
Создайте класс со статическим методом, который строит и показывает окно. Первый вариант — круговая диаграмма PieChart с данными, записанными вручную:
// src/main/java/com/example/notes/StatsWindow.java — первый вариант
package com.example.notes;
import java.util.List;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.stage.Stage;
import javafx.stage.Window;
public class StatsWindow {
public static void show(Window owner, List<Note> notes) {
PieChart pie = new PieChart();
pie.setTitle("Заметки по категориям");
pie.getData().add(new PieChart.Data("Работа", 3));
pie.getData().add(new PieChart.Data("Дом", 5));
pie.getData().add(new PieChart.Data("Идеи", 2));
Stage stage = new Stage();
stage.setTitle("Статистика");
stage.initOwner(owner);
stage.setScene(new Scene(pie, 450, 400));
stage.show();
}
}PieChart.Data — один сектор: подпись и число. Размер сектора JavaFX считает сам как долю от суммы.
Кнопка в главном окне
В нижний ряд main-view.fxml после кнопки «Удалить» добавьте кнопку, а в контроллер — метод:
<!-- src/main/resources/com/example/notes/main-view.fxml — нижний ряд -->
<Button text="Статистика" onAction="#showStats"/>// src/main/java/com/example/notes/MainController.java — новый метод showStats()
@FXML
private void showStats() {
StatsWindow.show(table.getScene().getWindow(), notes);
}Нажмите «Статистика» — откроется окно с кругом из трёх секторов, подписями у каждого и легендой внизу. Секторы вырастают с короткой анимацией.
Данные из заметок
Заменим ручные числа подсчётом. Поток с groupingBy собирает карту «категория → число заметок»; TreeMap сортирует категории по алфавиту:
// src/main/java/com/example/notes/StatsWindow.java — начало метода show()
Map<String, Long> byCategory = notes.stream()
.collect(Collectors.groupingBy(Note::category, TreeMap::new, Collectors.counting()));
PieChart pie = new PieChart();
pie.setTitle("Заметки по категориям");
byCategory.forEach((category, count) ->
pie.getData().add(new PieChart.Data(category, count)));Теперь круг показывает реальные заметки: например, при трёх заметках «Дом», двух «Работа» и одной «Идеи» половину круга займёт «Дом». Окно считает данные в момент открытия — чтобы увидеть новые заметки, откройте его заново.
Столбцы и серии
BarChart и LineChart рисуют точки на двух осях. Для подписей по горизонтали берут CategoryAxis, для чисел — NumberAxis. Данные группируются в серии XYChart.Series: у каждой серии своё имя в легенде и свой цвет. Покажем рядом две серии — все заметки и важные:
// src/main/java/com/example/notes/StatsWindow.java — продолжение метода show()
CategoryAxis xAxis = new CategoryAxis();
long max = byCategory.values().stream().mapToLong(Long::longValue).max().orElse(0);
NumberAxis yAxis = new NumberAxis(0, max + 1, 1);
yAxis.setLabel("Заметок");
BarChart<String, Number> bar = new BarChart<>(xAxis, yAxis);
bar.setTitle("Все и важные");
XYChart.Series<String, Number> all = new XYChart.Series<>();
all.setName("Все");
XYChart.Series<String, Number> important = new XYChart.Series<>();
important.setName("Важные");
byCategory.forEach((category, count) -> {
long importantCount = notes.stream()
.filter(note -> note.category().equals(category) && note.important())
.count();
all.getData().add(new XYChart.Data<>(category, count));
important.getData().add(new XYChart.Data<>(category, importantCount));
});
bar.getData().add(all);
bar.getData().add(important);XYChart.Data — одна точка: значение по X и по Y. Конструктор NumberAxis(0, max + 1, 1) задаёт границы и шаг делений: заметки считаются целыми, а сама ось выбрала бы шаг 0,25. Сцену соберите из двух диаграмм — new Scene(new HBox(pie, bar), 900, 450) — и добавьте импорты BarChart, CategoryAxis, NumberAxis, XYChart, HBox, Map, TreeMap и Collectors. Слева будет круг, справа у каждой категории — два столбца, оранжевый и жёлтый.
LineChart
Линейная диаграмма принимает те же серии — достаточно поменять класс:
// src/main/java/com/example/notes/StatsWindow.java — вместо BarChart
LineChart<String, Number> line = new LineChart<>(xAxis, yAxis);Точки серии соединятся линией. Она подходит, когда по оси X идёт время: дни, месяцы. Одна серия может принадлежать только одной диаграмме — для двух диаграмм создают две серии.
| Класс | Что рисует |
|---|---|
PieChart | Доли целого |
BarChart | Столбцы по категориям |
LineChart | Линию через точки |
AreaChart | Линию с закрашенной областью под ней |
ScatterChart | Отдельные точки |
Частая ошибка
Для столбчатой диаграммы берут две числовые оси: new BarChart<>(new NumberAxis(), new NumberAxis()). Окно не открывается: java.lang.IllegalArgumentException: Axis type incorrect, one of X,Y should be CategoryAxis and the other NumberAxis. У BarChart одна ось обязательно CategoryAxis — с подписями, другая NumberAxis — с числами.