TAChart - TChartToolSet - DataPointCrosshairTool

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von h-elsner »

Ich möchte mit den CrosshairTool den Index eines Datenpunktes bestimmen. Ich habe eine CSV Datei mit verschiedenen Werten, die einerseits in einem StringGrid dargestellt werden und andererseits in einem Chart mit mehreren BarSeries und zwei LineSeries. Alle haben die gleiche X-Achse (Zeit-Achse). Mich interessiert nur der Index des X-Wertes.

Das CrosshairTool hat DistanceMode=cdmOnlyX, um überall und nicht nur auf den Linien den X-Wert zu erfassen, sowie Shape=ccsVertical. Rest ist default.

Ganz simpel habe ich mir gedacht, den PointIndex zu nehmen. Der liegt aber um einige Datenpunkte daneben. Bei OnBeforeMouseMove und OnAfterMouseMove viel, bei OnDraw ist es etwas genauer, aber eben auch daneben.

Code: Alles auswählen

procedure TForm1.ChartToolset2DataPointCrosshairTool1Draw(ASender: TDataPointDrawTool);
begin
  SpinEdit3.Value:=ASender.PointIndex;
end;
 


Was mache ich falsch bzw. wie bekommt man den genauen Index des datenpunktes auf der X-Achse?

Gruß HE

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

Re: TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von wp_xyz »

PointIndex ist schon richtig. Aber TBarSeries ist etwas komplizierter, weil der eigentliche Datenpunkt am Ende in der Mitte des Balkens liegt (da wo eine LineSeries den Punkt zeichnen würde), was der User natürlich nicht weiß. Du musst darauf achten, dass sowohl bei der Barseries als auch beim CrosshairTool die Option nptCustom im Property ToolTarget bzw Targets gesetzt ist. Damit wird bei TBarSeries die spezielle Routine durchlaufen, die prüft, ob der Click im Balkeninneren erfolgt ist.

Den DistanceMode würde ich unverändert lassen, ich bin nicht sicher, ob das mit den ToolTargets nicht beeinflusst wird.

Es gibt dazu ein Demo-Programm im Ordner components/tachart/demo/barseriestools. Das Programm verwendet zwar kein CrosshairTool, sondern ein DatapointHintTool, ein DatapointClickTool und ein DatapointDragTool, das Vorgehen sollte aber dasselbe sein.

Achtung: ToolTarget gibt es noch nicht allzulange, es muss mindestens Laz 1.8.0 sein.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von h-elsner »

Danke für die schnelle Antwort.

Targets ist auf default: [nptPoint,nptXList,nptYList,nptCustom]. Ich habe aber auch alle anderen Varianten ausprobiert.

Es ist immer die LineSerie1 (und 2 auch) von vorn bis hinten vorhanden. Kann man das Ermitteln des X-Indexes darauf beschränken?
Wozu ist AffectedSeries und was muss man da eintragen? Egal was ich schreibe, es steht immer '-' drin.

Was mir auch aufgefallen ist, beim CrosshairPen wird die Color nicht genommen, die senkrechte Linie bleibt schwarz. Width jedoch funktioniert.

Ich habe leider noch ein weiteres Problem mit dem CrosshairTool, aber ich denke, da ist es besser einen neuen Threat aufzumachen und alles der reihe nach ;-).

Gruß HE

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

Re: TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von wp_xyz »

In der Anlage habe ich ein Projekt zusammengeklickt, bei dem eine BarSeries hinten (ZOrder) und zwei LineSeries vorne liegen. In der Standardkonfiguration schnappt sich die BarSeries immer den CrosshairCursor und gibt ihn nicht mehr her, wenn Punkte der LineSeries auf dem Balken liegen. Als Abhilfe kann man nptCustom beim CrosshairTool oder der BarSeries löschen (da keine weiteren Series im Chart sind, die nptCustom auswerten, ist es egal, welches), und damit erreicht man, dass die Barseries den Cursor nur noch dann fängt, wenn er sich in der Nähe des Balkenendes befindet.

AffectedSeries ist eine durch komma getrennte Liste der Indices der Series, die von dem Tool beachtet werden. Also, wenn die BarSeries Index 0 hat und die beiden LineSeries 1 und 2, und wenn du möchtest, dass das Crosshairtool nur beiden LineSeries betrachtet, schreibst du in AffectedSeries den String "1,2" (ohne "). Oder andersrum, wenn nur die BarSeries betrachtet werden soll, dann muss AffectedSeries "0" sein.

Das Fadenkreuz wird per Default im XOR-Modus bezeichnet, d.h. CrosshairPen.Color wird ignoriert. Stelle DrawingMode auf tdmNormal um, dann wird CrossHairPen verwendet. In dem Beispiel passt sich die Farbe des Crosshair der Farbe der Series an.
Dateianhänge
Crosshairtool_barseries_lineseries.zip
(2.54 KiB) 80-mal heruntergeladen

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von h-elsner »

Vielen Dank, solche beispiele helfen ungemein. Es ist immer schwierig, durch Rumprobieren zu verstehen, was manche Eigenschaften zu bedeuten haben. Ein Beispiel hilft ungemein.

Ich habe nun den Index der LineSeries eingetragen und der gelieferte Index ist genauer und nicht mehr von der Mausgeschwindigkeit abhängig, aber immer noch leicht daneben. Tja, und wie üblich sitzt der Fehler vor dem Bildschirm. Schlagartig ist mir klargeworden, dass der Index exakt zurückgegeben wird. Das problem ist, dass in den Datensätzen ein paar Dabei sind, die exorbitante Werte haben. Die filtere ich heraus und schreibe sie nicht in den Chart. In der Tabelle stehen sie aber drin und das genau ist der Fehler. Da weichen die Nummern der Datenpunkte voneinander ab, je nachdem, wieviele 'wegoptimiert' wurden. So kann das nix werden. Ich muss jeden Datensatz eintragen und bei unplausiblen Werten im einfachsten Fall den vorherigen Wert nehmen.

AffectedSeries ist aber auf jeden Fall schon mal eine deutliche Verbesserung, wenn man halt weiß, dass das der Index sein muss.

DrawingMode auf Normal ist auch die Lösung für die Farbe. Jetzt verstehe ich auch, warum ich ab und zu mal den Faden in rot gesehen hatte, konnte mir aber keinen Reim darauf machen unter welchen Umständen das war. Das war jeweils nur kurz und meist an den Rändern des Charts.

Das ganz oben angedeutete weitere Problem hat sich auch gelöst. Ich habe das Fadenkreuz per Menü zu- und abgeschaltet mit ChartToolset2DataPointCrosshairTool1.Enabled false/true. Da blieb die senkrechte Haarlinie immer stehen und ging nicht weg. Mit Crosshair.Visible:=false war er zwar dann weg, aber beim Zuschalten und visible:=true hatte ich dann zwei Linien stehen stehen bis ich die Maus bewegt habe. Das hat mich gestört.
Lösung: Statt OnBeforeMouseMove oder OnAfterMouseMove hab ich OnDraw genommen (natürlich aus einem Beispiel von dir hier im Forum). Da wird die Haarlinie sofort auf die neue Postition gesetzt.

Alles gelöst. Danke!

Viele Grüße und schöne Feiertage, HE

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

Re: TAChart - TChartToolSet - DataPointCrosshairTool

Beitrag von wp_xyz »

Es ist ziemlich viel aufgeschrieben (http://wiki.lazarus.freepascal.org/TACh ... tion#Tools), aber in der Kürze vielleicht nicht immer klar.

Antworten