Hallo,
ich habe eine Reihe von Daten in einer TDBF. 1 Feld hat das Format Date, die anderen beiden Float.
Nun brauche ich ein Chart, das in Y die beiden Floatreihen anzeigt und in der X-Achse das Datum aus der TDBF.
Funktioniert im Prinzip auch, außer das das Datum immer am 31.12.99 beginnt. Es gelingt mir nicht das entsprechende Detenssatzdatum anzuzeigen.
Kann jemand helfen?
Manfred
[Gelöst] TChart BottomAxis als Datum
-
- Beiträge: 27
- Registriert: Mi 16. Okt 2019, 15:13
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
[Gelöst] TChart BottomAxis als Datum
- Dateianhänge
-
- graf.pas
- (3.82 KiB) 45-mal heruntergeladen
Zuletzt geändert von ManniSt am Do 20. Jul 2023, 12:47, insgesamt 1-mal geändert.
Re: TChart BottomAxis als Datum
Leider kann ich mit der pas-Datei allein relativ wenig anfangen, besser wäre ein komplettes, auf den Chart reduziertes Projekt, das ich selbst durch den Compiler und vor allem den Debugger jagen kann.
Seltsam ist diese Stelle:
Die LCS_-Dinger sind ListChartSourcen, also wahrscheinlich als Datenquelle für eine Series gedacht. Aber warum nimmst du für x den Schleifen-Index? Denn damit wird der Index im Chart für die x-Achse genommen, und nachdem diese noch, wie ich vermute, durch die TDateTimeIntervalChart-Source läuft, wird daraus ein Datums-Wert gemacht. Aber der Index beginnt bei 0 - und das entspricht dem 30.12.1899!
Wenn ich deinen Code richtig deute, willst du das Feld DATUM entlang der x-Achse und Daten2 in einer Series (Cha_GrafikTaeglkWh) entlang der linken und Daten3 in der anderen Series (Cha_GrafikSummekWh) entlang der rechten Achse plotten.
Dafür brauchst du nur zwei ChartSources, LCS_Taegl und LCS_Summe. LCS_Datum muss weg. Stattdessen wird in jede Source jeweils das Datum als 1.Parameter übergeben (und verwende gleich den richtigen Datentyp für den Feldinhalt, also für das Datum AsDateTime statt des komplizierten Variants Value).
Seltsam ist diese Stelle:
Code: Alles auswählen
LCS_Datum.Add(I,Daten.FieldByName('DATUM').value);
LCS_Taegl.Add(I,Daten.FieldByName('Daten2').value);
LCS_Summe.Add(I,Daten.FieldByName('Daten3').value);
Wenn ich deinen Code richtig deute, willst du das Feld DATUM entlang der x-Achse und Daten2 in einer Series (Cha_GrafikTaeglkWh) entlang der linken und Daten3 in der anderen Series (Cha_GrafikSummekWh) entlang der rechten Achse plotten.
Dafür brauchst du nur zwei ChartSources, LCS_Taegl und LCS_Summe. LCS_Datum muss weg. Stattdessen wird in jede Source jeweils das Datum als 1.Parameter übergeben (und verwende gleich den richtigen Datentyp für den Feldinhalt, also für das Datum AsDateTime statt des komplizierten Variants Value).
Code: Alles auswählen
for I := 1 to N do // TListChartSource füllen
begin
LCS_Taegl.Add(Daten.FieldByName('DATUM').AsDateTime, Daten.FieldByName('Daten2').AsFloat);
LCS_Summe.Add(Daten.FieldByName('DATUM').AsDateTime, Daten.FieldByName('Daten3').AsFloat);
Daten.next;
end;
-
- Beiträge: 27
- Registriert: Mi 16. Okt 2019, 15:13
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: TChart BottomAxis als Datum
Hallo,
danke für die Antwort! Das mit dem Index hatte ich ich mir auch schon gedacht.
Das Teil fängt aber am 01.11.2002 an und nicht mit dem Datum im ersten Datensatz.
Hast Du noch eine Idee? Das komplette Proj hängt dran (Win64).
Gruß
Manfred
danke für die Antwort! Das mit dem Index hatte ich ich mir auch schon gedacht.
Das Teil fängt aber am 01.11.2002 an und nicht mit dem Datum im ersten Datensatz.
Hast Du noch eine Idee? Das komplette Proj hängt dran (Win64).
Gruß
Manfred
- Dateianhänge
-
FotoVoltaik.zip
- (2.33 MiB) 46-mal heruntergeladen
Re: TChart BottomAxis als Datum
Sind der Werte in der "stromernte.dbf" richtig? Am Ende sind einige Records, die vom Tag her in den Juni/Juli 2023 gehören sollten, jedoch ist als Jahr 2002 eingetragen. (siehe Screenshot von MyDBF)
Ein paar Anmerkungen noch zu deinem Code:
Den Namen der DBF-Dateien würde ich nicht im Objekt-Inspektor eintragen, denn dieses Laufwerk gibt es auf einem anderen Rechner nicht. Gib die DBF-Datei stattdessen im Quellcode vor dem Öffnen der Datei ein:
wobei die Verwendung von Application.Location auch gegen einige Regeln verstößt (wenn der Benutzer das Programm in c:\Programme installiert hat er da keine Schreibrechte). Besser wäre sowas wie GetAppConfigDir(true) + 'Daten'; das wäre dann in c:\ProgramData\StromErnte oder mit false als Argument für c:\Users\<login-name>\AppData\Local\Stromernte.
RecordCount eines Datasets muss nicht unbedingt die wahre Anzahl des Dataset angeben. Ich glaube zwar, dass das bei DBF nicht der Fall ist, aber gewöhne dir lieber das richtige Vorgehen an:
Bei einer größeren Anzahl von Records kann die immerwährende Feldsuche in Dataset.FieldByName ganz schön viel Zeit kosten. Besser wäre es, die Felder vor der Schleife zu bestimmen, und in der Schleife nur auf die Feldvariablen zuzugreifen:
Ein paar Anmerkungen noch zu deinem Code:
Den Namen der DBF-Dateien würde ich nicht im Objekt-Inspektor eintragen, denn dieses Laufwerk gibt es auf einem anderen Rechner nicht. Gib die DBF-Datei stattdessen im Quellcode vor dem Öffnen der Datei ein:
Code: Alles auswählen
Stromernte.FilePathFull := Application.Location + 'Daten';
Stromernte.ReadOnly := false;
Stromernte.Active := true;
....
Strompreis.FilePathFull := Application.Location + 'Daten';
Strompreis.Active := true;
...
RecordCount eines Datasets muss nicht unbedingt die wahre Anzahl des Dataset angeben. Ich glaube zwar, dass das bei DBF nicht der Fall ist, aber gewöhne dir lieber das richtige Vorgehen an:
Code: Alles auswählen
StromErnte.First;
while not StromErnte.EoF do
// for I := 1 to N do
begin
LCS_Taegl.Add(Stromernte.FieldByName('DATUM').AsDateTime,Stromernte.FieldByName('TAEGL_KWH').AsFloat);
LCS_Durchschn.Add(Stromernte.FieldByName('DATUM').AsDateTime,Stromernte.FieldByName('DURCHSCHN').AsFloat);
LCS_Median.Add(Stromernte.FieldByName('DATUM').AsDateTime,Stromernte.FieldByName('MEDIAN').AsFloat);
LCS_Summe.Add(Stromernte.FieldByName('DATUM').AsDateTime,Stromernte.FieldByName('Summe_KWH').AsFloat);
StromErnte.next;
end;
Code: Alles auswählen
var
fldDatum, fldTaegl, fldDurchschn, fldMedian, fldSumme: TField;
begin
fldDatum := Stromernte.FieldbyName('DATUM');
fldTaegl := Stromernte.FieldByName('TAEGL_KWH');
fldDurchschn := Stromernte.FieldByName('DURCHSCHN');
fldMedian := Stromernte.FieldByName('MEDIAN');
fldSumme := Stromernte.FieldByName('SUMME_KWH');
Stromernte.First;
while not Stromernte.EOF do
begin
LCS_Taegl.Add(fldDatum.AsDateTime, fldTaegl.AsFloat);
LCS_Durchschn.Add(fldDatum.AsDateTime, fldDurchschn.AsFloat);
LCS_Median.Add(fldDatum.AsDateTime, fldMedian.AsFloat);
LCS_Summe.Add(fldDatum.AsDateTime, fldSumme.AsFloat);
StromErnte.Next;
end;
- Dateianhänge
-
- photovoltaik.png (53.88 KiB) 641 mal betrachtet
-
- Beiträge: 27
- Registriert: Mi 16. Okt 2019, 15:13
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: [Gelöst] TChart BottomAxis als Datum
Hallo,
ich kriege die Krise ... Wenn mann ein paar Tage an sowas rumkaut und sucht, setzt man sich irgendwann mal selbst ne MÜtze auf und sieht nichts mehr ...
Der Fehler war tatsächlich die falsche Datumsangabe am Ende der dbf. Sowas abba auch ...
Danke für die anderen Hinweise!!!
Gruß
Manfred
ich kriege die Krise ... Wenn mann ein paar Tage an sowas rumkaut und sucht, setzt man sich irgendwann mal selbst ne MÜtze auf und sieht nichts mehr ...


Der Fehler war tatsächlich die falsche Datumsangabe am Ende der dbf. Sowas abba auch ...
Danke für die anderen Hinweise!!!
Gruß
Manfred