JFreeChart --> TimeSeries auslesen

Nisbo

Bekanntes Mitglied
Servus,

ich erstelle mehrere JInternalFrames auf einer JDesktopPane welche ich dann mit Charts fülle. Jetzt möchte ich das Ganze so umsetzen das sich die Charts auch von alleine aktualisieren (also ohne komplett alles neu erstellen mit removeAll und add, das funktioniert nämlich), dazu nutze ich einen SwingWorker mit
Java:
protected Void doInBackground() throws Exception {
            while (!this.isCancelled()) {
                startChartMonitoring();
                Thread.sleep(1000);
            }
            return null;
        }


Meine Idee ist alle Komponenten auf der DesktopPane zu durchlaufen und erst einmal die Frames raus suchen, das ist auch kein Problem. Dann suche ich auf den jeweiligen Frames nach den JFreeChart Komponenten (ist pro Frame jeweils nur einmal vorhanden)

Jetzt benötige ich die TimeSeries um denen dann die Werte hinzu zu fügen und hier hapert es. Es werden die Serien zwar gefunden aber der SwingWorker steigt kommentarlos aus und ruft gleich done() auf.

Jemand eine Idee ?

Java:
for(Component chartPanel : ((JInternalFrame) internalFrameToUse).getContentPane().getComponents()){
    // get the ChartPanel
    if(chartPanel instanceof ChartPanel){
        // get the Chart
        JFreeChart jFreeChart = ((ChartPanel) chartPanel).getChart();
       
        int i = 0;
        while(i < jFreeChart.getXYPlot().getDataset().getSeriesCount()){
            // get the TimeSeries(Collection)
            String timeSeriesName = jFreeChart.getXYPlot().getDataset().getSeriesKey(i).toString();
           
            // check if the READING is equal the name of the TimeSerie --> this work
            System.out.println("READING: " + result.getString("READING") + " - Name of the TimeSerie: " + timeSeriesName);
           
            if(result.getString("READING").equals(timeSeriesName)){
                System.out.println("Add or Update the value");
                // hier steigt der SwingWorker kommentarlos aus und ruft done() auf
                ((TimeSeries) jFreeChart.getXYPlot().getDataset().getSeriesKey(i)).addOrUpdate(new Second(myDate), result.getInt(6));
               
                System.out.println("Das wird nicht mehr angezeigt");
               
               
                if (result.getString("DEVICE").equals("Arbeitszimmer.Steckdose.PC")){
                    System.out.println(result.getString("TIMESTAMP") + " - READING: " + result.getString("READING") + " Value: " + result.getInt(6) +
                            " - Count: " + ((TimeSeries) jFreeChart.getXYPlot().getDataset().getSeriesKey(i)).getItemCount());
                }
            }
           
            i++;
        }
    }
}
 

Nisbo

Bekanntes Mitglied
So nach stundenlangen Suchen und probieren habe ich leider keine Lösung in der Art gefunden und habe mich halt selbst um eine Lösung gekümmert.

Also für alle welche auch das Problem haben

neue Klasse AvailableTimeSeries erstellen:
Java:
import java.util.ArrayList;
import org.jfree.data.time.TimeSeries;

public class AvailableTimeSeries {
    private String nameOfTheSet;
    private ArrayList<TimeSeries> timeSerie = new ArrayList<TimeSeries>();
   
    public AvailableTimeSeries(String nameOfTheSet){
        this.nameOfTheSet = nameOfTheSet;
    }

    public void addTimeSerie(TimeSeries timeSerie) {
        this.timeSerie.add(timeSerie);
    }

    public ArrayList<TimeSeries> getTimeSerie() {
        return timeSerie;
    }

    public String getNameOfTheSet() {
        return nameOfTheSet;
    }

    public void setNameOfTheSet(String nameOfTheSet) {
        this.nameOfTheSet = nameOfTheSet;
    }
}

Für eure Main Class oder wo auch immer ihr die TimeSeries braucht

Java:
private ArrayList<AvailableTimeSeries> timeSeriesMegaArray = new ArrayList<AvailableTimeSeries>();

Beim Aufruf eurer Methode welche das Monitoring der LiveDaten startet nicht vergessen die ArrayList zu clearen
Java:
this.timeSeriesMegaArray.clear();

Füttern mit den Daten (qName ist ein String mit dem Namen des Sets)

Java:
availableTimeSeries = new AvailableTimeSeries(qName);
TimeSeries ts1 = new TimeSeries("Serie 1");
TimeSeries ts1 = new TimeSeries("Serie 2");
TimeSeries ts1 = new TimeSeries("Serie 3");
availableTimeSeries.addTimeSerie(ts1);
availableTimeSeries.addTimeSerie(ts2);
availableTimeSeries.addTimeSerie(ts3);

this.timeSeriesMegaArray.add(availableTimeSeries);


Und so nutzen wir das Ganze dann, der String qName enthält wieder den Namen des Sets, result.getString("READING") in meinem Fall den Namen der TimeSerie
Java:
for(AvailableTimeSeries setOfTimeSeries : this.timeSeriesMegaArray){
    if(setOfTimeSeries.getNameOfTheSet().equals(qName)){
        for(TimeSeries timeSerie : setOfTimeSeries.getTimeSerie()){
            if(result.getString("READING").equals(timeSerie.getKey())){
                timeSerie.addOrUpdate(new Second(myDate), result.getInt(6));
            }
        }
    }
}

Hoffe irgendwer kann damit mal was anfangen, war ja doch eine etwas spezielle Frage gewesen. Evtl könnte man das Ganze auch mittels eines Streams lösen, k.A. ob das dann besser oder schneller wäre
 

Harry Kane

Top Contributor
Das automatische Aktualisieren von Daten ist bei JFreeChart immer mal wieder ein Thema. Ich habe mir deshalb mal den Thread durchgelesen, muss aber gestehen, dass ich deinen Anwendungsfall nicht nachvollziehen könnte. Dazu fehlt zu viel Kontext, z.B. wo qName herkommt und von welchem Objekt die getString-Methode aufgerufen wird.
Der Ansatz, die zu aktualisierenden TimeSeries in einem separaten Objekt abzuspeichern, anstatt sich immer durch die Swing-Komponenten und JFreeChart Objekthierarchie durchzukämpfen, ist schon mal richtig.
Der Fehler in deinem ersten Codeschnupsel dürfte daher kommen, dass eine ClassCastException fliegt. Keines von den Objekten, die bei deinem verketteten Methodenaufruf jemals zurückgeliefert werden, ist eine TimeSeries.
 

Nisbo

Bekanntes Mitglied
qName ist ein String welcher den Titel des InternalFrames enthält, ist gleichzeitig auch der Name des "Chart-Sets". Ich habe die ChartSets in einer CSV gespeichert welche dann beim Start des Programms eingelesen wird. Diese Charsets sind zusätzlich noch in einem Layout (auch csv) speicherbar.

Aufbau
Name vom ChartSet;Type;Devices;Readings
Wetter.Sensor;CUL_HM;Wetter.Sensor;dewpoint, humidity, temperature;

Sprich daraus wird dann ein Query für MySQL gefertigt
SELECT * FROM current WHERE TYPE=CUL_HM AND DEVICE=Wetter.Sensor and READING in (dewpoint, humidity, temperature)

getSting() geht somit auf das MySQL result und vergleicht ob das READING gleich der TimeSerie ist welche den selben Namen trägt.

Aber ich denke mal auch das es besser ist das Ganze über ein Objekt zu regeln wie ich es jetzt ja habe.

Hier mal ein lieblos :D erstelltes Video, ab ca Sekunde 35 siehst Du das mit dem Monitoring (automatischen Aktualisieren)

Das ganze Programm ist noch sehr ausbaufähig das ist mir bekannt ;)
 

Harry Kane

Top Contributor
Mit ist immer noch nicht klar, die die einzelnen Codeschnipsel zusammenarbeiten sollen. Dennoch habe ich ein paar Fragen/Anmerkungen:
1. Mir deucht, dass es statt deiner AvailableTimeSeries-Klasse eine HashMap <String,HashMap<String, TimeSeries>> tun müsste. An die gewünschte TimeSeries müsste man über map.get(qName).get(result.getString("READING")) kommen.
2. Wie oft fragst du die Datenbank ab?
3. Hast du Kontrolle darüber, dann die Daten in die db geschrieben werden?
 

