プロジェクト

全般

プロフィール

JavaFXとグラフ(Chart)

見栄えの制御

Chartでは、見栄えを変更するにはたいていはCSSを記述します。

散布図(ScatterChart)

デフォルトでは、次の様に大きな丸のシンボルで散布図が描画されます。

散布図デフォルトのシンボル

このシンボルの形状を変更するには、CSSを記述します。一律変更するには、セレクターに .chart-symbolを指定して記述します。
プロパティ名は、デフォルトの定義をしている modena.css を調べるのが手っ取り早いです。

modena.css のデフォルト定義 変更例
.chart-symbol { /* solid circle */
    -fx-background-color: CHART_COLOR_1;
    -fx-background-radius: 5px;
    -fx-padding: 5px;
}
.chart-symbol {
    -fx-background-radius: 1px;
    -fx-padding: 1px;
}

変更後は次の様に小さな丸のシンボルで散布図が描画されます。

散布図デフォルトのシンボルの大きさを小さく

凡例(Legend)のカスタマイズ

凡例(Legend)で各グラフ(Series)のNodeを取り出す

凡例は、Legendクラス(com.sun.javafx.charts.Legend)ですが、非公開APIで、Java SE 9以降はモジュール化のアクセス制御でアプリケーション側からは利用できません。
しかし、CSSのセレクターで.chart-legend-itemを指定して検索しNodeとして取り出すことは可能です。

Set<Node> chartLegendItemNodes = chart.lookupAll(".chart-legend-item");

取り出したNodeの実際のクラスを見ると、Label型となっていました。

凡例の各項目をクリックしたら処理を入れる

凡例の各項目をNodeとして取り出し、setOnMouseClickedでイベントハンドラを設定すると、マウスに反応する凡例の項目とすることができます。

Set<Node> chartLegendItemNodes = chart.lookupAll(".chart-legend-item");
chartLegendItemNodes.forEach(
    node -> node.setOnMouseClicked(event -> {
        System.out.println("Legend item is clicked");
    })
);

パフォーマンス

グラフ用データの生成

XYChart.SeriesにXYChart.Dataを入れるときは

LineChartに表示するグラフ用データ(点列)を生成する際、最初はSeriesのgetData().addメソッドをループで呼び出していました。数千個の点列は特に遅いと感じず、数十万個の点列を生成しようとしたところ、数分待っても表示されませんでした。
getDataで得られるListはObservableListなので、addの度にリスナーに通知が行き処理が走るためと思われます。

そこで、別途新規にFXCollections.observableArrayListでObservableListを作り(リスナーが空)、ここにaddで点を全て追加します。
続いて、Seriesのコンストラクタにこのリストを渡します。

クリップボードから画像を追加 (サイズの上限: 1 GB)