Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Диаграммы: 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 — с числами.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.