Wie lässt sich ein Säulendiagramm realisieren?
Säulendiagramm mit einer Datengruppe
In JavaFX lassen sich Säulendiagramme mit einer
oder mehreren Datengruppen durch die Klasse javafx.scene.chart.BarChart
realisieren. Wesentliche Gestaltungselemente wie die
Säulenbreite und -farbe sind dabei voreingestellt
können zumindest teilweise auch konfiguriert
werden.
Hierzu werden zuerst ein CategoryAxis
-Objekt
für String-Literale als X-Achse und ein NumberAxis
-Objekt
für numerische Werte als Y-Achse gebildet. Beide
Achsen-Objekte werden dem Konstruktor der BarChart
übergeben. Durch die Methode setLabel()
können beiden Achsen Kategoriebezeichner zugeteilt
werden.
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 BarChartEinfachBsp extends Application { @Override public void start(Stage stage) { stage.setTitle("Mopeds"); final CategoryAxis x = new CategoryAxis(); final NumberAxis y = new NumberAxis(); final BarChart<String, Number> bc = new BarChart<>(x, y); bc.setTitle("BMW"); x.setLabel("Typ"); y.setLabel("Leistung"); XYChart.Series<String, Number> serie = new XYChart.Series<String, Number>(); serie.setName("500ccm-Modelle"); serie.getData().add(new XYChart.Data<String, Number>("R 32", 8.5)); serie.getData().add(new XYChart.Data<String, Number>("R 37", 16)); serie.getData().add(new XYChart.Data<String, Number>("R 47", 18)); serie.getData().add(new XYChart.Data<String, Number>("R 57", 18)); serie.getData().add(new XYChart.Data<String, Number>("R 5", 24)); serie.getData().add(new XYChart.Data<String, Number>("R 51", 24)); serie.getData().add(new XYChart.Data<String, Number>("R 50", 26)); bc.getData().add(serie); Scene scene = new Scene(bc, 800, 600); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
Die Erfassung der Daten erfolgt als Gruppe in Form eines
Objektes der inneren Klasse XYChart.Series<String,
Number>
. Sie speichert die Daten in einer
ObservableList
, der durch add()
ein neues Datenobjekt hinzugefügt werden kann. Dies
wird als Objekt der zweiten innere Klasse von XYChart
,
XYChart.Data<String, Number>
,
bereitgestellt. Nach dem gleichen Prinzip wird die
gesamte Gruppe (series
) in Zeile 32 der
Chart hinzugefügt und diese schließlich auf
die Scene gesetzt.
Säulendiagramm mit mehreren Datengruppen
Die vergleichende Darstellung mehrer Gruppen in einem Säulendiagramm gestaltet sich recht einfach. Hierzu müssen lediglich mehrere Gruppen erzeugt und hinzugefügt werden.
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 BarChartDreifachBsp extends Application { @SuppressWarnings("unchecked") @Override public void start(Stage stage) { stage.setTitle("Bar Chart Beispiel"); final CategoryAxis x = new CategoryAxis(); final NumberAxis y = new NumberAxis(); final BarChart<String, Number> bc = new BarChart<>(x, y); bc.setTitle("BMW Klassiker"); y.setLabel("Leistung [PS]"); XYChart.Series<String, Number> serie1 = new XYChart.Series<String, Number>(); serie1.setName("500ccm-Modelle"); serie1.getData().add(new XYChart.Data<String, Number>("R 32", 8.5)); serie1.getData().add(new XYChart.Data<String, Number>("R 37", 16)); serie1.getData().add(new XYChart.Data<String, Number>("R 47", 18)); serie1.getData().add(new XYChart.Data<String, Number>("R 57", 18)); serie1.getData().add(new XYChart.Data<String, Number>("R 5", 24)); serie1.getData().add(new XYChart.Data<String, Number>("R 51", 24)); serie1.getData().add(new XYChart.Data<String, Number>("R 50", 26)); XYChart.Series<String, Number> serie2 = new XYChart.Series<String, Number>(); serie2.setName("250ccm-Modelle"); serie2.getData().add(new XYChart.Data<String, Number>("R 39", 6.5)); serie2.getData().add(new XYChart.Data<String, Number>("R 23", 10)); serie2.getData().add(new XYChart.Data<String, Number>("R 24", 12)); serie2.getData().add(new XYChart.Data<String, Number>("R 25", 12)); serie2.getData().add(new XYChart.Data<String, Number>("R 25/2", 12)); serie2.getData().add(new XYChart.Data<String, Number>("R 25/3", 13)); serie2.getData().add(new XYChart.Data<String, Number>("R 26", 15)); serie2.getData().add(new XYChart.Data<String, Number>("R 27", 18)); XYChart.Series<String, Number> serie3 = new XYChart.Series<String, Number>(); serie3.setName("750ccm-Modelle"); serie3.getData().add(new XYChart.Data<String, Number>("R 62", 18)); serie3.getData().add(new XYChart.Data<String, Number>("R 63", 24)); serie3.getData().add(new XYChart.Data<String, Number>("R 11", 18)); serie3.getData().add(new XYChart.Data<String, Number>("R 16", 25)); serie3.getData().add(new XYChart.Data<String, Number>("R 12", 18)); serie3.getData().add(new XYChart.Data<String, Number>("R 17", 33)); serie3.getData().add(new XYChart.Data<String, Number>("R 71", 22)); serie3.getData().add(new XYChart.Data<String, Number>("R 75", 26)); Scene scene = new Scene(bc, 800, 600); bc.getData().addAll(serie2, serie1, serie3); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
Farbeinstellungen
Sollen Werte gleicher Elemente
kategorieübergreifend verglichen werden, so kann
dies auch farblich unterstützt werden. Hierzu
müssen die einzelnen Säulen, sowie deren
Farben in der Legende angesprochen werden. Dies
geschieht über Stylesheets durch die Selektoren .default-colorX.chart-bar
und .default-colorX.chart-bar-symbol
und
der Eigenschaft -fx-bar-fill
Das X
des Selektors muss hierbei durch eine Zahl zwischen 0
und 7 ersetzt werden. Sie bezieht sich auf die Position
eines Eintrags in der Gruppe beginnend bei 0. Somit
können acht unterschiedliche Farben vergeben
werden. Die Position bestimmt sich übrigens durch
die Ladereihenfolge innerhalb der Methode addAll()
,
hier in Zeile 109.
Das folgende Beispiel demonstriert
das Gesagte anhand einer Übersicht über einen
fiktiven Getränkekonsum.
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 BarChartMehrfachBsp extends Application { private final static String j50 ="1950"; private final static String j60 ="1960"; private final static String j70 ="1970"; private final static String j80 ="1980"; private final static String j90 ="1990"; private final static String j00 ="2000"; private final static String j10 ="2010"; @SuppressWarnings("unchecked") @Override public void start(Stage stage) { stage.setTitle("Bar Chart Beispiel"); final CategoryAxis x = new CategoryAxis(); final NumberAxis y = new NumberAxis(); final BarChart<String , Number> bc = new BarChart<>(x, y); bc.setTitle("Getr\u00e4nkekonsum"); x.setLabel("Jahr"); y.setLabel("Menge"); XYChart.Series<String , Number> serie1 = new XYChart.Series<String , Number>(); serie1.setName("Milch"); serie1.getData().add(new XYChart.Data<String , Number>(j50, 321)); serie1.getData().add(new XYChart.Data<String , Number>(j60, 35)); serie1.getData().add(new XYChart.Data<String , Number>(j70, 0)); serie1.getData().add(new XYChart.Data<String , Number>(j80, 0)); serie1.getData().add(new XYChart.Data<String , Number>(j90, 0)); serie1.getData().add(new XYChart.Data<String , Number>(j00, 0)); serie1.getData().add(new XYChart.Data<String , Number>(j10, 0)); XYChart.Series<String , Number> serie2 = new XYChart.Series<String , Number>(); serie2.setName("Kakao"); serie2.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie2.getData().add(new XYChart.Data<String , Number>(j60, 18)); serie2.getData().add(new XYChart.Data<String , Number>(j70, 32)); serie2.getData().add(new XYChart.Data<String , Number>(j80, 0)); serie2.getData().add(new XYChart.Data<String , Number>(j90, 0)); serie2.getData().add(new XYChart.Data<String , Number>(j00, 0)); serie2.getData().add(new XYChart.Data<String , Number>(j10, 0)); XYChart.Series<String , Number> serie3 = new XYChart.Series<String , Number>(); serie3.setName("Wasser"); serie3.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie3.getData().add(new XYChart.Data<String , Number>(j60, 10)); serie3.getData().add(new XYChart.Data<String , Number>(j70, 134)); serie3.getData().add(new XYChart.Data<String , Number>(j80, 160)); serie3.getData().add(new XYChart.Data<String , Number>(j90, 135)); serie3.getData().add(new XYChart.Data<String , Number>(j00, 146)); serie3.getData().add(new XYChart.Data<String , Number>(j10, 120)); XYChart.Series<String , Number> serie4 = new XYChart.Series<String , Number>(); serie4.setName("Cola"); serie4.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie4.getData().add(new XYChart.Data<String , Number>(j60, 0)); serie4.getData().add(new XYChart.Data<String , Number>(j70, 9)); serie4.getData().add(new XYChart.Data<String , Number>(j80, 3)); serie4.getData().add(new XYChart.Data<String , Number>(j90, 0)); serie4.getData().add(new XYChart.Data<String , Number>(j00, 0)); serie4.getData().add(new XYChart.Data<String , Number>(j10, 0)); XYChart.Series<String , Number> serie5 = new XYChart.Series<String , Number>(); serie5.setName("Limo"); serie5.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie5.getData().add(new XYChart.Data<String , Number>(j60, 0)); serie5.getData().add(new XYChart.Data<String , Number>(j70, 29)); serie5.getData().add(new XYChart.Data<String , Number>(j80, 2)); serie5.getData().add(new XYChart.Data<String , Number>(j90, 1)); serie5.getData().add(new XYChart.Data<String , Number>(j00, 1)); serie5.getData().add(new XYChart.Data<String , Number>(j10, 0)); XYChart.Series<String , Number> serie6 = new XYChart.Series<String , Number>(); serie6.setName("Bier"); serie6.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie6.getData().add(new XYChart.Data<String , Number>(j60, 0)); serie6.getData().add(new XYChart.Data<String , Number>(j70, 19)); serie6.getData().add(new XYChart.Data<String , Number>(j80, 39)); serie6.getData().add(new XYChart.Data<String , Number>(j90, 42)); serie6.getData().add(new XYChart.Data<String , Number>(j00, 76)); serie6.getData().add(new XYChart.Data<String , Number>(j10, 67)); XYChart.Series<String , Number> serie7 = new XYChart.Series<String , Number>(); serie7.setName("Wein"); serie7.getData().add(new XYChart.Data<String , Number>(j50, 0)); serie7.getData().add(new XYChart.Data<String , Number>(j60, 0)); serie7.getData().add(new XYChart.Data<String , Number>(j70, 5)); serie7.getData().add(new XYChart.Data<String , Number>(j80, 34)); serie7.getData().add(new XYChart.Data<String , Number>(j90, 46)); serie7.getData().add(new XYChart.Data<String , Number>(j00, 76)); serie7.getData().add(new XYChart.Data<String , Number>(j10, 68)); Scene scene = new Scene(bc, 800, 600); String stylesheet = getClass().getResource("/styles/styles.css").toExternalForm(); scene.getStylesheets().add(stylesheet); bc.getData().addAll(serie1, serie2, serie3, serie4, serie5, serie6, serie7); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
In Zeile 107 und 108 werden zur Farbkonfiguration die folgenden Stylesheets aus einer Datei geladen und an die scene übergeben. Die erste Angabe ist hierbei für die Hintergrundfarbe der Grafik und der Legende verantwortlich.
.chart-plot-background, .chart, .chart-legend { -fx-background-color: #bbb; } /* Milch */ .default-color0.chart-bar-symbol { -fx-bar-fill: #ffffff; } .default-color0.chart-bar { -fx-bar-fill: #ffffff; } /* Kakao */ .default-color1.chart-bar-symbol { -fx-bar-fill: #932; } .default-color1.chart-bar { -fx-bar-fill: #432; } /* Wasser */ .default-color2.chart-bar-symbol { -fx-bar-fill: #0af; } .default-color2.chart-bar { -fx-bar-fill: #0af; } /* Cola */ .default-color3.chart-bar-symbol { -fx-bar-fill: #855; } .default-color3.chart-bar { -fx-bar-fill: #855; } /* Limo */ .default-color4.chart-bar-symbol { -fx-bar-fill: #fd0; } .default-color4.chart-bar { -fx-bar-fill: #fd0; } /* Bier */ .default-color5.chart-bar-symbol { -fx-bar-fill: #d9c033; } .default-color5.chart-bar { -fx-bar-fill: #d9c033; } /* Wein */ .default-color6.chart-bar-symbol { -fx-bar-fill: #fd8; } .default-color6.chart-bar { -fx-bar-fill: #fd8; }
Quellen
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.