![]() |
Fortlaufenden Graph zeichnen lassen
Wie der Threadtitel schon sagt suche ich nach einer Möglichkeit, möglichst ohne viel Rechenleistung einen fortlaufenden Graph (wie z.B. im Task Manager bei der CPU-Anzeige) zeichnen zu lassen. Bisher habe ich es mit Canvas auf einem Image versucht, möglicherweise ist meine Idee nicht die beste, denn ich habe, um den Fortlaufeffekt zu verwirklichen, alle bisherigen Pixel einzeln nach links verschieben lassen, sobald der Graph den rechten Rand des Images erreicht. Mein Image hat die ungefähren Maße 200x150 px was ja eigentlich nicht sonderlich groß ist. Selbst bei einem TimerInterval von 1000ms merkt man schon, dass er mit dem Zeichnen nicht ganz nach kommt. Ich möchte jedoch, dass es auch auf schlechteren Rechnern bei größeren Maßen des Images noch flüssig läuft.
Als nächstes habe ich es mit DelphiX probiert, ich dachte, dass das Canvas auf einem DxDraw auch von der Hardware gerendert wird, was aber scheinbar nicht der Fall ist. Die Performance war identisch. Was käme noch an Möglichkeiten in Frage? Ich habe schon daran gedacht ein TRect aus dem bisherigen Image zu schneiden und eben etwas weiter links im Image zu platzieren, was den gleichen Effekt haben sollte. Allerdings scheitere ich dort an der Ausführung :? Wie bekomme ich einen bestimmten Inhalt aus einem Image in das Rect? Und ist das denn überhaupt weniger rechenlastig?
Delphi-Quellcode:
Ich wäre euch unglaublich dankbar wenn ihr eine Lösung für mich parat hättet :)
//Timerereignis, sieht mit DelphiX genauso aus, da ich nicht weiß wie ob es eine Funktion für DX gibt um einfache Linien zu zeichnen wie bei Canvas
if rand=false then ix:=ix+2; image1.Canvas.Pen.color:=clred; if ix=5 then begin image1.canvas.moveto(ix-2,image1.Height); image1.Canvas.lineto(ix,image1.Height-trunc(Temperatur*4)); end else begin //Bei erster Zeichnung image1.Canvas.MoveTo(ix-2,ypsilon); image1.Canvas.LineTo(ix,image1.Height-trunc(Temperatur*4)); ypsilon:=image1.Height-trunc(Temperatur*4); end; //Wenn am Rand angekommen, alle linken Pixel ersetzen (bis auf 2px Rand links) if (ix>=image1.Width-2) then begin for i:=2 to image1.Width do begin for j:=0 to image1.Height do begin image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pixels[i-1,j]:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i,j]; image1.Canvas.Pixels[i-2,j]:=image1.Canvas.Pixels[i,j]; end; end; rand:=true; end; MfG ituser |
Re: Fortlaufenden Graph zeichnen lassen
Du könntest mit der Methode Draw oder BitBlt einen Bildausschnitt verschieben
|
Re: Fortlaufenden Graph zeichnen lassen
|
Re: Fortlaufenden Graph zeichnen lassen
Wow, danke für die schnellen Antworten. Ich werde es gleich mal ausprobieren.
|
Re: Fortlaufenden Graph zeichnen lassen
Da mich die Syntax etwas verwirrt und ich kein gutes Beispiel gefunden habe scheint es nicht zu funktionieren. Hat einer von euch ein funktionierendes Beispiel? Habe folgendes ausprobiert nach einem Thread hier im Forum.
Delphi-Quellcode:
Funktioniert aber leider nicht :-/
image1.Canvas.Pen.color:=clred;
if ix=5 then begin image1.canvas.moveto(ix-2,image1.Height); image1.Canvas.lineto(ix,image1.Height-trunc(Temperatur*4)); end else begin image1.Canvas.MoveTo(ix-2,ypsilon); image1.Canvas.LineTo(ix,image1.Height-trunc(Temperatur*4)); ypsilon:=image1.Height-trunc(Temperatur*4); end; //Wenn am Rand angekommen if (ix>=image1.Width-2) then begin //Einzelne Pixel Methode {for i:=2 to image1.Width do begin for j:=0 to image1.Height do begin image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pixels[i-1,j]:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i,j]; image1.Canvas.Pixels[i-2,j]:=image1.Canvas.Pixels[i,j]; end; end;} //Andere ScrollRect := image1.BoundsRect; ClipRect := image1.BoundsRect; ScrollDC(image1.Canvas.Handle, -2, 0, ScrollRect, ClipRect, 0, @UpdateRect); rand:=true; end; |
Re: Fortlaufenden Graph zeichnen lassen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab das mal mit ner Paintbox und nem temporären Bitmap so gemacht:
Delphi-Quellcode:
Was jetzt OldYPosition und NewYPosition genau sind, ist ja egal. Wenn man da nen zufi-generator drumbaut, sieht es z.B. so aus wie in der exe im Anhang
tmpbmp.Canvas.FillRect(tmpbmp.Canvas.ClipRect);
tmpbmp.Canvas.CopyRect( rect(0,0,Paintbox1.Width-1, Paintbox1.Height), Paintbox1.Canvas, rect(1,0,Paintbox1.Width, Paintbox1.Height)); tmpbmp.Canvas.MoveTo(Paintbox1.Width-2, OldYPosition); tmpbmp.Canvas.LineTo(Paintbox1.Width-1, NewYPosition); BitBlt(Paintbox1.Canvas.handle, 0, 0, tmpbmp.Width, tmpbmp.Height, tmpbmp.Canvas.Handle, 0, 0, srccopy); |
Re: Fortlaufenden Graph zeichnen lassen
Hi ituser,
also bei mir funzt es genau so:
Delphi-Quellcode:
Dabei sind alle Rect's die ClientRects meiner Compo. Mit alternativ für UpdateRect = nil klappt es genau so.
ScrollDC(image1.Canvas.Handle, -2, 0, ScrollRect, ClipRect, 0, @UpdateRect);
Gruß oki |
Re: Fortlaufenden Graph zeichnen lassen
Klappt irgendwie alles nicht so wirklich, wahrscheinlich liegt dann wohl der Fehler in einem anderen Teil der Prozedur, ich poste mal das gesamte Timerereignis... wahrscheinlich hab ich da wieder was vergessen :wall:
@Gausi: Scheinbar vergesse ich bei deiner Version jedes mal was bestimmtes einzubauen, nur was...
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var Dezimalwert: byte; Spannung, Widerstand, Temperatur: double; ScrollRect, ClipRect: TRect; begin {if rand=false then} ix:=ix+2; //Einlesen von Daten {try Dezimalwert:=ADEin; except dezimalwert:=random(30)+1; end;} //Zufällige DAten dezimalwert:=random(10)+90; Spannung:=(DezimalWert/255)*5; Widerstand:=Spannung/Ik; Temperatur:=25+(sqrt(k1*k1-4*k2+4*k2*(Widerstand/2000))-k1)/(2*k2); label5.caption:=inttostr(Dezimalwert); label6.caption:=floattostrf(Spannung,fffixed,6,2)+' V'; label7.caption:=floattostrf(Widerstand,fffixed,6,2)+' Ohm'; label8.caption:=floattostrf(Temperatur,fffixed,6,2)+' °C'; image1.Canvas.Pen.color:=clred; if ix=5 then begin image1.canvas.moveto(ix-2,image1.Height); image1.Canvas.lineto(ix,image1.Height-trunc(Temperatur*4)); end else begin image1.Canvas.MoveTo(ix-2,ypsilon); image1.Canvas.LineTo(ix,image1.Height-trunc(Temperatur*4)); ypsilon:=image1.Height-trunc(Temperatur*4); end; //Wenn am Rand angekommen if (ix>=image1.Width-2) then begin //Einzelne Pixel Methode {for i:=2 to image1.Width do begin for j:=0 to image1.Height do begin image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pixels[i-1,j]:=image1.Canvas.Pixels[i+1,j]; image1.Canvas.Pen.Color:=image1.Canvas.Pixels[i,j]; image1.Canvas.Pixels[i-2,j]:=image1.Canvas.Pixels[i,j]; end; end;} //Andere ScrollRect:=image1.BoundsRect; ClipRect:=image1.BoundsRect; ScrollDC(image1.Canvas.Handle, -2, 0, ScrollRect, ClipRect, 0, nil); end; end; |
Re: Fortlaufenden Graph zeichnen lassen
Schau mal so geht es
Delphi-Quellcode:
Image1.Canvas.Pen.color := clred;
if (ix < Image1.Width - 6) then begin Image1.Canvas.MoveTo(ix - 2, ypsilon); Image1.Canvas.LineTo(ix, trunc(Temperatur)); ypsilon := trunc(Temperatur); end //Wenn am Rand angekommen else begin ScrollRect := Image1.BoundsRect; ClipRect := Image1.BoundsRect; ScrollDC(Image1.Canvas.Handle, -2, 0, ScrollRect, ClipRect, 0, nil); Image1.Canvas.MoveTo(Image1.Width - 6, ypsilon); Image1.Canvas.LineTo(Image1.Width - 4, trunc(Temperatur)); ypsilon := trunc(Temperatur); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz