Hướng dẫn sử dụng JavaFX BarChart và StackedBarChart
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- JavaFX BarChart

JavaFX BarChart sử dụng để vẽ ra một biểu đồ dạng thanh (bar chart), nó là một biểu đồ 2 chiều, có 2 trục tọa độ X và Y.  Trong đó một trục tọa độ biểu thị một nhóm đối tượng quan tâm, và một trục tọa độ biểu thị dữ liệu số.
Ví dụ: dữ liệu dưới đây mô tả độ thông dụng của một vài ngôn ngữ lập trình ứng với năm 2014 và 2015.
  2014 2015
Java 20.973% 26.983%
C# 4.429% 6.569%
PHP 2.792% 6.619%
Bạn có thể sử dụng BarChart để vẽ biểu đồ mô tả độ thông dụng của các ngôn ngữ lập trình với số liệu ở trên. Hãy xem hình minh họa dưới đây:
Trục X thể hiện các ngôn ngữ lập trình đang được quan tâm, trục Y là trục dữ liệu số, nó mô tả thị phần của các ngôn ngữ. Có 2 series, một cái thể hiện số liệu năm 2014, và một cái thể hiện số liệu năm 1015.

2- Ví dụ với BarChart

BarChartDemo.java
package org.o7planning.javafx.barchart;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BarChartDemo extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {

       CategoryAxis xAxis = new CategoryAxis();
       xAxis.setLabel("Programming Language");

       NumberAxis yAxis = new NumberAxis();
       yAxis.setLabel("Percent");

 
       // Tạo đối tượng BarChart
       BarChart<String, Number> barChart = new BarChart<String, Number>(xAxis, yAxis);

 
       // Series 1 - Số liệu năm 2014
       XYChart.Series<String, Number> dataSeries1 = new XYChart.Series<String, Number>();
       dataSeries1.setName("2014");

       dataSeries1.getData().add(new XYChart.Data<String, Number>("Java", 20.973));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("C#", 4.429));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("PHP", 2.792));

 
       // Series 2 - Số liệu năm 2015
       XYChart.Series<String, Number> dataSeries2 = new XYChart.Series<String, Number>();
       dataSeries2.setName("2015");

       dataSeries2.getData().add(new XYChart.Data<String, Number>("Java", 26.983));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("C#", 6.569));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("PHP", 6.619));
 
       // Thêm Series vào BarChart
       barChart.getData().add(dataSeries1);
       barChart.getData().add(dataSeries2);

       barChart.setTitle("Some Programming Languages");

       VBox vbox = new VBox(barChart);

       primaryStage.setTitle("JavaFX BarChart (o7planning.org)");
       Scene scene = new Scene(vbox, 400, 200);

       primaryStage.setScene(scene);
       primaryStage.setHeight(300);
       primaryStage.setWidth(400);

       primaryStage.show();
   }

   public static void main(String[] args) {
       Application.launch(args);
   }
}

3- Biểu đồ BarChart nằm ngang

Theo mặc định trục Y thường là trục mô tả dữ liệu số, còn trục X mô tả các đối tượng quan tâm. Trong trường hợp này BarChart là một biểu đồ thẳng đứng. Tuy nhiên bạn cũng có thể tạo một biểu đồ nằm ngang. Hãy xem ví dụ minh họa:
HorizontalBarChartDemo.java
package org.o7planning.javafx.barchart;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class HorizontalBarChartDemo extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {

       CategoryAxis xAxis = new CategoryAxis();
       xAxis.setLabel("Programming Language");

       NumberAxis yAxis = new NumberAxis();
       
       yAxis.setLabel("Percent");
 
       // Tạo đối tượng BarChart
       BarChart<Number, String> barChart = new BarChart<Number, String>(yAxis, xAxis);

 
       // Series 1 - Số liệu năm 2014
       XYChart.Series<Number, String> dataSeries1 = new XYChart.Series<Number, String>();
       dataSeries1.setName("2014");

       dataSeries1.getData().add(new XYChart.Data<Number, String>(20.973, "Java"));
       dataSeries1.getData().add(new XYChart.Data<Number, String>(4.429, "C#"));
       dataSeries1.getData().add(new XYChart.Data<Number, String>(2.792, "PHP"));

 
       // Series 2 - Số liệu năm 2015
       XYChart.Series<Number, String> dataSeries2 = new XYChart.Series<Number, String>();
       dataSeries2.setName("2015");

       dataSeries2.getData().add(new XYChart.Data<Number, String>(26.983, "Java"));
       dataSeries2.getData().add(new XYChart.Data<Number, String>(6.569, "C#"));
       dataSeries2.getData().add(new XYChart.Data<Number, String>(6.619, "PHP"));

 
       // Thêm Series vào BarChart
       barChart.getData().add(dataSeries1);
       barChart.getData().add(dataSeries2);

       barChart.setTitle("Some Programming Languages");

       VBox vbox = new VBox(barChart);

       primaryStage.setTitle("JavaFX BarChart (o7planning.org)");
       Scene scene = new Scene(vbox, 400, 200);

       primaryStage.setScene(scene);
       primaryStage.setHeight(300);
       primaryStage.setWidth(400);

       primaryStage.show();
   }

   public static void main(String[] args) {
       Application.launch(args);
   }
}

4- Tùy biến BarChart

// Hiển thị các thanh đánh (Tick Mark) dấu của trục X
xAxis.setTickMarkVisible(true);

// Xoay nhãn trên các thanh đánh dấu (Tick) đi 90 độ
xAxis.setTickLabelRotation(90);
// Sét mầu chữ
xAxis.setTickLabelFill(Color.RED);
// Sét Font
xAxis.setTickLabelFont( new Font("Arial", 15));

// Đặt Legend ở bên cạnh trái.
barChart.setLegendSide(Side.LEFT);

5- Quản lý hoạt hình khi dữ liệu thay đổi

Khi số liệu thay đổi, bạn có thể cập nhập để vẽ lại biểu đồ. JavaFX cho phép bạn tạo ra các hiệu ứng hoạt hình vẽ lại biểu đồ với dữ liệu mới.
// Thay đổi dữ liệu ngẫu nhiên sau mỗi 1 giây.
Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
   @Override
   public void handle(ActionEvent actionEvent) {
       for (XYChart.Series<String, Number> series : barChart.getData()) {
           for (XYChart.Data<String, Number> data : series.getData()) {
               Number yValue = data.getYValue();
               Number randomValue = yValue.doubleValue() * (0.5 + Math.random());
               data.setYValue(randomValue);
           }
       }
   }
}));
 
// Lặp vô thời hạn cho tới khi phương thức stop() được gọi.
timeline.setCycleCount(Animation.INDEFINITE);
timeline.setAutoReverse(true);
timeline.play();
Xem ví dụ đầy đủ:
AnimationBarChartDemo.java
package org.o7planning.javafx.barchart;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AnimationBarChartDemo extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {

       CategoryAxis xAxis = new CategoryAxis();
       xAxis.setLabel("Programming Language");

       NumberAxis yAxis = new NumberAxis();
       yAxis.setLabel("Percent");

 
       // Tạo đối tượng BarChart
       BarChart<String, Number> barChart = new BarChart<String, Number>(xAxis, yAxis);

 
       // Series 1 - Số liệu năm 2014
       XYChart.Series<String, Number> dataSeries1 = new XYChart.Series<String, Number>();
       dataSeries1.setName("2014");

       dataSeries1.getData().add(new XYChart.Data<String, Number>("Java", 20.973));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("C#", 4.429));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("PHP", 2.792));

 
       // Series 2 - Số liệu năm 2015
       XYChart.Series<String, Number> dataSeries2 = new XYChart.Series<String, Number>();
       dataSeries2.setName("2015");

       dataSeries2.getData().add(new XYChart.Data<String, Number>("Java", 26.983));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("C#", 6.569));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("PHP", 6.619));

 
       // Thêm Series vào BarChart
       barChart.getData().add(dataSeries1);
       barChart.getData().add(dataSeries2);

       barChart.setTitle("Some Programming Languages");

 
       // Thay đổi dữ liệu ngẫu nhiên sau mỗi 1 giây.
       Timeline timeline = new Timeline();
       timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
           @Override
           public void handle(ActionEvent actionEvent) {
               for (XYChart.Series<String, Number> series : barChart.getData()) {
                   for (XYChart.Data<String, Number> data : series.getData()) {
                       Number yValue = data.getYValue();
                       Number randomValue = yValue.doubleValue() * (0.5 + Math.random());
                       data.setYValue(randomValue);
                   }
               }
           }
       }));
 
       // Lặp vô thời hạn cho tới khi phương thức stop() được gọi.
       timeline.setCycleCount(Animation.INDEFINITE);
       timeline.setAutoReverse(true);
       timeline.play();

       VBox vbox = new VBox(barChart);

       primaryStage.setTitle("JavaFX BarChart (o7planning.org)");
       Scene scene = new Scene(vbox, 400, 200);

       primaryStage.setScene(scene);
       primaryStage.setHeight(300);
       primaryStage.setWidth(400);

       primaryStage.show();
   }

   public static void main(String[] args) {
       Application.launch(args);
   }
}

6- JavaFX StackedBarChart

Không có sự khác biệt về cách để tạo BarChartStackedBarChart. Khác biệt duy nhất là cách hiển thị dữ liệu. Với StackedBarChart các Series sẽ xếp chồng nên nhau.
StackedBarChartDemo.java
package org.o7planning.javafx.stackedbarchart;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class StackedBarChartDemo extends Application {

   @Override
   public void start(Stage primaryStage) throws Exception {

       CategoryAxis xAxis = new CategoryAxis();
       xAxis.setLabel("Programming Language");

       NumberAxis yAxis = new NumberAxis();
       yAxis.setLabel("Percent");

 
       // Tạo đối tượng StackedBarChart
       StackedBarChart<String, Number> barChart = new StackedBarChart<String, Number>(xAxis, yAxis);

 
       // Series 1 - Số liệu năm 2014
       XYChart.Series<String, Number> dataSeries1 = new XYChart.Series<String, Number>();
       dataSeries1.setName("2014");

       dataSeries1.getData().add(new XYChart.Data<String, Number>("Java", 20.973));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("C#", 4.429));
       dataSeries1.getData().add(new XYChart.Data<String, Number>("PHP", 2.792));

 
       // Series 2 - Số liệu năm 2015
       XYChart.Series<String, Number> dataSeries2 = new XYChart.Series<String, Number>();
       dataSeries2.setName("2015");

       dataSeries2.getData().add(new XYChart.Data<String, Number>("Java", 26.983));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("C#", 6.569));
       dataSeries2.getData().add(new XYChart.Data<String, Number>("PHP", 6.619));
 
       // Thêm Series vào StackedBarChart
       barChart.getData().add(dataSeries1);
       barChart.getData().add(dataSeries2);
     
       barChart.setTitle("Some Programming Languages");

       VBox vbox = new VBox(barChart);

       primaryStage.setTitle("JavaFX StackedBarChart (o7planning.org)");
       Scene scene = new Scene(vbox, 400, 200);

       primaryStage.setScene(scene);
       primaryStage.setHeight(300);
       primaryStage.setWidth(400);

       primaryStage.show();
   }

   public static void main(String[] args) {
       Application.launch(args);
   }
}

7- BarChart và sự kiện

Bạn có thể sử lý các sự kiện với biểu đồ, bao gồm cả BarChartStackedBarChart. Có một vài ví dụ với sử lý sự kiện với PieChart, và nó có thể áp dụng đối với BarChart, StackedBarChart, bạn có thể tham khảo thêm tại: