TChart aus TAGraph: LineSeries ineinander

Rund um die LCL und andere Komponenten
Antworten
Rob
Beiträge: 34
Registriert: Fr 8. Jul 2011, 10:45
OS, Lazarus, FPC: Win7, Ubuntu 64 und 32bit Lazarus (immer aktuellstes Release) FPC 2.6.4
CPU-Target: amd_64 und i386
Kontaktdaten:

TChart aus TAGraph: LineSeries ineinander

Beitrag von Rob »

Hallo,

noch ein Problem für das ich gerade kein Lösung finde.

Ich will mehrere Linien in ein Diagramm zeichnen, drei bis vier geanuer gesagt.
Dafür habe ich vier LineSeries angelegt.

Das Problem, Linie 1 ist invertiert, die Linien 2 und 3 sollen an der rechten Achse angezeigt werden, die Linie 4 auch aber mit einer separaten Skala. Linien 2-4 sind nicht invertiert.
Linie 1 geht von 0 bis -400 (0 - Left inverted TChartAxis ) dargestellt von oben nach unten 0-400
Linie 2 und 3 sollen an einer rechten Skala (1 - Right TChartAxis ) von +5 bis +40
Linie 4 rechte Skala (2 - Right TChartAxis ) von 0-100 (Prozentwert)
angezeigt werden.

Die X Achse ist eine (3 - Bottom TChartAxis)Sekundenachse und über alle y Werte synchron. Das funktioniert ;-)

Leider werden die LineSeries aber als "eine" Grafik interpretiert so dass 3-4 oberhalb von Line1 erscheinen und auch den gleichen Skalierungsfakror haben. Meine Y-Skala geht nun von +100 - -400 so dass ich mit Line 2-3 kaum einen Ausschlag sehe.

Was muss ich anstellen dass jeder y Eintrag in der Axislist die Höhe der Garfik komplett ausnutzt?

Ich hoffe ich habe es genau genug beschrieben.

Grüße
Rob

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

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von wp_xyz »

Für mehrachsige Diagramme braucht man die ChartTransformations. VIelleicht hilft dir dieses Tutorial: http://wiki.lazarus.freepascal.org/TACh ... _one_Chart. Wenn nicht, melde dich hier nochmals.

Rob
Beiträge: 34
Registriert: Fr 8. Jul 2011, 10:45
OS, Lazarus, FPC: Win7, Ubuntu 64 und 32bit Lazarus (immer aktuellstes Release) FPC 2.6.4
CPU-Target: amd_64 und i386
Kontaktdaten:

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von Rob »

wp_xyz hat geschrieben:Für mehrachsige Diagramme braucht man die ChartTransformations. VIelleicht hilft dir dieses Tutorial: http://wiki.lazarus.freepascal.org/TACh ... _one_Chart. Wenn nicht, melde dich hier nochmals.
Leider nein. Ich fürchte da funktioniert in TChart irgendetwas nicht.

Ich kann meine Kurven übereinander darstellen, aber sobald ich bei einer der TChatAxis
Achsen inverted auf True setze, sind alle Y-Achsen invertiert.
-egal ob die Achsen auf einer Seite sind, oder eine rechts eine links
-ich habe es auch durch vertauschen der min und max Werte in den TChartAxisTransformations.

Ich brauche eine TChartAxis Invertiert und zusätzlich zwei bis drei nicht invertiert.

Gibt es hier eine Lösung die ich nicht sehe?

Meine Idee ist nun die Kurvenwerte alle zu negieren ( *(-1) ) und dann die Achsenbeschriftung selbst zu erstellen, so dass diese wieder passt.

Grüße
Rob

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

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von wp_xyz »

Da hast du dir aber fürs erste Mal einen harten Brocken ausgesucht...

Man kann einer ChartTransformations-Komponente auch mehrere Transformationen zuweisen, die der Reihe nach abgearbeitet werden. Der "offizielle" Weg daher wäre meiner Meinung nach, der Autoscale-Transformation, die der gespiegelten Achse zugewiesen wird, noch eine LinearAxisTransform nachzuschalten, bei der der Scale-Faktor -1 und der Offset 1 ist: die Autoscale-Transformation skaliert die y-Achse auf den Bereich zwischen 0 und 1, und die LinearTransformation multipliziert die Werte mit -1, so dass sie im Bereich -1...0 liegen, und schiebt sich mit dem Offset +1 wieder in den Bereich 0..1 zurück. Wenn ich das so mache, wird die entsprechende Kurve umgedreht und füllt auch den Chart-Bereich aus, allerdings verschwindet die Achsenbeschriftung...

Sorry - auf die Schnelle kann ich da auch nicht helfen, ich muss mir das mal in einer ruhigen Stunde genauer anschauen. Könntest du einen Bugreport schreiben, damit ich das Problem nicht vergesse?

Ansonsten sollte der von dir vorgeschlagene Workaround (gespiegelte Daten und manuell erzeugte Achsenbeschriftungen - im Event OnMarkToText das Minus-Zeichen wegmachen) problemlos funktionieren.

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

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von wp_xyz »

Brauchst keinen Bug-Report schreiben, ich hab's gefunden, es war leichter als gedacht. Um den Fix zu bekommen, musst du Lazarus trunk aus svn installieren, auf Lazarus 1.2.8 oder 1.4 warten, oder selbst patchen nach folgender Anleitung:
  • Öffne TAChartAxisUtils.
  • Suche die Prozedur "TAxisDrawHelper.DrawMark".
  • Ziemlich bald nach "begin" kommt eine "if"-Anweisung; ersetze diese durch den gleich folgenden Code.
  • Speichern.
  • Übersetze Lazarus neu ("Tools"/"Build Lazarus")

Code: Alles auswählen

 
  if
    not IsInClipRange(coord) or
    ((FValueMax >= FValueMin) and not InRangeUlps(AMark, FValueMin, FValueMax, 2)) or
    ((FValueMax < FValueMin) and not InRangeUlps(AMark, FValueMax, FValueMin, 2))
  then exit;
 
Im Anhang ist ein Beispiel mit einer linearen Funktion an der linken y-Achse und einer Parabel an der rechten y-Achse. Die rechte y-Achse ist invertiert.

Die Invertierung erreichst du folgendermaßen:
  • Zwei ChartTransformations ins Formular klicken
  • Die erste ChartTransformations-Komponenten wird der Transformations-Eigenschaft der linken y-Achse zugeordnet, die zweit der rechten y-Achse.
  • In jede Transformations-Komponente wird eine AutoScale-AxisTransform aufgenommen. Alles bei den voreingestellten Werten lassen.
  • In die zweite Transformations-Komponente kommt zusätzlich eine LinearAxisTransform. Hier musst du "Scale = -1" und "Offset = 1" setzen. Damit wird die entsprechende Kurve gespiegelt und wieder in das durch den AutoScale-Transformation festgelegte Fenster von 0...1 geschoben.
  • Was man gerne vergisst: AxisIndexX und AxisIndexY müssen bei jeder Series auf die Indices der Achsen zeigen, die für die jeweilige Series zuständig ist.
Die Eigenschaft "Inverted" wird für mehrachsige Diagramme ignoriert (genauso wie Chart.Extent).
Dateianhänge
Chart-AutoscaleTransform-Inverted.zip
(2.43 KiB) 47-mal heruntergeladen

Rob
Beiträge: 34
Registriert: Fr 8. Jul 2011, 10:45
OS, Lazarus, FPC: Win7, Ubuntu 64 und 32bit Lazarus (immer aktuellstes Release) FPC 2.6.4
CPU-Target: amd_64 und i386
Kontaktdaten:

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von Rob »

Hi,
wp_xyz hat geschrieben:Brauchst keinen Bug-Report schreiben, ich hab's gefunden,
wow, das nenne ich mal schnelle Reaktion. (im Gegensatz zu TRegistry wo sich nix tut...)

Ich werde es ausprobieren, komme dazu aber wohl erst am Wochenende. Danke!
Allerdings schaue ich mir die offenen Käfer zu TChart trotzdem an, in meinem verzweifelten herumgeklicke an der Komponente hab ich es zweimal geschafft die Lazarus IDE abzuschiessen.
Ich finde im Bugtracker zur FPC nichts über TAChart oder TChart. Wo muss ich Bugs einstellen?

Einen neuen Käfer hätte ich für dich:
Wenn ich mittels eines Scrollers ein Chart auf 0 verkleinere ist alles gut, solange eine Y ChartAxis nicht invertiert ist.
Dann Fehler in TAChartAxis, Exception run error (201) Zeile 590

Code: Alles auswählen

 
procedure TChartAxis.GetMarkValues;
...
  if Inverted then
    for i := 0 to High(FMarkValues) div 2 do begin
 
      t := FMarkValues[i]; <<<< Hier knallt es (Zeile590)
 
      FMarkValues[i] := FMarkValues[High(FMarkValues) - i];
      FMarkValues[High(FMarkValues) - i] := t;
    end;
 
siehe Beispielprojekt, einfach Scroller nach oben schieben (zur Programmlaufzeit, zur Designzeit passiert kein Fehler)
ChartTest1.zip
(126.21 KiB) 71-mal heruntergeladen
Grüße
Rob

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

Re: TChart aus TAGraph: LineSeries ineinander

Beitrag von wp_xyz »

Danke für deine eifrige Debugging-Tätigkeit. Das Problem könnte sein, dass kaum jemand mit invertierten Achsen arbeitet und diese Fehler daher noch nicht gesehen worden sind.

Den von dir hier berichteten Fehler wirst du los, indem du die zitierte Zeile "if Inverted then ..." änderst zu

Code: Alles auswählen

 
  if Inverted and (Length(FMarkValues) > 0) then  ....
 
Ich werd's gleich hochladen. [EDIT]Ist als revision 46892 im trunk.

Den Bug-Tracker findest du unter http://bugs.freepascal.org. "Report Issue" und den Anweisungen folgen; es gibt eine Rubrik speziell für TAChart. In der Regel solltest du ein Mini-Projekt beifügen, das den Fehler zeigt - ohne das landet der Report in der Regel ganz unten im Stapel. Wenn du aktiv an der Entwicklung von Lazarus teilnehmen willst, kannst du selbst versuchen den Fehler zu finden und einen Patch anhängen (diesen immer relativ zur aktuellen trunk-Version im svn). Ein Hinweis noch aus eigener Erfahrung: den Report vor dem Abschicken mindestens dreimal durchlesen, man kann normalerweise hinterher nichts mehr korrigieren...
Ich finde im Bugtracker zur FPC nichts über TAChart oder TChart.
Du musst im BugTracker auch immer das Projekt und die Kategorie richtig einstellen - ist wirklich etwas unübersichtlich... Unter "FPC" wirst du nichts über TAChart finden, weil das da nicht hingehört. Höchstens unter "LCL", "Packages", oder "TAChart". Zur Zeit sollte das meiste aber abgearbeitet sein.

Antworten