Tchart verändern

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Tchart verändern

Beitrag von michael76 »

Hallo!

Ich bin neu hier da ich vor einem Problem stehe und dazu im Netz nicht wirklich was finden konnte. Meine Aufgabe besteht darin: Eine Textdatei mit Werten einzulesen, in einem Chart darzustellen, die Werte anpassen und zurück in die Datei zu schreiben. Das Auslesen der Datei und speichern sollte mir keine Probleme breiten. Hab hier schon Erfahrung in der Programmierung von Mikrocontrollern. Zudem kann ich einiges mit Pascal (aber eher für Roboter- und SPS-Steuerungen) und vor langer Zeit hatte ich mal etwas mit Delphi zu tun. Meine Fragen: Wo soll ich die Daten zwischenspeichern? Wie macht man das am besten? Mein Gedanke: In einem Array und dies als Datenquelle für den Chart hernehmen. Gibt es eine Möglichkeit die Datenpunkte in dem Chart mit der Maus zu verschieben? Hat hier jemand mal einen Anhaltspunkt für mich?

Ich danke schon mal
Grüße Michael

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

Re: Tchart verändern

Beitrag von wp_xyz »

Wenn du Daten eines Chart "live" verändern möchtest, überträgst du die eingelesenen Daten direkt in die entsprechende Series mit "Series.AddXY()"; es gibt zwar noch andere Möglichkeiten, aber dann ist es aufwendiger, die Daten interaktiv zu ändern. Also z.B. so:

Code: Alles auswählen

const
  Datei = 'Daten.txt';

procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStringList;
  sa: TStringArray;
  x, y: Double;
  i, j: Integer;
  res: Integer;
begin
  List := TStringList.Create;
  try
    List.LoadFromFile(Datei);
    sa := List[0].Split(';');
    Chart1.BottomAxis.Title.Caption := sa[0];
    Chart1.BottomAxis.Title.Visible := true;
    Chart1.LeftAxis.Title.Caption := sa[1];
    Chart1.LeftAxis.Title.Visible := true;
    for i := 1 to List.Count-1 do
    begin
      sa := List[i].Split(';');
      val(sa[0], x, res);
      val(sa[1], y, res);
      Chart1LineSeries1.AddXY(x, y);
    end;
  finally
    List.Free;
  end;
end;
Die Daten werden dann intern in der Series gespeichert, du kannst sie über Series.XValue[index] bzw. Series.YValue[index] lesen und beschreiben.

Das interaktive Ändern der Daten geht ohne eine Zeile Code mit den ChartTools: Klicke ein TChartToolset aufs Formular und trage seinen Namen in der Eingeschaft Toolset des Chart ein. Ein Doppelklick auf dem Toolset öffnet den zugehörigen Editor, in dem du auf '+ Hinzuf' klicken und den Eintrag "Datenpunkt verschieben" musst. Wenn der zugehörige Eintrag im Objektbaum über dem Objektinspektor ausgewählt ist, siehst du die Eigenschaften des "DatapointDragTool"s. Gehe zu "Shift" und wähle die Tastenkombination, mit der das Tool aktiv sein soll, z.B. ssLeft und ssCtrl. Wenn das Programm läuft, kannst du mit der Maus über einen Datenpunkt fahren, bei gedrückter Ctrl-Taste (ssCtrl) die linke Maustaste drücken und den Punkt an die neue Stelle schieben. Mit GrabRadius kannst du die Genauigkeit einstellen, mit der ein Datenpunkt getroffen werden muss. Um nur das vertikale Veschieben zuzulassen, kannst du DistanceMode auf cdmOnlyY einstellen.

Um die Datenpunkt einer LineSeries besser erkennen zu können, kannst du deren Eigenschaft "ShowSymbols" einschalten und über die Eigenschaft "Pointer" das Aussehen verändern.

Um die geänderten Daten in die Datei zurückzuschreiben, durchläufst du die Datenpunkte vom 1., (index 0) bis zum letzten (index ist Series.Count-1) und schreibst sie in die Datei, etwa so:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
var
  F: TextFile;
  i: Integer;
  x, y: Double;
begin
  AssignFile(F, Datei);
  Rewrite(F);
  WriteLn(F, Chart1.BottomAxis.Title.Caption, ';', Chart1.LeftAxis.Title.Caption);
  for i := 0 to Chart1LineSeries1.Count-1 do
  begin
    x := Chart1LineSeries1.XValue[i];
    y := Chart1LineSeries1.YValue[i];
    WriteLn(F, x:0:3, ';', y:0:3);
  end;
  CloseFile(F);
end; 
Ein ausführbares Beispies ist angehängt. Damit die Änderung der Daten nicht unabsichtlich geschieht, ist eine Checkbox vorgesehen, die erst markiert werden muss.
Dateianhänge
Lesen_Ändern_Schreiben.zip
(3 KiB) 82-mal heruntergeladen
Zuletzt geändert von wp_xyz am So 20. Dez 2020, 23:42, insgesamt 1-mal geändert.

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

WOW!!!
So eine ausführliche Antwort hatte ich nicht erwartet. Meine Kernfrage hast du perfekt beantwortet! Die TChartToolset ist genau das was ich gesucht habe. Das Projekt selber war zwar leer nach dem öffnen, den Quelltext der Unit konnte ich mir jedoch ansehen und adoptieren. Werde mich jetzt erstmal mit dem Einlesen der Datei beschäftigen. Hier muss ich mir die Struktur der Quellfiles genau ansehen und die benötigen Werte herrausfiltern.

Ich muss jetzt erstmal meine "Hausaufgaben" machen, was sicher ein paar Tage dauern wird. Falls noch Fragen werde ich mich wieder melden....

Herzlichen Dank wp_xyz für die tolle Hilfe!

Grüße Michael

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

Re: Tchart verändern

Beitrag von wp_xyz »

michael76 hat geschrieben: So 20. Dez 2020, 22:47 Das Projekt selber war zwar leer nach dem öffnen, den Quelltext der Unit konnte ich mir jedoch ansehen und adoptieren.
Mist, das passiert mir immer wieder. Ich arbeite mit Lazarus Trunk, wo die Struktur der xml-Dateien geändert wurde, und vergesse immer, das Kompatibilitäts-Häkchen in den Projekt-Optionen zu setzen. Ich habe nun im vorigen Beitrag den Anhang gegen den richtigen ausgetauscht.

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

So, jetzt muss ich doch nochmal Nachfragen, da sich zwei weitere Probleme aufgezeigt haben. Um die Veränderung des Charts zu veranschaulichen, hab ich eine zweite Series auf den Chart gelegt. Diese soll jedoch noch mit der Maus änderbar sein. Gibt es da eine Möglichkeit um das für eine Series auszuschalten?
Wenn ein Punnkt verschoben wurde, würde ich gerne die Daten in einem Memo oder einer StringList aufbereiten. Dazu bräuchte ich jedoch die Info, welcher Punkt zuletzt angewählt war. Wie komme ich an diese Information?

Vielen Dank für die super Hilfe bisher!
Grüße Michael

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

Re: Tchart verändern

Beitrag von wp_xyz »

michael76 hat geschrieben: Mo 21. Dez 2020, 19:40 So, jetzt muss ich doch nochmal Nachfragen, da sich zwei weitere Probleme aufgezeigt haben. Um die Veränderung des Charts zu veranschaulichen, hab ich eine zweite Series auf den Chart gelegt. Diese soll jedoch noch mit der Maus änderbar sein. Gibt es da eine Möglichkeit um das für eine Series auszuschalten?
Jedes (?) ChartTool hat eine Eigenschaft "AffectedSeries", das listet die Nummern der Series, die auf das Tool reagieren. Die Nummern beginnen mit 0 und sind mit Komma (? - evtl auch Strichpunkt, oder |) getrennt. Wenn du also zuerst die veränderbare Series erzeugt hast, dann hat diese die Nummer 0; die andere, nicht veränderbare Series hätte die Nummer 1. Als AffectedSeries müsstest du '0' somit eintragen. Zur Not etwas experimentieren.
michael76 hat geschrieben: Mo 21. Dez 2020, 19:40 Wenn ein Punnkt verschoben wurde, würde ich gerne die Daten in einem Memo oder einer StringList aufbereiten. Dazu bräuchte ich jedoch die Info, welcher Punkt zuletzt angewählt war. Wie komme ich an diese Information?
Das DatapointDragTool hat ein Ereignis OnDrag. Ohne das jetzt ausprobiert zu haben, kommt das meiner Meinung nach, wenn die Maus wieder losgelassen wird. Im Parameter AGraphPoint stehen die Koordinaten des neuen Punkts.

Ich hänge hier mal die "offizielle" Dokumentation rein: https://wiki.lazarus.freepascal.org/TAC ... umentation

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

Und noch eine Frage: Gibts die Möglichkeit, das die Punkte nur auf ganze Zahlen verschoben werden können? Z.B. Nur 1,2,3,4,... und nicht 1,5 oder 1,6

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

Vielen Dank, so habe ich jetzt mal ein paar Anhaltspunkte, mit denen ich etwas Probieren kann. Die ganzen Funktionen haben so viele Eigenschaften, da ist man als Anfänger ja schnell überfordert....

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

Re: Tchart verändern

Beitrag von wp_xyz »

michael76 hat geschrieben: Mo 21. Dez 2020, 20:12 Und noch eine Frage: Gibts die Möglichkeit, das die Punkte nur auf ganze Zahlen verschoben werden können? Z.B. Nur 1,2,3,4,... und nicht 1,5 oder 1,6
Da bist du mit dem schon erwähnten OnDrag-Ereignis an der richtigen Stelle. Der GraphPoint-Parameter ist "var", d.h. du bekommst den Wert, den das Tool gefunden hat, als Eingabe, und kannst dann den Wert so lassen - oder ihn nochmals verändern. Die folgende Routine übergibt der aufrufenden Routine nur den ganzzahligen Teil der x-Koordinaten:

Code: Alles auswählen

procedure TForm1.ChartToolset1DataPointDragTool1Drag(
  ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint);
begin
  AGraphPoint.X := round(AGraphPoint.X);
    // der y-Wert bleibt unverändert.
end; 

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

Perfekt! Damit komm ich jetzt schon sehr weit.
Gibts jetzt noch eine Möglickeit an den Index des veränderten Punktes der Series zu kommen? Ich hab das mal so versucht:

Code: Alles auswählen

procedure TForm1.ChartToolset1DataPointDragTool1Drag(
  ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint);
var
  index : integer;
begin
  index := TDataPointDragTool.Index;
  index := TDataPointDragTool.Series.Index;
end; 
Beide Möglichkeiten werden mit der Fehlermeldung nicht compiliert:
unit1.pas(134,41) Error: Only class methods, class properties and class variables can be referred with class references

Grüße Michael

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Tchart verändern

Beitrag von Sieben »

Nicht den Typ / die Klasse aufrufen, sondern die Instanz / Variable. Das wäre dann hier ASender und nicht TDataPointDragTool... aber is ja auch schon spät.

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

Re: Tchart verändern

Beitrag von wp_xyz »

TDataPointDragTool stammt von TDataPointTool ab, und dort gibt es einige zusätzliche public-Properties (die nicht im Objekt-Inspektor stehen):

Code: Alles auswählen

    property NearestGraphPoint: TDoublePoint read FNearestGraphPoint;  // nächster Series-Punkt an Maus
    property PointIndex: Integer read FPointIndex;           // Punkt-Index des getroffenen Punkte
    property Series: TBasicChartSeries read FSeries;   // Series, auf der der Punkt liegt
    property XIndex: Integer read FXIndex;          // Wenn die Series mehrere x-Werte hat: Index des getroffenen x-Werts
    property YIndex: Integer read FYIndex;     // Wenn die Series mehrere y-Werte hat: Index des getroffenen y-Werts
Um den vom DatapointDragTool veränderten Datenpunkt in einem Grid einzutragen, kannst du also - sinngemäß - folgendes machen:

Code: Alles auswählen

procedure TForm1.ChartToolset1DataPointDragTool1Drag(
  ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint);
var
  index: Integer;
begin
  index := ASender.PointIndex;
  StringGrid1.Cells[1, index + StringGrid1.FixedRows] := FormatFloat('0.000', AGraphPoint.X);
  StringGrid1.cells[2, index + StringGrid1.FixedRows} := FormatFloat('0.000', AGraphPoint.Y);
end;  

michael76
Beiträge: 24
Registriert: Fr 18. Dez 2020, 21:56

Re: Tchart verändern

Beitrag von michael76 »

Vielen Dank!
Funktioniert jetzt schon einigermaßen so wie ich es möchte. Werde die nächten Tag weiter am Projekt arbeiten und mich melden fals noch Fragen.

Top Hilfreiche Antworten von Euch!!!

Grüße Michael

Antworten