36 棒グラフ
この章では、縦と横のどちらにもできる四角形の棒を使用した2軸チャートである、棒グラフについて説明します。
各棒の長さは、グラフが表す特定の値に比例します。通常、棒グラフは連続しないデータを表示するために使用されます。図36-1に示すように、棒のグループをカテゴリとして使用してデータを描画できます。
棒グラフの作成
JavaFXアプリケーションで棒グラフをビルドするには、2つの軸を作成し、BarChart
クラスをインスタンス化し、データの系列を定義し、データをグラフに割り当てます。例36-1では、5か国の財務情報を表すために3つのデータの系列を使用した棒グラフを作成しています。各国は、横軸上の棒のグループであるカテゴリとして表されます。
例36-1 データの系列が3つある棒グラフの作成
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.stage.Stage; public class BarChartSample extends Application { final static String austria = "Austria"; final static String brazil = "Brazil"; final static String france = "France"; final static String italy = "Italy"; final static String usa = "USA"; @Override public void start(Stage stage) { stage.setTitle("Bar Chart Sample"); final CategoryAxis xAxis = new CategoryAxis(); final NumberAxis yAxis = new NumberAxis(); final BarChart<String,Number> bc = new BarChart<>(xAxis,yAxis); bc.setTitle("Country Summary"); xAxis.setLabel("Country"); yAxis.setLabel("Value"); XYChart.Series series1 = new XYChart.Series(); series1.setName("2003"); series1.getData().add(new XYChart.Data(austria, 25601.34)); series1.getData().add(new XYChart.Data(brazil, 20148.82)); series1.getData().add(new XYChart.Data(france, 10000)); series1.getData().add(new XYChart.Data(italy, 35407.15)); series1.getData().add(new XYChart.Data(usa, 12000)); XYChart.Series series2 = new XYChart.Series(); series2.setName("2004"); series2.getData().add(new XYChart.Data(austria, 57401.85)); series2.getData().add(new XYChart.Data(brazil, 41941.19)); series2.getData().add(new XYChart.Data(france, 45263.37)); series2.getData().add(new XYChart.Data(italy, 117320.16)); series2.getData().add(new XYChart.Data(usa, 14845.27)); XYChart.Series series3 = new XYChart.Series(); series3.setName("2005"); series3.getData().add(new XYChart.Data(austria, 45000.65)); series3.getData().add(new XYChart.Data(brazil, 44835.76)); series3.getData().add(new XYChart.Data(france, 18722.18)); series3.getData().add(new XYChart.Data(italy, 17557.31)); series3.getData().add(new XYChart.Data(usa, 92633.68)); Scene scene = new Scene(bc,800,600); bc.getData().addAll(series1, series2, series3); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
図36-2に、このアプリケーションをコンパイルして実行したときに想定される出力を示します。
BarChart
クラスの2つのプロパティを使用して、データのカテゴリ間のスペースと、同じカテゴリ内の棒間のスペースを管理できます。barGap
およびcategoryGap
プロパティを使用すると、チャート描画内で棒をより適切に配置できます。例36-2では、setBarGap
およびsetCategoryGap
メソッドを使用して、これらのプロパティに特定の値を設定しています。
横棒グラフ
縦軸のカテゴリを定義することにより、棒グラフの方向を縦から横に変更できます。例36-3では、これを「Country Summary」アプリケーションに実装しています。NumberAxis
タイプの横軸とCategoryAxis
タイプの縦軸を宣言します。BarChart
オブジェクトの宣言を必ず変更してください。
例36-3 棒グラフの方向の変更
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.stage.Stage; public class BarChartSample extends Application { final static String austria = "Austria"; final static String brazil = "Brazil"; final static String france = "France"; final static String italy = "Italy"; final static String usa = "USA"; @Override public void start(Stage stage) { stage.setTitle("Bar Chart Sample"); final NumberAxis xAxis = new NumberAxis(); final CategoryAxis yAxis = new CategoryAxis(); final BarChart<Number,String> bc = new BarChart<>(xAxis,yAxis); bc.setTitle("Country Summary"); xAxis.setLabel("Value"); xAxis.setTickLabelRotation(90); yAxis.setLabel("Country"); XYChart.Series series1 = new XYChart.Series(); series1.setName("2003"); series1.getData().add(new XYChart.Data(25601.34, austria)); series1.getData().add(new XYChart.Data(20148.82, brazil)); series1.getData().add(new XYChart.Data(10000, france)); series1.getData().add(new XYChart.Data(35407.15, italy)); series1.getData().add(new XYChart.Data(12000, usa)); XYChart.Series series2 = new XYChart.Series(); series2.setName("2004"); series2.getData().add(new XYChart.Data(57401.85, austria)); series2.getData().add(new XYChart.Data(41941.19, brazil)); series2.getData().add(new XYChart.Data(45263.37, france)); series2.getData().add(new XYChart.Data(117320.16, italy)); series2.getData().add(new XYChart.Data(14845.27, usa)); XYChart.Series series3 = new XYChart.Series(); series3.setName("2005"); series3.getData().add(new XYChart.Data(45000.65, austria)); series3.getData().add(new XYChart.Data(44835.76, brazil)); series3.getData().add(new XYChart.Data(18722.18, france)); series3.getData().add(new XYChart.Data(17557.31, italy)); series3.getData().add(new XYChart.Data(92633.68, usa)); Scene scene = new Scene(bc,800,600); bc.getData().addAll(series1, series2, series3); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
ラベルを回転し、値のキャプションを読みやすくするために、横軸に対してsetTickLabelRotation
メソッドがコールされていることに注意してください。
変更したアプリケーションをコンパイルして実行した結果を図36-3に示します。
横棒グラフは、ランク付けされたリストとしてデータを表す場合に特に役に立ちます。
積上げ棒グラフの作成
カテゴリ内の棒が積み上げられるように棒グラフ内のデータを表すことができます。例36-4に示すように、JavaFX APIに用意されているStackedBarChart
クラスを使用します。
例36-4 積上げ棒グラフの作成
import java.util.Arrays; import javafx.application.Application; import javafx.collections.FXCollections; 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.stage.Stage; public class StackedBarChartSample extends Application { final static String austria = "Austria"; final static String brazil = "Brazil"; final static String france = "France"; final static String italy = "Italy"; final static String usa = "USA"; final CategoryAxis xAxis = new CategoryAxis(); final NumberAxis yAxis = new NumberAxis(); final StackedBarChart<String, Number> sbc = new StackedBarChart<>(xAxis, yAxis); final XYChart.Series<String, Number> series1 = new XYChart.Series<>(); final XYChart.Series<String, Number> series2 = new XYChart.Series<>(); final XYChart.Series<String, Number> series3 = new XYChart.Series<>(); @Override public void start(Stage stage) { stage.setTitle("Bar Chart Sample"); sbc.setTitle("Country Summary"); xAxis.setLabel("Country"); xAxis.setCategories(FXCollections.<String>observableArrayList( Arrays.asList(austria, brazil, france, italy, usa))); yAxis.setLabel("Value"); series1.setName("2003"); series1.getData().add(new XYChart.Data<>(austria, 25601.34)); series1.getData().add(new XYChart.Data<>(brazil, 20148.82)); series1.getData().add(new XYChart.Data<>(france, 10000)); series1.getData().add(new XYChart.Data<>(italy, 35407.15)); series1.getData().add(new XYChart.Data<>(usa, 12000)); series2.setName("2004"); series2.getData().add(new XYChart.Data<>(austria, 57401.85)); series2.getData().add(new XYChart.Data<>(brazil, 41941.19)); series2.getData().add(new XYChart.Data<>(france, 45263.37)); series2.getData().add(new XYChart.Data<>(italy, 117320.16)); series2.getData().add(new XYChart.Data<>(usa, 14845.27)); series3.setName("2005"); series3.getData().add(new XYChart.Data<>(austria, 45000.65)); series3.getData().add(new XYChart.Data<>(brazil, 44835.76)); series3.getData().add(new XYChart.Data<>(france, 18722.18)); series3.getData().add(new XYChart.Data<>(italy, 17557.31)); series3.getData().add(new XYChart.Data<>(usa, 92633.68)); Scene scene = new Scene(sbc, 800, 600); sbc.getData().addAll(series1, series2, series3); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
アプリケーションで積上げ棒グラフの軸を定義する場合、データのカテゴリを特定の軸に明示的に割り当てる必要があります。例36-4では、setCategories
メソッドを使用してカテゴリが横軸に割り当てられています。このアプリケーションによって生成された棒グラフを図36-4に示します。
図36-3に示すデータを図36-4の同じデータと比較してください。積上げ棒グラフ内の面では、横軸上の任意の点において縦軸の値が累積して表示されます。たとえば、図36-4の縦軸では、Austriaの2004年の値は約25,000から約85,000の範囲に収まっています。ただし、例36-4のデータは2004年のAustriaの値は57,401.85であることを示しています。図36-4の2004年の約85,000という高い値は、2003年と2004年のAustriaの累積結果を表します。
JavaFXアプリケーションで棒グラフを開発する場合、縦軸のデータはBarChart
とStackedBarChart
では異なる方法で解釈されることに注意してください。アプリケーションのタスクを最も適切に表すグラフのタイプを選択してください。
setCategoryGap
メソッドに値を設定することにより、積上げカテゴリ間の距離を指定できます。たとえば、sbc.setCategoryGap(50);
のように、「Country Summary」棒グラフで距離を50ピクセルに設定できます。
グラフのデータのアニメーション化
財務活動の動的な動きを表すためにアニメーション化したグラフを実装できます。例36-5では、アニメーションの時系列を定義し、キー・フレームを作成することにより、棒グラフのデータのX値をランダムに設定しています。時系列は、アプリケーションが起動すると開始され、オートリバース・モードで無期限に続行されます。
例36-5 棒グラフのデータのアニメーション化
Timeline tl = new Timeline(); tl.getKeyFrames().add(new KeyFrame(Duration.millis(500), (ActionEvent actionEvent) -> { bc.getData().stream().forEach((series) -> { series.getData().stream().forEach((data) -> { data.setXValue(Math.random() * 1000); }); }); } )); tl.setCycleCount(Animation.INDEFINITE); tl.setAutoReverse(true); tl.play();
このコード・フラグメントを例36-3の「Country Summary」アプリケーションに追加し、変更したコードをコンパイルして実行すると、範囲内の新しい値や棒の新しい長さに対応して軸とチャート描画の両方がなめらかに変化します。これは、Chart
およびAxis
クラスのanimated
プロパティによるものです。デフォルトでは、データの変更をアニメーション化するようにこれらはtrue
に設定されています。
「Country Summary」アプリケーションでは、縦軸のデータがカテゴリ内にあり、変更されない場合は、縦軸のデータのアニメーション化を禁止できます。国ラベルの不要なちらつきが発生しないようにするには、例36-6に示すように、setAnimated
メソッドを使用します。
JavaFXグラフの機能の詳細は、APIドキュメントを参照してください。
関連APIドキュメント