Alle Werte aus DB auslesen und in Chart darstellen

dior

Bekanntes Mitglied
Hi,

ich hoffe mein Problem ist nicht zu Banal, aber ich bekomme die Lösung gerade nicht alleine zustande:

Ich habe eine DB Tabelle (oracle) die folgendermasen aussieht:


O9 O10 O11 O12 O13 O14 O15 Datum Zeilennummer
-4,8 -20,4 -32 -31,5 -24 -10,7 -3,4 16.12.1992 1
-3,8 -9 -11,7 -12,7 -9,3 -2,6 -1,6 26.05.1993 2
-3,9 -9,1 -12,1 -13,1 -9,4 -3 -1,6 20.07.1993 3
-4 -9,3 -12,9 -13,7 -9,6 -3,4 -1 17.11.1993 4
-4,4 -10,7 -14,5 -15,5 -11,2 -4,1 -1,7 10.05.1994 5
-4,3 -11,2 -15,6 -16,7 -11,6 -4,1 -1,6 01.08.1994 6
-4,2 -11,7 -16,3 -17,2 -11,9 -4 -1,6 21.10.1994 7
-4,6 -13,2 -18,2 -19,5 -13,1 -4,6 -2,1 15.03.1995 8
-4,8 -13,6 -18,6 -20 -13,5 -4,7 -2 04.07.1995 9
-4,9 -13,8 -19,1 -20,2 -13,7 -4,8 -1,8 22.09.1995 10

Jetzt möchte ich ein JavaFX Line Chart mit den Werten erstellen wobei für jede Zeile eine Diagrammlinie verwendet wird.

akutell habe ich "händisch" die ersten 2 Zeilen eingetragen:

fxlinecharttest.jpg


Mein Code:
Java:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
 
 
public class LineChartTest_1 extends Application {
 
    public static ResultSet rs1;
    public static ResultSet rs2;
     
    @Override public void start(Stage stage) throws SQLException, Exception {
        
        
                    Connection conn = db_input.Db_select.getConnection();
                    Statement stmt = conn.createStatement();
                    rs1 = stmt.executeQuery("SELECT * FROM D_KRONE WHERE TO_CHAR(datum, 'YYYY')='1992'");
        
                    if (!rs1.next()) {
                        throw new SQLException("SELECT *: no result");
                    }
                    
                    Connection conn2 = db_input.Db_select.getConnection();
                    Statement stmt2 = conn.createStatement();
                    rs2 = stmt2.executeQuery("SELECT * FROM D_KRONE WHERE TO_CHAR(datum, 'YYYY')='1993'");
       
                    if (!rs2.next()) {
                        throw new SQLException("SELECT *: no result");
                    }
        
        
        stage.setTitle("FX Line Chart");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
         xAxis.setLabel("Month");
        final LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
       
        lineChart.setTitle("Charts 1992 - 2009");
                          
        XYChart.Series series1 = new XYChart.Series();
        series1.setName("1992");
        
        series1.getData().add(new XYChart.Data( "O9",  rs1.getDouble(1)));
        series1.getData().add(new XYChart.Data("O10", rs1.getDouble(2)));
        series1.getData().add(new XYChart.Data("O11", rs1.getDouble(3)));
        series1.getData().add(new XYChart.Data("O12", rs1.getDouble(4)));
        series1.getData().add(new XYChart.Data("O13", rs1.getDouble(5)));
        series1.getData().add(new XYChart.Data("O14", rs1.getDouble(6)));
        series1.getData().add(new XYChart.Data("O15", rs1.getDouble(7)));

        
        XYChart.Series series2 = new XYChart.Series();
        series2.setName("1993");
        series2.getData().add(new XYChart.Data( "O9",  rs2.getDouble(1)));
        series2.getData().add(new XYChart.Data("O10", rs2.getDouble(2)));
        series2.getData().add(new XYChart.Data("O11", rs2.getDouble(3)));
        series2.getData().add(new XYChart.Data("O12", rs2.getDouble(4)));
        series2.getData().add(new XYChart.Data("O13", rs2.getDouble(5)));
        series2.getData().add(new XYChart.Data("O14", rs2.getDouble(6)));
        series2.getData().add(new XYChart.Data("O15", rs2.getDouble(7)));

        
        Scene scene  = new Scene(lineChart,800,600);       
        lineChart.getData().addAll(series1, series2);       
        stage.setScene(scene);
        stage.show();
    }
 
 
    public static void main(String[] args) {
        launch(args);
    }
}


Wie kann ich das so abändern, das mir automatisch alle Zeilen die in der Tabelle vorhanden sind ausgegeben werden, egal wie viele das im laufe der Zeit sind? :rtfm:
 
ist das ein Programmierkurs?
na wenn es sein muss:
Schritt 1, wichtige allgemeine Denkfähigkeit, auch beim Schuhe-zubinden:
Aufgaben voneinander trennen,

-> Schritt 2: lade zunächst nur die Daten aus der DB, speichere sie in einem 2D-Array oder in Listen/ Map, irgendwas einfaches,
immer nur ein ResultSet offen halten, dessen Daten herausholen

falls sich die Queries nur im Jahr 1992, 1993 usw. ändern, dann Untermethode mit Parameter aufrufen,
vielleicht geht gar eine Schleife mit inkrementierten Jahr


Schritt 3: aus den Daten komplett unabhängig von deren Quelle (DB, Text-Datei, User-Eingabe, Zufall) eine Chart bauen,
damit 1992, 1993 usw. zugehörig bekannt ist sollte die Datenstruktur entsprechend strukturiert sein,
Map<String,List> bietet sich vielleicht an,
für jeden Eintrag ein Series-Objekt erstellen, per Schleife die Werte einfügen
 
So, erstmals Danke für die Anregungen.....

ich habe jetzt das ResultSet in eine HashMap geschrieben und kann mir diese auch ausgeben lassen
Problem1: die Werte kommen umgekehrter Reihenfolge.... wie kann ich das umdrehen?

Problem2: Wie lasse ich alle Zeilen im Chart anzeigen? jetzt wird mir nur ein einziger xy Wert angezeigt?
(mit PrintLn kann ich mir ja auch alle anzeigen lassen...)

Java:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
 
 
public class LineChartTest_2DArray extends Application {
 
    public static ResultSet rs1;
 
    
    
    
    @Override public void start(Stage stage) throws SQLException, Exception {
        
        
                    Connection conn = db_input.Db_select.getConnection();
                    Statement stmt = conn.createStatement();
                    rs1 = stmt.executeQuery("SELECT O9, O10, O11, O12, O13, O14, O15 FROM D_KRONE");
        
                    if (!rs1.next()) {
                        throw new SQLException("SELECT *: no result");
                    }
                    
                    
                    HashMap<String, Double> hm = new HashMap<String, Double>();

                    int i = 1;
                    
                    
                    while (rs1.next()){
                        for (i = 1; i <= 7; i++)
                            {   
                                hm.put("O" + i, new Double(rs1.getDouble(i))); 
                            }
                        for( String name: hm.keySet() )
                            {
                                
                                Iterator it = hm.keySet().iterator();
                                while (it.hasNext()) 
{
                                    String key = (String)it.next();
                                    System.out.println(key + ", "+ (Double)hm.get(key));
                                
 
                  
        
        stage.setTitle("FX Line Chart");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
         xAxis.setLabel("Month");
        final LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
       
        lineChart.setTitle("Charts 1992 - 2009");
                          
        XYChart.Series series1 = new XYChart.Series();
        series1.setName("1992");

        
        series1.getData().add(new XYChart.Data(name, (Double)hm.get(key)));
       
        
        Scene scene  = new Scene(lineChart,800,600);       
        lineChart.getData().addAll(series1); //, series2);
        stage.setScene(scene);
}
                                
                      //          System.out.println(name + ": "+ hm.get(name));    
                        
                            }
                    }
                 
        stage.show();
    }
 
 
    public static void main(String[] args) {
        launch(args);
    }
}


