Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi [XE7, VCL] Wie TChart-Zeichnen beschleunigen? (https://www.delphipraxis.net/185712-%5Bxe7-vcl%5D-wie-tchart-zeichnen-beschleunigen.html)

nuclearping 1. Jul 2015 06:30

[XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo! :)

Ich habe in meinem Projekt drei
Delphi-Quellcode:
TChart
Komponenten. Jedes
Delphi-Quellcode:
TChart
enthält mehrere Serien. Die ersten beiden
Delphi-Quellcode:
TChart
enthalten insg. 5
Delphi-Quellcode:
TLineSeries
. Das dritte eine
Delphi-Quellcode:
TBarSeries
und eine
Delphi-Quellcode:
TLineSeries
.

Diese Charts sind in einem
Delphi-Quellcode:
TPageControl
untergebracht. Jedes Chart hat seine eigene
Delphi-Quellcode:
TTabSheet
Seite. Die Charts werden kontinuierlich mit ausgewerteten Daten gefüttert, die über einen
Delphi-Quellcode:
TThread
von einer USB-Hardware ausgelesen und verarbeitet werden. Dabei nutzt der Thread zur Weitergabe der Daten schon kein
Delphi-Quellcode:
Synchronize
, sondern arbeitet mit
Delphi-Quellcode:
PostMessage
.

Jedoch stelle ich leider fest, dass diese Konstellation zum schreien langsam ist und der Flaschenhals hier in der Zeichnung des (sichtbaren)
Delphi-Quellcode:
TChart
liegt. Ich habe ein Beispielprojekt angehangen, wo das Problem deutlich wird. Zum zeichnen / aktualisieren eines
Delphi-Quellcode:
TChart
benötigt er bei maximierten Fenster (1920x1080) ~300-500ms, selbst nach dem Start der Anwendung, wenn noch nichtmal Daten vorhanden sind. :pale:

Das führt dazu, dass der Wechsel zwischen den
Delphi-Quellcode:
TTabSheet
Seiten hier in meiner Entwicklungs-VM ca. 1 Sekunde dauert. Auch die Buttons, das ganze Fenster usw. reagieren dermaßen verzögert, dass man das keinem anbieten kann. Die VM läuft auf 2/1 CPUs, 8GB RAM; Host-System ist ein i7 4790K @ 4GHz, 16GB RAM. Auf einem Testlaptop beim Kunden sieht das Ganze jedoch genauso aus, sogar noch schlimmer. Dort ging dann nach dem Wechsel zur Diagram-Ansicht nach einer kurzen Zeit garnichts mehr, weil das System mit dem Zeichnen nicht klar gekommen ist.

Den einzigen Geschwindigkeitszuwachs sehe ich, wenn ich das Fenster extrem verkleinere. Aber das ist ja nicht Sinn der Sache.

Habt ihr eine Idee, wie ich das Ganze (um Faktoren) beschleunigen kann? Geht da überhaupt noch was mit TChart? Was nutzt ihr denn für die Darstellung von solchen Daten?

Ich habe hier noch
Delphi-Quellcode:
TMS Advanced Charts
in der Palette. Damit habe ich früher mal gearbeitet, jedoch ziemlich schlechte Erfahrungen mit der ZoomControl gemacht und seither nicht mehr angefasst.

Auch wollte ich die Charts von Lohninger mal probieren. Das scheitert jedoch schon daran, dass ich nach der Installation und dem Öffnen eines Beispielprojekts eine
Delphi-Quellcode:
Zugriffsverletzung bei Adresse 19DB4072 in Modul 'sdlchartpack_rt_104X7.bpl'. Schreiben von Adresse 00000070.
erhalte. Das gleiche auch beim Anlegen eines neuen Testprojekts, mit dem Versuch eine "RChart"-Komponenten auf die Form zu ziehen. Und bei der Deinstallation der Lohninger-Komponenten hat er meinen Delphi-Bibliothekspfad irgendwie geleert und seither funktioniert auch Castalia nicht mehr (ebenfalls Zugriffsverletzung in einer der Castalia-BPLs beim Start von Delphi), auch nicht nach einer De- und Reinstallation. :?

Wäre für jede Hilfe dankbar! :)

Vielen Dank!

ConstantGardener 1. Jul 2015 07:03

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
...also auf den ersten Blick fehlen mir da Series.BeginUpdate und Series.EndUpdate. Das beschleunigt das zeichnen schon etwas. Die LineSeries könntest/solltest Du zu FastLineSeries machen.
Außerdem solltest Du das Scrollen (SetBounds) vor dem EndUpdate handeln, sonnst muss er ja alles nochmal zeichnen.

Sir Rufo 1. Jul 2015 08:23

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Die Optimierungen am Chart sind die eine Sache, der Transport der Werte eine völlig andere.

Man bekommt jedes Control und damit die Anzeige in den Wahnsinn getrieben, wenn man nur schnell genug versucht dort Daten hinein zu pusten. Je aufwändiger das Erzeugen der Darstellung ist, umso schneller erreicht man den Zustand "geht nix mehr".

Darum ja auch die Trennung von Darstellung, Daten und Code.

Der Thread sollte die Daten in einen Speicher schreiben.
Der Speicher signalisiert, dass neue Daten vorhanden sind.
Die Anzeige nimmt dieses Signal zur Kenntnis und stellt die Daten (aus dem Speicher) dar, wenn Zeit dafür da ist.

stahli 1. Jul 2015 08:31

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Also konkrete Hilfe kann ich nicht geben, aber...

Schau mal (wenn Du das irgendwie erkennen kannst), wie oft das Control sich zeichnet. Wenn Du z.B. einem Panel die aktuelle Breite nochmal zuweist, zeichnet es sich (und die Umgebung ebenfalls) nochmal neu.
Wenn das Wiederholt-Neuzeichnen in einem Control gekapselt wäre ist dem vielleicht schlecht beizukommen.

Aber vielleicht kannst Du mit Ersetzen von
Delphi-Quellcode:
MyChart.Widht := 100
durch
Delphi-Quellcode:
if MyChart.Widht <> 100 then
  MyChart.Widht := 100
oder mit ähnlichen Maßnahmen schon etwas erreichen.


Ansonsten wäre es vielleicht möglich, das Chart in einem Thread ein Bitmap erzeugen zu lassen und wenn das fertig ist, dieses in´s Formular zu kopieren. Ist natürlich umständlich und ggf. schwierig, aber vielleicht als Notlösung machbar.

Der schöne Günther 1. Jul 2015 08:55

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Mein 20 Sekunden-Test: Mache ich beim Chart das GDI+-AntiAlias aus, geht die Zeichnzeit von 516ms auf 37ms runter 8-)

(Und mit OpenGL habe ich 0ms)

nuclearping 1. Jul 2015 13:52

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Danke für eure Antworten! :)

Zitat:

Zitat von Der schöne Günther (Beitrag 1307300)
Mein 20 Sekunden-Test: Mache ich beim Chart das GDI+-AntiAlias aus, geht die Zeichnzeit von 516ms auf 37ms runter 8-)

(Und mit OpenGL habe ich 0ms)

Oh man. :shock: Du bist mein Held! Das war es! Vielen Dank! :hello:

Ich hatte schon sowas vermutet, konnte aber auf den ersten Blick nichts finden. Und eine Google-Suche nach TChart AntiAliasing hatte mich eher zu der Annahme geführt, dass man das AntiAliasing erst aktiv einschalten müsste: http://www.teechart.net/support/view...t=13164#p60730
Delphi-Quellcode:
Chart1.Tools.Add(TAntiAliasTool);


Wenn ich aber mal auf das Chart doppelklicke,
Delphi-Quellcode:
Chart -> 3D -> Renderer
da ist dort in der Tat unter GDI+ ein "AntiAlias" Häkchen versteckt. Und siehe da: In der Tat nur 31ms fürs zeichnen. Und wenn ich statt GDI+ nur GDI nehme, schafft er das Ganze sogar auch in 0ms. Wow! :thumb:

Wie schalte ich denn OpenGL ein? Oder gibts das erst ab einer höheren TeeChart Version? Bei mir in der Palette ist nur unter "TeeChart Lite" "TTeeGDIPlus" und bei "Renderer" hatte ich nur "GDI" und "GDI+" in der Liste.

Zitat:

Zitat von Sir Rufo (Beitrag 1307294)
Darum ja auch die Trennung von Darstellung, Daten und Code.

Der Thread sollte die Daten in einen Speicher schreiben.
Der Speicher signalisiert, dass neue Daten vorhanden sind.
Die Anzeige nimmt dieses Signal zur Kenntnis und stellt die Daten (aus dem Speicher) dar, wenn Zeit dafür da ist.

Ja, da hast du auf jeden Fall recht. :)

Das Hauptprogramm macht das auch. Der Thread pusht die verarbeiteten Daten per PostMessage an ein Fenster, was die Werte erstmal in verschiedene
Delphi-Quellcode:
TList<TRecord>
ablegt und dem Frame, wo die Charts draufliegen, danach "bescheid" sagt. Da hatte ich schonmal mit den TimeOuts herumgespielt. Hat nichts gebracht. Weil wie schon gesagt, er brauchte ja für das Darstellen eines nackten Charts schon ~500ms.

Aber siehe oben: Der Tipp von Günther hats gebracht!

Zitat:

Zitat von ConstantGardener (Beitrag 1307278)
...also auf den ersten Blick fehlen mir da Series.BeginUpdate und Series.EndUpdate. Das beschleunigt das zeichnen schon etwas. Die LineSeries könntest/solltest Du zu FastLineSeries machen.
Außerdem solltest Du das Scrollen (SetBounds) vor dem EndUpdate handeln, sonnst muss er ja alles nochmal zeichnen.

Das hatte ich schon probiert und leider keinen signifikanten Unterschied gemerkt. Habs grad eben nochmal reaktiviert, und es macht in der Tat leider keinen Unterschied.

Delphi-Quellcode:
procedure TForm1.Chart_BeginUpdate;
var
  i: Integer;
begin
  for i := 0 to 4 do
    begin
      Chart1.Series[i].BeginUpdate;
      Chart2.Series[i].BeginUpdate;
    end;
end;

procedure TForm1.Chart_EndUpdate;
var
  i: Integer;
begin
  for i := 0 to 4 do
    begin
      Chart1.Series[i].EndUpdate;
      Chart2.Series[i].EndUpdate;
    end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  ST, ET, TT: Cardinal;
begin
  ST := GetTickCount;

  Chart_BeginUpdate;
  try
    PlotMeanData;
    PlotValueData;
    HandleScroll;
  finally
    Chart_EndUpdate;
  end;

  ET := GetTickCount;
  TT := ET - ST;
  Label1.Caption := 'Draw Time: ' + TT.ToString + 'ms';
end;

Der schöne Günther 1. Jul 2015 15:50

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Ich habe TeeChart Pro, kann sein dass es OpenGL bei TeeChart Lite nicht gibt :smile2:

nuclearping 1. Jul 2015 16:27

AW: [XE7, VCL] Wie TChart-Zeichnen beschleunigen?
 
Ok. Danke. Das normale GDI sieht zwar jetzt nicht so schick aus, aber es erfüllt seinen Zweck allemal. :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz