TChart x-Achse eigene Einteilung der Marks definieren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Sonic
Beiträge: 2
Registriert: Mi 17. Dez 2025, 21:45

TChart x-Achse eigene Einteilung der Marks definieren

Beitrag von Sonic »

Hallo zusammen

Ich bin neu mit Lazarus unterwegs. Vor längerer Zeit habe ich mit Delphi programmiert und möchte nun für private Zwecke Lazarus verwenden.
In vielerlei Hinsicht ist das ja identisch. Nicht so bei der TChart-Komponente.

In dem Projekt lese ich eine CSV-Datei in ein Stringrid ein und möchte die Werte der Spalten im Chart graphisch darstellen. Das funktioniert auch schon gut.
Jetzt möchte ich die X-Achse nach eigenen Vorgaben beschriften. Bisher habe ich es nur geschafft, dass die X-Achse immer die aufgeteilte Anzahl der Stringgridrows entspricht. Also der Anzahl eingelesenen Datenpunkte. In meinem Fall sind das zunächst 2880 Werte, wodurch die X-Achsenbeschriftung in hunderter Schritten von 0 bis 2880 erfolgt.
Ich möchte aber die XAchse von 0 bis 48 Beschriften, was dem 60gsten Teil der Anzahl der Messpunkte entspricht.
In Delphi war das für mich früher kein Problem, aber hier steige ich da einfach nicht durch wie ich das bewerkstelligen kann.
Stelle ich im Objektinspektor die Achsenbeschriftung/Einteilung so ein, dass sie von 0 bis 48 geht, wird diese mit der Übergabe der Daten des Stringgrids von 0 bis 2880 geändert.
Auch meine bisherigen Versuche das Anschließend zur Laufzeit mit den gewünschten Werten zu überschreiben sind gescheitert.

Ich habe mir die Beispiele zur Chartkomponente angesehen, jedoch nichts diesbezügliches gefunden.

Grüße
Sonic

wp_xyz
Beiträge: 5326
Registriert: Fr 8. Apr 2011, 09:01

Re: TChart x-Achse eigene Einteilung der Marks definieren

Beitrag von wp_xyz »

Bin nicht 100% sicher, ob ich das Problem richtig verstanden habe, aber ich denke, da gibt es zwei Möglichkeiten:
- Schreibe einen Handler für das Event OnGetMarkText der betreffenden Achse und skaliere dort den Achsentext um:

Code: Alles auswählen

procedure TForm1.Chart1AxisList1GetMarkText(Sender: TObject; var AText: String; AMark: Double); 
// AMark ist der Zahlenwert, der an der Achsenmarkierung steht, AText seine Text-Darstellung
begin
  AText := FormatFloat('0', AMark/60);
end; 
- Da du die Werte ohnehin in einem StringGrid vorhältst, ist es unnötig sie nochmals im Chart zu speichern. Setze eine TUserDefinedChartSource aufs Formular und verbinde sie mit der Source-Eigenschaft der Series. Setze PointsNumber auf die Anzahl der Datenpunkte (= Zeilen des Grid, minus evt. 1 für die FixedRow?). Schreibe einen Event-Handler für OnGetChartData, in dem die Daten aus dem StringGrid extrahiert und an die Series übergeben werden. Wenn du dabei die x-Werte durch 60 dividierst, hast du die gewünschte Achseneinteilung:

Code: Alles auswählen

procedure TForm1.UserDefinedChartSource1GetChartDataItem(
  ASource: TUserDefinedChartSource; AIndex: Integer; var AItem: TChartDataItem);
  // AIndex ist der Index des Datenpunktes, von der Series aus gesehen.
  // TChartDateItem ist ein Record, u.a. mit den X- und Y-Werten des Datenpunktes
var
   s: String;
begin
  // Angenommen, dass die x-Werte in Spalte 0 stehen...
  s := StringGrid1.Cells[0, AIndex+StringGrid1.FixedRows]; 
  AItem.X := StrToFloat(s) / 60;
  // oder falls du gar keine x-Werte hast, sondern den Zeilenindex verwendest:
  // AItem.X := AIndex + StringGrid1.FixedRows;
  
  // y-Werte in Spalte 1
  s := StringGrid1.Cells[1, AIndex + StringGrid1.FixedRows];
  AItem.Y := StrToFloat(s);
end;

Sonic
Beiträge: 2
Registriert: Mi 17. Dez 2025, 21:45

Re: TChart x-Achse eigene Einteilung der Marks definieren

Beitrag von Sonic »

Danke für die Hilfe, ich werde das mal ausprobieren.

Grüße
Sonic

wp_xyz
Beiträge: 5326
Registriert: Fr 8. Apr 2011, 09:01

Re: TChart x-Achse eigene Einteilung der Marks definieren

Beitrag von wp_xyz »

Eine dritte Möglichkeit wäre, die standardmäßig Chartsource der Series zu verwenden (auch wenn dies zu Doppelspeicherung der Daten führt), und beim AddXY die x-Werte wie gefordert zu skalieren:

Code: Alles auswählen

var
  i: Integer;
  s: String;
  x, y: Double;
begin
  Chart1LineSeries1.Clear;
  for i := StringGrid1.FixedRows to StringGrid1.RowCount-1 do
  begin
    // Angenommen, die x-Werte stehen in Spalte 0
    x := StrToFloat(StringGrid1.Cells[0, i]);
    // ... oder es gibt keine x-Spalte, sondern x ist der Zeilenindex
    //x := i;
    // x wie gewünscht transformieren:
    x := x / 60;
    // y-Werte auslesen (Annahme: sie sind in Spalte 1)
    y := StrToFloat(StringGrid1.Cells[1,i]);
    // x,y-Paar in die Series übertragen
    Chart1LineSeries1.AddXY(x, y);
  end;

Sonic
Beiträge: 2
Registriert: Mi 17. Dez 2025, 21:45

Re: TChart x-Achse eigene Einteilung der Marks definieren

Beitrag von Sonic »

Also ich habe die erste Variante ausprobiert und es hat genau das bewirkt, was ich wollte.
Besten Dank noch mal.

Die dritte Variante werde ich auch mal probieren, nur um zu sehen wie das funktioniert.

Grüße
Sonic
Zuletzt geändert von Sonic am Do 18. Dez 2025, 15:52, insgesamt 1-mal geändert.

Antworten