PrintLn Ergebnis sieht so aus:

O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
O6, -2.6
O5, -9.3
O4, -12.7
O3, -11.7
O2, -9.0
O1, -3.8
O7, -1.6
.
.
.
 
ich habe jetzt das ResultSet in eine HashMap geschrieben und kann mir diese auch ausgeben lassen
Problem1: die Werte kommen umgekehrter Reihenfolge.... wie kann ich das umdrehen?
ist es kein Problem dass die DB-Felder O9-O15 heißen und du O1-O7 draus machst?
für diese Werte dachte ich eher an eine Liste, keine Map,
anderenfalls könntest du das Key-Set der Map später erst noch in eine neue Liste einfügen und sortieren

dass du jeweils 7 Werte pro Zeile im ResultSet hast, hast du bisher nicht bedacht und speicherst alles übereinander,
wie gesagt war meine Idee ursprünglich
Map<String,List>
mit Einträgen
key 1992 -> 7 Werte in einer Liste
key 1993 -> 7 Werte in einer Liste
usw.

im Moment hast du zudem noch mehrere Zeilen im ResultSet pro Jahr, 26.05.1993, 20.07.1993,
wie das wohl werden soll..

Problem2: Wie lasse ich alle Zeilen im Chart anzeigen? jetzt wird mir nur ein einziger xy Wert angezeigt?
(mit PrintLn kann ich mir ja auch alle anzeigen lassen...)
dein PrintLn steht in einer Schleife, bei der Chart hast du keine Schleife,
ist da der Unterschied zwischen vielen Ausgaben und nur einem Wert in der Chart nicht offensichtlich?


------

ein struktureller Fehler ist übrigens, die Ausgabe bei der Befüllung der Daten laufen zu lassen,
bzw. ist als erster Schritt gar nicht schlecht, aber du solltest nicht glauben dass danach auch ebensoviele Werte in der HashMap stehen,
wie gesagt wird im Moment alles übereinander geschrieben, es bleiben nur die zuletzt eingefügten 7 Werte

-------

Java:
 for( String name: hm.keySet() )
                            {
                                
                                Iterator it = hm.keySet().iterator();
                                while (it.hasNext())
ist ebenso strukturell falsch, wenn du über das KeySet in einer for-Schleife iterierst, alle Keys durchgehtst,
warum dann in dieser Schleife nochmal ein Iterator auf das KeySet?
damit gibst du nur alles quadratisch oft aus
 
Zuletzt bearbeitet von einem Moderator:
Sorry wenn ich lästig bin und mit meinen bescheidenen Java Wissen mich hier nicht besonders beliebt mache (evtl auch den einen oder anderen Hinweis übersehe...)

Ich hab das Programm etwas umgeschrieben und kann mir jetzt auch alle Werte ausgeben lassen. Aber wie muss ich das in mein XYChart übergeben damit es mir die Diagramme zeichnet?

Java:
public class LineChartTest_2DArray1 extends Application {
 
    public static ResultSet rs1;
  //  private ObservableList<Object> data;
        
    @Override public void start(Stage stage) throws SQLException, Exception {
        
   //     data = FXCollections.observableArrayList(); 
                    Connection conn = db_input.Db_select.getConnection();
                    Statement stmt = conn.createStatement();
                    rs1 = stmt.executeQuery("SELECT O9, O10, O11, O12, O13, O14, O15 FROM DMT_DAMMKRONE");
        
                    if (!rs1.next()) {
                        throw new SQLException("SELECT *: no result");
                    }
                  
        
        stage.setTitle("FX Line Chart");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
         xAxis.setLabel("Month");
        final LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
       
        lineChart.setTitle("Charts 1992 - 2009");
                          
        XYChart.Series series1 = new XYChart.Series();
        series1.setName("1992");
       
        List<Double> row = new ArrayList<Double>(); 
        
        while(rs1.next()){  

               //ObservableList<String> row = FXCollections.observableArrayList();  
               
                 int i = 1;
                 for( i=1 ; i<=rs1.getMetaData().getColumnCount(); i++){  
                    row.add(rs1.getDouble(i));  
                    System.out.println(i + ": " + row.get(i-1));    //   only a Test for the first entry of each line
                 }  
                            // series1.getData().add(new XYChart.Data("name", row.get(i-1)));
                 }        
        series1.getData().addAll("test", row);         //    .add(new XYChart.Data("name", row.get(0)));
        
        Scene scene  = new Scene(lineChart,800,600);       
        lineChart.getData().addAll(series1); //, series2);
        stage.setScene(scene);         
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

.
.
.
1: -3.8
2: -9.0
3: -11.7
4: -12.7
5: -9.3
6: -2.6
7: -1.6
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:378)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:27)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:97)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to javafx.scene.chart.XYChart$Data
at javafx.scene.chart.XYChart$Series$1.onChanged(XYChart.java:1361)
at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:78)
at com.sun.javafx.collections.ObservableListWrapper.addAll(ObservableListWrapper.java:109)
at com.sun.javafx.collections.ObservableListWrapper.addAll(ObservableListWrapper.java:103)
at com.sun.javafx.collections.ObservableListWrapper.addAll(ObservableListWrapper.java:227)
at Charts.LineChartTest_2DArray1.start(LineChartTest_2DArray1.java:70)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:298)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:152)
at com.sun.javafx.application.PlatformImpl$3.run(PlatformImpl.java:119)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$2$1.run(WinApplication.java:62)
... 1 more
Java Result: 1


Evtl. sollte man das Thema in das Anfängerforum verschieben... :rtfm:
 
du machst weiterhin den Fehler der Ausgabe noch während der Eingabe bzw. [siehe sonstige Anmerkungen dazu]

wieder hast du nur eine row-Liste, in der diesmal alle Daten landen,
die Liste dürfte auf zig Werte ansteigen, deine Ausgabe mit i-1 schaut sich immer nur die ersten Werte in der row an,
selbst wenn das aktuelel Element an Position 75 eingefügt wird

-----

wie gesagt kannst du für das Einfügen eine Schleife verwenden,
du machst es nicht und schreibst addAll(), habe ich nie erwähnt, Kreativität ist zu begrüßen,
aber ist hier schlicht falsch oder ich kann zumindest nichts dazu sagen

aus
Java:
        series1.getData().add(new XYChart.Data( "O9",  rs1.getDouble(1)));
        series1.getData().add(new XYChart.Data("O10", rs1.getDouble(2)));
        series1.getData().add(new XYChart.Data("O11", rs1.getDouble(3)));
        series1.getData().add(new XYChart.Data("O12", rs1.getDouble(4)));
        series1.getData().add(new XYChart.Data("O13", rs1.getDouble(5)));
        series1.getData().add(new XYChart.Data("O14", rs1.getDouble(6)));
eine Schleife zu machen dürfte aber Standard sein, vielleicht schwierig mit dem O-String, evtl. ruhig erstmal die 7 Befehle beibehalten und nur die Liste der Daten variabel machen
->
Java:
        series1.getData().add(new XYChart.Data( "O9",  row.get(0)));
        series1.getData().add(new XYChart.Data("O10", row.get(1)));
usw.

wie das für verschiedene rows klappt ist wiederum eine andere Frage, aber bisher hast du ja eh nur eine row


ein weiteres Mal die Rückkehr auf die grundlegende Annahme:
konzentriere dich zunächst auf das Einlesen bzw. noch davor überhaupt auf irgendein Datenmodell,
wie willst du die Daten darstellen, Liste von Liste oder irgendwas,
die Chart spielt solange keine Rolle, außer dass du schon bisschen überlegen kannst, welche Werte du brauchst
 
Ich glaub jetzt hab ich es kapiert 🙂

noch ne schleife drüber und schaun wie ich die series1 - seriesx elemente anlege und fertig!


Vielen Dank SlaterB 😉




-> wenn noch fragen sind darf ich mich hoffentlich nochmal melden!
 

Neue Themen


Zurück
Oben