Hallo, ich würde gerne die Werte einer laufenden Messung nebenbei als (weiter wandernden) Graph darstellen, so wie die CPU-Auslastung im Task-Manager.
z.B.
Die zed-lib ist dafür wohl überdimensioniert/für etwas anderes gedacht.
was gibt es da sonst an fertigen Lösungen?
zeichne das doch mit DrawLine. Punkt array merken. Dann scrollen (einfach Versatz der Grafik ausrechnen, d.h. in diesem Falle ganz einfach im Array an einem anderen Index anfangen und neuzeichnen)
Wenn es zu unverständlich sein sollte, erläutere ich das gerne noch einmal genauer.
Dafür brauchst du keine Lib.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
Würde mich auch interessieren, besonders der Teil bei dem die Linien (neu)gezeichnet werden. Das macht man bestimmt mit GDI, oder?
Weeks of programming can save you hours of planning
ok, hier bitteschön:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MessungsGraph
{
public partial class Form1 : Form
{
List<Point> m_aPoint = new List<Point>();
Timer m_Timer = new Timer();
Random random = new Random((int)DateTime.Now.Ticks);
CustomPanel panel1 = new CustomPanel();
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
for (int i = 0; i < panel1.Width / 2; i += 2)
{
this.panel1.Points.Add(new Point(0,random.Next(0,panel1.Height)));
}
m_Timer.Tick += new EventHandler(m_Timer_Tick);
m_Timer.Interval = 20;
m_Timer.Start();
panel1.Bounds = this.Bounds;
panel1.Parent = this;
panel1.Dock = DockStyle.Fill;
}
void m_Timer_Tick(object sender, EventArgs e)
{
if (this.panel1.Points.Count > 0)
{
this.panel1.Points.RemoveAt(0);
}
this.panel1.Points.Add(new Point(0,random.Next(0,panel1.Height)));
panel1.Invalidate();
}
}
}
Das hier ist die Hauptroutine, wenn wir einen Timer-Tick-Event erhalten, löschen wir den 1. Punkt und fügen einen neuen hinzu. Jetzt müssen wir uns schon nicht mehr um das scrollen, sondern nur noch um das neuzeichnen kümmern.
Da die Control (In diesem Falle das Panel) die Anzeige übernehmen soll,
leiten wir es von Panel ab und können somit DoubleBuffered = true setzen ohne Reflection o. ä. Tricks benutzen zu müssen.
Das Panel enhtält die Punkte Liste und eine Schleife zum Zeichnen der Punkte:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace MessungsGraph
{
class CustomPanel:Panel
{
private List<Point> m_aPoint = new List<Point>();
private int m_nDelta = 0;
public CustomPanel()
{
this.DoubleBuffered = true;
this.BackColor = Color.Black;
}
public List<Point> Points
{
get { return this.m_aPoint; }
}
protected override void OnResize(EventArgs eventargs)
{
m_nDelta = this.Width / this.m_aPoint.Count;
base.OnResize(eventargs);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
for (int i = 0; i < this.m_aPoint.Count - 1; i++)
{
e.Graphics.DrawLine(Pens.Blue, new Point(m_nDelta*i, this.m_aPoint[i].Y), new Point(m_nDelta*i+m_nDelta, this.m_aPoint[i + 1].Y));
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), e.ClipRectangle);
}
}
}
Ausserdem enthält es ein "m_nDelta", das beim Resizen neu berechnet wird.
Probiert es aus, sogar beim Skalieren wird korrekt weitergezeichnet.
Hier das Testprojekt dazu:
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
Hi,
Wieso nimmst nicht Dundas Charts?
Mit den Dingern kann man relativ einfach Graphen jeglicher Art machen. Habe auch mal den CPU Verlauf nachprogrammiert mit so einem Ding. Das ganze hat villeicht 10 min gedauert 🙂.
Ich weiß leider nicht mehr welchen von diesen Charts ich dafür genommen habe, aber wenn es dich interessiert kann ich mal nachschauen.
Wieso soll er jetzt etwas kaufen, das hiermit eigentlich schon gelöst ist!?
Na, das müßt ihr wissen.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
Soo, bin nun endlich mal dazu gekommen mit dem Projekt weiterzumachen.
Danke @Dragon, hilft mir super weiter. Hab aber jetzt noch mal ein Problem (bin ja noch recht neu in OOP, hab wohl irgendwas nicht richtig bekannt gemacht...).
Jedenfalls wollte ich die Funktion die die Werte generiert jetzt mal auslagern (ganz am Ende, die Funktion "Zahlgenerator", jedoch bekomme ich folgende Fehler:
Fehler 1 Die beste Übereinstimmung für die überladene System.Drawing.Point.Point(int, int)-Methode hat einige ungültige Argumente. C:\Dokumente und Einstellungen\Sebastian\Desktop\messungsgraph\MessungsGraph\MessungsGraph\Form1.cs 40 36 MessungsGraph
Fehler 2 2-Argument: kann nicht von "Methodengruppe" in "int" konvertiert werden. C:\Dokumente und Einstellungen\Sebastian\Desktop\messungsgraph\MessungsGraph\MessungsGraph\Form1.cs 40 48 MessungsGraph
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MessungsGraph
{
public partial class Form1 : Form
{
List<Point> m_aPoint = new List<Point>();
Timer m_Timer = new Timer();
Random random = new Random((int)DateTime.Now.Ticks);
CustomPanel panel1 = new CustomPanel();
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
for (int i = 0; i < panel1.Width / 2; i += 2)
{
this.panel1.Points.Add(new Point(0,random.Next(0,panel1.Height)));
}
m_Timer.Tick += new EventHandler(m_Timer_Tick);
m_Timer.Interval = 20;
m_Timer.Start();
panel1.Bounds = this.Bounds;
panel1.Parent = this;
panel1.Dock = DockStyle.Fill;
}
void m_Timer_Tick(object sender, EventArgs e)
{
if (this.panel1.Points.Count > 0)
{
this.panel1.Points.RemoveAt(0);
}
this.panel1.Points.Add(new Point(0,zahlgenerator));
panel1.Invalidate();
}
[b] public int zahlgenerator()
{
return random.Next(0, panel1.Height);
}
[/b]
}
}
this.panel1.Points.Add(new Point(0,zahlgenerator));
fällt dir auf, dass da zwei Klammern fehlen? 😁
nebenbei, warum verwendest du die Funktion in m_Timer_Tick aber nicht im Konstruktur?
Hallo,
sry, mir fällt da nix auf 😄. hab genau so das Projekt von dort oben genommen (lief auch wunderbar) und lediglich aus
void m_Timer_Tick(object sender, EventArgs e)
{
if (this.panel1.Points.Count > 0)
{
this.panel1.Points.RemoveAt(0);
}
this.panel1.Points.Add(new Point(0,random.Next(0, panel1.Height)));
panel1.Invalidate();
}
das gemacht was ich vorher gepostet hab, also den Zufallsgenerator in eine Funktion ausgelagert, deren Rückgabewert der Zufallswert ist (oder besser: sein sollte.. 🤔 )