LineSeries einzelnen Datenpunkt markieren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

LineSeries einzelnen Datenpunkt markieren

Beitrag von ErnstVolker »

Guten Abend,

ich habe schon das Forum nach TAChart etc. durchsucht, finde vermutlich den Wald vor lauter Bäumen nicht.

Wie kann man einen einzelnen Datenpunkt einer "TLineSeries" oder auch CubicSpline mit z.B. einem Kringel markieren? Ich möchte entlang einer Kurve nur einige Datenpunkte mit einer Markierung versehen, nicht alle. Wenn ich über den Objektinspektor gehe, kann ich alle Punktmarkierungen anschalten oder ausschalten.

Sofern die Frage im Forum schon beantwortet wurde und ich es nur nicht gefunden habe bitte ich die Administratoren den Beitrag zu löschen.

Vielen Dank

Volker

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

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von wp_xyz »

Man kann zwar im OnCustomDrawPoint-Ereignis der LineSeries sich die Datenpunktsymbole selbst zeichnen, aber ich würde - wie in dem beigefügten Demoprojekt - einfach eine zweite LineSeries nehmen, die nur die hervorzuhebenden Punkte enthält. Mit LineType = ltNone die Verbindungslinien unterdrücken, mit ShowSymbols die Symbole einschalten, mit Pointer.Style = psCircle einen Kreis als Symbol, mit Pointer.HorizSize und Pointer.VertSize = 15 den Kreis größer machen als die normalen Datenpunktsymbole in der eigentlichen Daten-Series, und mit Pointer.Brush.Style = bsClear die Datenpunktsymbole transparent machen. Falls die Kringel an den Rand fallen und abgeschnitten werden, kann man mit Chart.Margins.Top und .Bottom einen weiteren Randbereich einstellen. Falls die Kringel-Series nicht in der Legende auftauchen soll, das mit ShowInLegend = false unterdrücken.
Dateianhänge
Highlight_Datapoints.zip
(2.18 KiB) 99-mal heruntergeladen

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von ErnstVolker »

Hallo wp_xyz,

vielen Dank für Deine Hilfe und den Tipp mit der zweiten Kurve. Die Lösung hat allerdings einen Nachteil denke ich. Ich möchte die Kurve sammt der Markierungen verschieben. Du hattest mir dabei schon Hilfestellung gegeben und einen ChartMover gebastelt.

Ich denke wenn man dann die Kurve verschiebt, bleiben die Punkte zurück, weil diese ja eine zweite Kurve darstellen.

Kann man nicht über DrawPointer-Ereignis psCircle oder PsRectangle über Index zuweisen?

Was ist eigentlich der Unterschied zwischen DrawPointer und CustomDrawPointer? Beim CustomDrawPointer kann man sich vermutlich die Markierung frei ausdenken?

Viele Grüße

Volker

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

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von wp_xyz »

Daran kann ich mich nicht mehr erinnern. Meinst du mit "Kurve verschieben" ein Verschieben der Achsen (mit gedrückter rechter Maustaste) oder einen Wert zu den x-Koordinaten addieren? In letzterem Fall würden in der Tat die beiden Kurven auseinanderlaufen, es sei denn, du veränderst die x-Werte der Kringelkurve genauso.

Aber das ist zugegebenermaßen etwas unschön. Damit käme die erste Variante wieder ins Spiel, nämlich die Datenpunktsymbole selbst zu zeichnen. Das ist nur etwas ungewöhnlich, weil man zum Zeichnen die Methoden des IChartDrawers verwenden muss, nicht die die gewohnten Canvas. Das zuständige Event ist OnCustomDrawPointer, mit dem man sich aber alle Pointer selber zeichnen muss, also auch die ohne Kringel. Da die Legende nichts von den selbstgezeichneten Symbolen mitkriegt, sollte du in der OnCustomDrawPointer-Routine dasselbe Symbol zeichnen, das auch im Objektinspektor eingestellt ist. Im Prinzip könnte man auch das Ereignis OnGetPointerStyle verwenden, aber hier kann man je nach Datenpunkt nur die Symbolart austauschen, nicht aber die Größe, und die Kombination normales Symbol + zusätzlicher Kreis geht schon gar nicht.

Hier ist Beispielcode für das OnCustomDrawPointer-Event:

Code: Alles auswählen

procedure TForm1.Chart1LineSeries1CustomDrawPointer(ASender: TChartSeries;
  ADrawer: IChartDrawer; AIndex: Integer; ACenter: TPoint);
const
  dxL = 16;
  dyL = 16;
var
  dxS, dyS: Integer;
  pen: TPen;
begin
  dxS := TLineSeries(ASender).Pointer.HorizSize;
  dyS := TLineSeries(ASender).Pointer.VertSize;
  ADrawer.Brush := TLineSeries(ASender).Pointer.Brush;
  ADrawer.Pen := TLineSeries(ASender).Pointer.Pen;
  ADrawer.Rectangle(ACenter.X - dxS, ACenter.Y - dyS, ACenter.X + dxS, ACenter.Y + dyS);
    // Ich nehme an, dass im Objekt-Inspector auch ein Rechteck eingestellt ist.
  if AIndex in [2, 5, 8] then begin
    ADrawer.SetBrushParams(bsClear, clNone);
    pen := TPen.Create;
    try
      pen.Style := psSolid;
      pen.Color := clRed;
      pen.Width := 3;
      ADrawer.Pen := pen;
      ADrawer.Ellipse(ACenter.X - dxL, ACenter.Y - dyL, ACenter.X + dxL, ACenter.Y + dyL);
    finally
      pen.Free;
    end;
  end;
end;
Dateianhänge
kringel_series.png
kringel_series.png (7.03 KiB) 1971 mal betrachtet

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von ErnstVolker »

Hallo wp_xyz,

dass Du um diese Uhrzeit immer noch so aktiv bist und mal eben eine Lösung hast, HUT AB!!

Jetzt gehe ich mal in die Falle. Im Anhang noch der ChartMover von Damals.

Vielen Dank für Deine Hilfe. Morgen geht's an's umsetzen.

Volker
Dateianhänge
ChartMover.zip
(138.42 KiB) 88-mal heruntergeladen

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von ErnstVolker »

Guten Morgen,

ich habe Deine Lösung ausprobiert. Die kommt dem schon näher was ich suche, trifft es aber noch nicht ganz. Im Anhang ist ein Bild, wie ich es mit "NSP-Tumbi", ein Scilab-Ableger (so nenne ich es mal) gelöst habe.

Meine Kurve wird mit dt:=1/1000 Schrittweite berechnet. Wenn da die Datenpunkte grundsätzlich eingeschaltet sind ist die Kurve schwarz mit Datenpunkten.

Beim Compilieren erscheint im Nachrichtenfenster, dass die Index-Vorgaben nur zwischen 0 und 255 liegen dürfen. Ich hatte mal 1000, 1500 und 2000 vorgegeben.

In Python mit Matplotlib geht es auch nur mit weiteren Kurven, man kann da keine Individuellen Marker entlang eines Plots darstellen. Ich dachte TAChart wäre da weiter.

Vielen Dank und viele Grüße

Volker
Dateianhänge
NSP.png

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

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von wp_xyz »

ErnstVolker hat geschrieben:Ich dachte TAChart wäre da weiter.

Natürlich. Wer sagt, dass das nicht geht?
Dateianhänge
Highlight_Datapoints-v3.zip
(2.88 KiB) 105-mal heruntergeladen

ErnstVolker
Beiträge: 327
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: LineSeries einzelnen Datenpunkt markieren

Beitrag von ErnstVolker »

Hallo wp_xyz,

da bin ich wieder baff. Da wäre ich so nie im Leben drauf gekommen. Es geht. Ich hatte allerdings die Vorstellung, dass es ein Feature ist, was ggf. häufiger in TAChart nachgefragt werden würde und mit weniger Code erschlagen wäre.
Mit so einem Einzeiler der Art:

Code: Alles auswählen

Chart1LineSeries1.SetMarkerAt(index_x, index_y):=Markerart


Aber so hilft es mir auch weiter. Tausend Dank!!

Schönen Abend und viele Grüße

Volker

Antworten