JavaFX のチャートを使いこなせるようになりたいと、ずいぶん前に LineChart のサンプルを示しました [1]。その時には、横軸にカテゴリの軸を使って整数値の年を文字列に変換して表示しましたが、今回は DateAxis クラスを使って、日付として軸を設定してみます。
使用した環境は以下の通りです。開発版の NetBeans IDE で JDK 9 を使用できることを確認したので、経験を積むためにも Java 9 を積極的に使っていきたいと考えています。
- OS: Fedora 27 beta (x86_64)
- Java: jdk-9.0.1-9.0.1-ga.x86_64 (Oracle)
- IDE: NetBeans IDE Dev (Build 201710270002) [2]
LineChartSample8.java
DateAxis は JavaFX 標準で用意されているクラスではありません。何人かの方が Axis クラスを継承して DataAxis クラスを作成して公開されていますが、ここでは Christian Schudt 氏および Diego Cirujano 氏が著作者 (author) になっているソースを使用させていただきました [3]。
プロジェクトは、前述した以前のサンプル [1] の構成と同じですが、プロジェクト内に上記 DateAxis.java を加えています[左図参照]。
それぞれのソースを紹介したいのですが、長くなってしまいますので、ここではメインの LineChartSample8.java だけ紹介します。すべてのソースは GitHub [4] にありますので、そこからクローンして下さい。
package linechartsample8; import java.util.Calendar; import java.util.Date; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart.Series; import javafx.stage.Stage; public class LineChartSample8 extends Application { @Override public void start(Stage stage) { stage.setTitle("Line Chart Sample (8)"); //defining the axes DateAxis xAxis = new DateAxis(); NumberAxis yAxis = new NumberAxis(); xAxis.setLabel("X軸ラベル(年)"); yAxis.setLabel("Y軸ラベル(数値)"); //creating the chart LineChart<Date, Number> lineChart = new LineChart<>(xAxis, yAxis); lineChart.setData(getChartData()); lineChart.setTitle("折れ線グラフのサンプル"); Scene scene = new Scene(lineChart, 800, 400); String ClassName = getClass().getSimpleName(); scene.getStylesheets().add(getClass().getResource(ClassName + ".css").toExternalForm()); stage.setScene(scene); stage.show(); } private ObservableList<XYChart.Series<Date, Number>> getChartData() { double y1 = 0.1; double y2 = -0.1; Series<Date, Number> series1 = new Series<>(); Series<Date, Number> series2 = new Series<>(); series1.setName("系列1"); series2.setName("系列2"); for (int i = 2011; i < 2021; i++) { series1.getData().add(new XYChart.Data<>(getYear(i), y1)); y1 = y1 + Math.random() - .5; series2.getData().add(new XYChart.Data<>(getYear(i), y2)); y2 = y2 + Math.random() - .5; } ObservableList<XYChart.Series<Date, Number>> seriesList = FXCollections.observableArrayList(); seriesList.add(series1); seriesList.add(series2); return seriesList; } private Date getYear(int i) { Calendar calendar = Calendar.getInstance(); calendar.set(i, 0, 1, 0, 0); return calendar.getTime(); } public static void main(String[] args) { launch(args); } }
コンパイルオプション
DateAxis.java のインポート宣言で、パッケージ com.sun.javafx.charts はモジュール javafx.controls で宣言されていますが、エクスポートされていません
というメッセージでエラーになっています。このエラーは、Java 8 では見られなかったものです。
これは Java 9 でモジュールシステムを導入したことにより、パッケージレベルでのカプセル化が可能になったため、JDK の内部 API を使用するとコンパイル エラーにすることが可能になったためのようです。このエラーの解決には代替機能を探すことが推奨されていますが、一時的にこの強力なカプセル化を壊す方法がコンパイラのオプションに --add-exports として追加されています [5][6]。今回は、これを利用します。
--add-exports javafx.controls/com.sun.javafx.charts=ALL-UNNAMED
NetBeans IDE で、このプロジェクトの「プロジェクト・プロパティ」ダイアログを表示させ、「コンパイル」画面の「追加コンパイラ・オプション(L):」のエントリに上記オプションを追加します。これでコンパイルが通るようになります。
実行例を以下に示します。
このサンプルでは、一見、前回の実行例と違いがないように見えますが、Date 型という「数値」で軸を作っていますので、ウィンドウのサイズを変えると目盛り間隔が調整されます。日付を軸に使いたいときは日付に対応した軸を使ったほうが当然便利なのです。日付(通常は、日や時間単位の間隔)を横軸にしてデータのトレンドをプロットするニーズが多いので重宝しています。
参考サイト
- bitWalk's: JavaFX: LineChart を使いこなそう (2)
- NetBeans IDE ダウンロード
- sco0ter / ExtFX / source / src / main / java / extfx / scene / chart / DateAxis.java — Bitbucket
- bitwalk123/LineChartSample8
- ヌーラボのアカウント基盤を Java 9 にマイグレーションして起きた問題と解決法 | ヌーラボ
- Java Platform, Standard Edition Oracle JDK 9 Migration Guide, Release 9
にほんブログ村