Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
JavaFX.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
4.88 Mб
Скачать

3.3.2 Створення графіків

За допомогою JavaFx можна наглядно представити дані за допомогою графіків. Існує шість видів графіків, але будуть розглянуті три найчастіше використовувані види, це: pie chart, line chart, bar chart.

Отже спочатку потрібно створити клас ChartView в новому пакеті chart:

public class ChartView extends BorderPane{

private static final Random random = new Random();

private final HBox hbox = new HBox();

private final XYChart.Series<Number, Number> series1 = new XYChart.Series<Number, Number>();

private final XYChart.Series<Number, Number> series2 = new XYChart.Series<Number, Number>();

private final StackPane chartWrapper = new StackPane();

private final Button nextBut = new Button("Next value");

private final ToggleGroup group = new ToggleGroup();

public ChartView(){}

}

random — буде допомогати генерувати нові значення для LineChart.

hbox — буде містити кнопки для переключення між графіками.

series1, series2 — це безпосередньо лінії графіку LineChart. Вони винесені в поля класу через те, що буде створений обробник подій, який буде додавати до них нові значення, а із обробників подій можна звертатися тільки до елементів з модифікатором final.

chartWrapper — буде містити в собі графіки.

nextBut — кнопка для генерації нових значень графіку LineChart.

ToggleGroup group — група кнопок-перемикачів графіків.

Спочатку потрібно зробити перемикачі графіків. Для цього в конструкторі потрібно ввести наступні рядки коду:

final ToggleButton lineBut = new ToggleButton("Line chart");

lineBut.setToggleGroup(group);

final ToggleButton pieBut = new ToggleButton("Pie chart");

pieBut.setToggleGroup(group);

final ToggleButton barBut = new ToggleButton("Bar chart");

barBut.setToggleGroup(group);

lineBut.setUserData(getLineChart());

pieBut.setUserData(getPieChart());

barBut.setUserData(getBarChart());

setUserData — дозволяє «покласти» у перемикач будь-який об’єкт. Методи getLineChart(), getPieChart(), getBarChart() повертають відповідні графіки. Тепер потрібно написати логіку роботи перемикання:

group.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){

public void changed(ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle) {

if (new_toggle == null){

chartWrapper.getChildren().clear();

nextBut.setDisable(true);

} else {

chartWrapper.getChildren().clear();

if (group.getSelectedToggle().equals(lineBut))

nextBut.setDisable(false);

else

nextBut.setDisable(true);

chartWrapper.getChildren().add((Chart)group.getSelectedToggle().getUserData());

}

}

});

Якщо всі перемикачі вимкнені, то область графіків буде очищатися. В іншому випадку у chartWrapper із перемикача дістається відповідний графік. Як можна побачити, можливість зберігати об’єкти в перемикачі (також ця можливість існує і у деяких інших класів) є дуже корисною, адже не потрібно писати багато коду. Через те що nextBut використовується тільки у LineChart, то також потрібно регулювати те, щоб вона буле активна чи неактивна.

В конструкторі залишилося тепер дописати обробник подій для генерації нових значень і розмістити всі об’єкти. Це зроблять наступні рядки коду:

nextBut.setOnAction(new EventHandler<ActionEvent>(){

@Override public void handle(ActionEvent e){

series1.getData().add(ChartView.getNextPoint(series1.getData().size()));

series2.getData().add(ChartView.getNextPoint(series2.getData().size()));

}

});

hbox.setAlignment(Pos.CENTER);

hbox.getChildren().addAll(lineBut, pieBut, barBut, nextBut);

lineBut.fire();

this.setBottom(hbox);

this.setCenter(chartWrapper);

Тепер потрібно розробити всі нереалізовані методи, які використовуються у конструкторі. Першим з методів буде getNextPoint:

public static XYChart.Data<Number, Number> getNextPoint(int i){

return new XYChart.Data<Number, Number>(10*i+5, random.nextDouble() * 100);

}

По осі Х буде плавний рівномірний зсув, а по осі Y випадковий, від 0 до 100.

Другим з методів буде getLineChart():

public LineChart<Number, Number> getLineChart(){

nextBut.setDisable(false);

final NumberAxis xAxis = new NumberAxis();

final NumberAxis yAxis = new NumberAxis();

LineChart<Number, Number> chart = new LineChart<Number, Number>(xAxis, yAxis);

chart.setTitle("Random values");

xAxis.setLabel("X Axis");

yAxis.setLabel("Y Axis");

series1.getData().clear();

series2.getData().clear();

series1.setName("Random Data 1");

for (int i = 0; i < 10; i++) {

series1.getData().add(getNextPoint(i));

}

series2.setName("Random Data 2");

for (int i = 0; i < 10; i++) {

series2.getData().add(getNextPoint(i));

}

chart.getData().addAll(series1, series2);

return chart;

}

Якщо на нереалізовані методи поставити заглушки, то можна запустити додаток і подивитися на перший графік із трьох (рис. 3.24). При натисканні на кнопку «Next value» можна побачити анімаційну зміну графіку.

Третім з методів буде getPieChart():

public PieChart getPieChart(){

nextBut.setDisable(true);

ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList();

GenericDAO<UserFx> userManager = new GenericDAO(UserFx.class);

List<UserFx> list = userManager.getAll();

Map<String, Integer> map = new HashMap();

List<PieChart.Data> datalist = new ArrayList();

UserFx ufx;

for (int i=0; i<list.size(); i++){

ufx = (UserFx)list.get(i);

if (map.containsKey(ufx.getCity())){

map.put(ufx.getCity(), map.get(ufx.getCity())+1);

} else {

map.put(ufx.getCity(), 1);

}

}

for (Entry<String,Integer> entry : map.entrySet()){

if (entry.getKey().equals(""))

pieChartData.add(new PieChart.Data("Unknown", entry.getValue()));

else

pieChartData.add(new PieChart.Data(entry.getKey(), entry.getValue()));

}

final PieChart chart = new PieChart(pieChartData);

chart.setTitle("User's cities");

return chart;

}

Рис. 3.24. Line chart із випадково згенерованими даними

На відміну від попереднього графіку, дані для цього виду графіку беруться із бази даних. Графік відображає співвідношення кількості користувачів у містах. Отже, додавши декілька нових користувачів через раніш розроблений інструмент адміністрування, можна побачити такий результат (рис. 3.25):

Рис. 3.25. Pie chart, який відображає відношення користувачів у містах

Останнім буде getBarChart ():

public BarChart getBarChart(){

nextBut.setDisable(true);

final String china = "China";

final String india = "India";

final String usa = "USA";

final String indonesia = "Indonesia";

final String brasil = "Brasil";

final String russia = "Russia";

final CategoryAxis xAxis = new CategoryAxis();

final NumberAxis yAxis = new NumberAxis();

final BarChart<String,Number> bc =

new BarChart<String,Number>(xAxis,yAxis);

bc.setTitle("Demography forecasts of the UN");

xAxis.setLabel("Country");

yAxis.setLabel("People(M)");

XYChart.Series series1 = new XYChart.Series();

series1.setName("2004");

series1.getData().add(new XYChart.Data(china, 1308.0));

series1.getData().add(new XYChart.Data(india, 1087,0));

series1.getData().add(new XYChart.Data(usa, 295,4));

series1.getData().add(new XYChart.Data(indonesia, 220,1));

series1.getData().add(new XYChart.Data(brasil, 183,9));

series1.getData().add(new XYChart.Data(russia, 143,9));

XYChart.Series series2 = new XYChart.Series();

series2.setName("2015");

series2.getData().add(new XYChart.Data(china, 1393,0));

series2.getData().add(new XYChart.Data(india, 1260,0));

series2.getData().add(new XYChart.Data(usa, 325,7));

series2.getData().add(new XYChart.Data(indonesia, 246,8));

series2.getData().add(new XYChart.Data(brasil, 209,4));

series2.getData().add(new XYChart.Data(russia, 136,7));

bc.getData().addAll(series1, series2);

return bc;

}

Цей графік відображає значення популяції в країнах за 2004 рік і прогнози ООН відносно цих країн на 2015 рік (рис. 3.26).

Рис. 3.26. Bar chart, який відображає популяційні прогнози ООН