Nisbo

Bekanntes Mitglied
2. momentan 1 mal pro Sekunde, werde ich aber noch einstellbar machen
3. nein nicht wirklich denn das wird durch die Homeautomatisierung FHEM übernommen
http://fhem.de/fhem_DE.html
Welche einmal auf Änderungen im angeschlossenen System reagiert und einmal in festlegbaren Intervallen, sprich Tür geht auf, Eintrag wird sofort geloggt. Lampe hat von 8-16 Uhr immer 60 Watt dann wird dafür nur alle 10 Minuten ein Eintrag erstellt, hat sie einmal 60,1 Watt dann wird sofort geloggt (wenn man das so einstellt)


Wegen der Eingangsfrage Deines Beitrages, evtl hilft Dir der Code ja besser beim Verständnis. Das if / else um die DB Abfrage bitte nicht beachten, hierfür brauchst DU nur den else Zweig welcher aus der current DB ausliest
Java:
// in qReading sind die Namen der Werte drin welche aus der READING Spalte der MySQL DB ausgelesen werden sollen
ArrayList<TimeSeries> series = new ArrayList<>();
     if(qReading.contains(",")){
       String[] splitti = qReading.split(",");
       for(String sss : splitti){
         if (updateFrame == false){
           TimeSeries ts = new TimeSeries(sss.trim());
           series.add(ts);
          
           availableTimeSeries.addTimeSerie(ts);
         }
        
         if(readings.length() > 0) readings = readings + ", ";
          readings = readings + "'" + sss.trim() + "'";
        
         if(value.length() > 0) value = value + " / ";
                  value = value + sss.trim();
       }
     }else{
       if (updateFrame == false){
         TimeSeries ts = new TimeSeries(qReading.trim());
         series.add(ts);
        
         availableTimeSeries.addTimeSerie(ts);
       }
       readings = "'"  + qReading.trim() + "'";
       value  = value + qReading.trim();
     }

value = qName;// + ": " + value;
    
     if (updateFrame == false){
       result = dbConnection.connect2db().executeQuery("select * from history WHERE "
           + "TYPE  = '" + qType + "' AND "
           + "DEVICE  = '" + qDevice + "' AND "
         + "READING IN(" + readings + ") AND "
         + "TIMESTAMP < '" + this.datePickerTo2.getDateTimeStrict().toString().replace("T", " ") + "' AND "
         + "TIMESTAMP > '" + this.datePickerFrom2.getDateTimeStrict().toString().replace("T", " ") + "' "
         + "ORDER BY TIMESTAMP ASC"
         );
     }else{
       result = dbConnection.connect2db().executeQuery("select * from current WHERE "
         + "TYPE  = '" + qType + "' AND "
         + "DEVICE  = '" + qDevice + "' AND "
       + "READING IN(" + readings + ") "
       );
     }
    
     while(result.next()){
       try {
         java.util.Date now = new Date();
        
         String strDate = standardDateFormat.format(now);
         myDate = standardDateFormat.parse(strDate);
       } catch (ParseException e) {
         e.printStackTrace();
       }

       if (updateFrame == true){
         for(AvailableTimeSeries setOfTimeSeries : this.timeSeriesMegaArray){
           if(setOfTimeSeries.getNameOfTheSet().equals(qName)){
             for(TimeSeries timeSerie : setOfTimeSeries.getTimeSerie()){
               if(result.getString("READING").equals(timeSerie.getKey())){
                 timeSerie.addOrUpdate(new Second(myDate), result.getInt(6));
               }
             }
           }
         }
       }else{
         for(TimeSeries s : series){
         if(result.getString("READING").equals(s.getKey())){
           s.addOrUpdate(new Second(myDate), result.getInt(6));
         }
      }
       }
     }
      
     dbConnection.disconnectFromDb();
 

Harry Kane

Top Contributor
Danke. Allmählich wirds klarer. Ich habe den Eindruck als wäre manches noch etwas unschön gelöst.
Der Sinn seiner AvailableTimeSeries Klasse erschliesst sich mit nach wie vor nicht. Sind die Namen der AvailableTimeSeries und die Keys der TimeSeries unique?
Statt if (aBoolean ==true) bzw. if (aBoolean==false) schreibt man einfach if (aBoolean) bzw. if (!aBoolean)
Verwende PreparedStatements und vermeide "Select *"
Mache qReading zu einem String []. Dann ist Fallunterscheidung im ersten if-else-Bock überflüssig. Aktuell wird nur durch das Vorhandensein von "," angezeigt, das qReading eigentlich aus mehreren Fragmenten besteht.
Das wiederholte Aufrufen von trim () auf denselben Strings ist ebenfalls unschön. Besser: einmal trimmen, dann mit dem getrimmten String weiterarbeiten.
Wenn ich keinen massiven Verständnisfehler habe, kannst du einfach myDate = new Date() schreiben und das temporäre Umwandeln in ein String inkl. exception handling sparen.
 

Nisbo

Bekanntes Mitglied
Sind die Namen der AvailableTimeSeries und die Keys der TimeSeries unique?
Ja

verwende PreparedStatements und vermeide "Select *"
OK hast recht, 4 Spalten benötige ich nicht wirklich

Statt if (aBoolean ==true) bzw. if (aBoolean==false) schreibt man einfach if (aBoolean) bzw. if (!aBoolean)
Die Frage ist jetzt ernst gemeint, gehört das in die Kategorie "Weil man das so macht" oder "Weil es schöner ausschaut" oder "weil das alle so machen" oder gibt es da einen technischen Grund dahinter ? Bitte die Frage nicht falsch verstehen, würde mich wirklich interessieren.

Das wiederholte Aufrufen von trim () auf denselben Strings ist ebenfalls unschön.
Die Trims können eigentlich raus, wird bei der Erstellung/Einlesen schon getrimmt

Wenn ich keinen massiven Verständnisfehler habe, kannst du einfach myDate = new Date() schreiben und das temporäre Umwandeln in ein String inkl. exception handling sparen.

Jetzt wo Du es sagst weiß ich auch nicht mehr warum ich das da drin habe, ich glaube da war zuerst Date nur von MySQL importiert gewesen, deswegen hatte ich dann auch
java.util.Date now = new Date();
geschrieben

Danke für die Hinweise :)
 

Harry Kane

Top Contributor
Nachteile von if (aBoolean == true)
1. Es ist unnötig.
2. Beim verketten von mehreren boolschen Ausdrücken wird das ganze sehr schnell unübersichtlich.
3. Es kann sehr leicht mit der Zuweisung if (aBoolean = true) verwechselt werden. Die Zuweisung ändert nicht nur möglicherweise den Wert von aBoolean, sondern ergibt auch immer true.
 

Meniskusschaden

Top Contributor
@Nisbo: Ausserdem ist es bei Verwendung vernünftiger Namen auch viel besser lesbar. Du hast es teilweise ja bereits so gemacht. Folgendes Beispiel aus deinem Code:
Java:
if (qReading.contains(",")) {
ist doch viel klarer als folgender Code:
Java:
if (qReading.contains(",")==true) {
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E JFreeChart (LineChart) akutalisiert nicht Java Basics - Anfänger-Themen 10
C JFreeChart Linie nicht korrekt dargestellt Java Basics - Anfänger-Themen 1
B Markieren einzelner Punkte in JFreeChart Java Basics - Anfänger-Themen 1
N JFreeChart - Value und veriable Zeitachse Java Basics - Anfänger-Themen 15
J JFreeChart wird nicht angezeigt Java Basics - Anfänger-Themen 6
A JFreeChart als png abspeichern Java Basics - Anfänger-Themen 2
S Jfreechart mit LinkedList befüllen Java Basics - Anfänger-Themen 1
G JFreeChart | Plot updaten bei neuem Dataset | wahrscheinlich "Thread-abhängig" Java Basics - Anfänger-Themen 3
S JFreeChart - Speichermanagement Java Basics - Anfänger-Themen 6
M Problem JFreeChart Java Basics - Anfänger-Themen 8
M JFreeChart Java Basics - Anfänger-Themen 5
P JFreechart Java Basics - Anfänger-Themen 9
G JFreeChart und das Update(was nicht klappt). Java Basics - Anfänger-Themen 3
G jfreechart einbinden + tutorial Java Basics - Anfänger-Themen 2
G JFreeChart einbinden Java Basics - Anfänger-Themen 4
M JFreeChart nach erneutem aufruf fehlt 2. Achse Java Basics - Anfänger-Themen 4
N JFreeChart Koordinatenachsen Java Basics - Anfänger-Themen 11
G Problem mit der Darstellung (JFreechart) Java Basics - Anfänger-Themen 3
M jfreechart - Balkendiagramm mit Werten anzeigen, geht das? Java Basics - Anfänger-Themen 2
S JFreeChart Java Basics - Anfänger-Themen 4
L JFreeChart Java Basics - Anfänger-Themen 3
L JFreeChart in Eclipse Java Basics - Anfänger-Themen 5
S JFreeChart Java Basics - Anfänger-Themen 7
S Daten aus Import Datei auslesen und sortieren Java Basics - Anfänger-Themen 2
T array auslesen Java Basics - Anfänger-Themen 2
I Klassen von einem package laden, Statisches Feld auslesen und Objekt erstellen Java Basics - Anfänger-Themen 8
N Einzelne Werte aus einem TreeSet auslesen Java Basics - Anfänger-Themen 2
D Eclipse will nicht auslesen Java Basics - Anfänger-Themen 6
E TIF Datei auslesen Java Basics - Anfänger-Themen 2
krgewb Breite und Höhe eines Bildes in base64 auslesen Java Basics - Anfänger-Themen 3
sserio TXT-Datei Auslesen und den Wert jedes Namen ausrechnen etc. Java Basics - Anfänger-Themen 37
J Speichern von zwei Variablen durch Auslesen aus einem Numberfield Java Basics - Anfänger-Themen 2
U Sekunden von LocalTime auslesen, wie möglich? Java Basics - Anfänger-Themen 1
E Outlook ordner auslesen Java Basics - Anfänger-Themen 4
R Eigenschaft über Parameter auslesen und ändern Java Basics - Anfänger-Themen 15
B Bin komplett am verzweifeln :( Verkettete Liste die Objekte hat Attribut auslesen Java Basics - Anfänger-Themen 14
J Datei aus Netzwerk auslesen Java Basics - Anfänger-Themen 9
J Jsonfile auslesen Java Basics - Anfänger-Themen 8
A Eine Textdatei auslesen Java Basics - Anfänger-Themen 16
N Aus einem String die Anzahl der Vokale auslesen Java Basics - Anfänger-Themen 40
H Array rückwärts auslesen funktioniert nicht Java Basics - Anfänger-Themen 3
J Bestimmte parameter aus Jsonfile auslesen Java Basics - Anfänger-Themen 15
AleXusher Mehrdimensionales Array aus txt.file auslesen Java Basics - Anfänger-Themen 4
L Zeichen an bestimmter Stelle auslesen Java Basics - Anfänger-Themen 4
3 Textdatei Zeilenweise auslesen Java Basics - Anfänger-Themen 3
J Json Datei auslesen Java Basics - Anfänger-Themen 4
I Java String einlesen und auslesen Java Basics - Anfänger-Themen 11
S Tastatureingabe auslesen und in Konsole ausgeben Java Basics - Anfänger-Themen 6
S CSV Datei auslesen und anders darstellen Java Basics - Anfänger-Themen 2
G Scanner nutzen und Index auslesen Java Basics - Anfänger-Themen 8
N JTable auslesen Java Basics - Anfänger-Themen 6
N Java CSV Datei auslesen Java Basics - Anfänger-Themen 6
F Webseiten Quelltext auslesen Java Basics - Anfänger-Themen 5
J Datei auslesen (nur bestimmte Stellen) Java Basics - Anfänger-Themen 2
I csv auslesen, mittels List Java Basics - Anfänger-Themen 18
S Letzte Zahl eines Integer auslesen? Java Basics - Anfänger-Themen 3
G If / While Programm (Datei auslesen) Java Basics - Anfänger-Themen 6
S Aus einer .bz2 Datei auslesen Java Basics - Anfänger-Themen 2
K Textdatei auslesen und über Mqtt schicken Java Basics - Anfänger-Themen 4
B Name von Verzeichnis bekommen - Files von einem Ordner auslesen Java Basics - Anfänger-Themen 4
A Daten auslesen/vergleichen Java Basics - Anfänger-Themen 3
D XML von Seite auslesen Jsoup Java Basics - Anfänger-Themen 2
I Druckerauflösung auslesen - mittlerweile möglich? Java Basics - Anfänger-Themen 4
B WSDL auslesen? Java Basics - Anfänger-Themen 8
D Methoden Textdokument erstellen und auslesen. Java Basics - Anfänger-Themen 46
B HTML Code / Seite auslesen und JAVA Objekte erstellen Java Basics - Anfänger-Themen 12
S Datein auslesen und verarbeiten Java Basics - Anfänger-Themen 1
J Geld speichern und wieder auslesen Java Basics - Anfänger-Themen 10
S CSV auslesen UTF-8 Problem Java Basics - Anfänger-Themen 7
D Datei auslesen & Werte in Variable speichern Java Basics - Anfänger-Themen 12
K String buchstaben auslesen Java Basics - Anfänger-Themen 9
S Amazon Produktbeschreibung auslesen und nach Keywords suchen Java Basics - Anfänger-Themen 2
x-tshainge Interface Wie kann ich aus Textfeldern auslesen Java Basics - Anfänger-Themen 6
Z Ersten Buchstaben eines Elements eines String-Arrays auslesen Java Basics - Anfänger-Themen 5
B .txt. Datei auslesen und bestimmten Wert wiedergeben Java Basics - Anfänger-Themen 5
CptK x wert eines Bildes auslesen Java Basics - Anfänger-Themen 1
T Website auslesen Java Basics - Anfänger-Themen 2
T String auslesen bzw. überprüfen Java Basics - Anfänger-Themen 1
L CSV Auslesen Java Basics - Anfänger-Themen 5
B Auslesen von PDF / Bilder Java Basics - Anfänger-Themen 5
das_leon Alle Zeilen einer CSV-Datei auslesen Java Basics - Anfänger-Themen 1
D Mit Java HTML bzw Javascript auslesen Java Basics - Anfänger-Themen 1
F Arrays Sätze speichern und einzelne Worte mit Index Angabe auslesen Java Basics - Anfänger-Themen 4
F Zwischenwerte aus Browser auslesen Java Basics - Anfänger-Themen 19
S Jede Ziffer einer Zahl auslesen, damit rechnen und beim Ergebnis wiederholen ? Java Basics - Anfänger-Themen 20
G Servlet - externe HTML (URL) auslesen Java Basics - Anfänger-Themen 1
T class Datei auslesen Java Java Basics - Anfänger-Themen 5
P Liste auslesen und in Variablen speichern Java Basics - Anfänger-Themen 7
D String erste Zahl mit LKZ auslesen lassen Java Basics - Anfänger-Themen 36
J Hashmap auslesen Java Basics - Anfänger-Themen 7
J Auslesen/speichern und wieder einlesen Java Basics - Anfänger-Themen 7
D String untereinander auslesen lassen Java Basics - Anfänger-Themen 2
M Aus Datei auslesen und untersuchen ob diese Zeile schon vorhanden ist Java Basics - Anfänger-Themen 3
DaCrazyJavaExpert Variablen Zahlen aus Strings auslesen Java Basics - Anfänger-Themen 4
J Informationen aus Webseiten auslesen Java Basics - Anfänger-Themen 1
S Text aus einer HTML Datei auslesen Java Basics - Anfänger-Themen 1
M Einzelne Pixel in einem Bild auslesen und bearbeiten Java Basics - Anfänger-Themen 1
dragonfight86 Erste Schritte OpenDocument auslesen Java Basics - Anfänger-Themen 13
I Texte mit Absätzen in Dateien speichern und auslesen Java Basics - Anfänger-Themen 1
W DNS Name auslesen + weitere Anfängerfrage Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben