Liniendiagramm

03/07/2008 - 00:13 von Sachsenhessi | Report spam
Hallo,

vielleicht eine etwas einfache Frage, aber ich hatte bisher mit Grafik noch
nix zu schaffen.
Problem:
Ich habe ein Array (oder DataSet) mit
(1.) Datum/Uhrzeit (DateTime z.B. 10.06.2008 08:25)
(2.) Wert (numerisch z.B. 10,5)
Daraus muß ein Liniendiagramm erstellt werden.
Die Anzahl der Messwerte ist variabel.
(und ausdruckbar sollte es auch noch sein)
Es handelt sich um eine WindowsForm.

Hat jemand zufàllig ein Stückchen Beispielcode, oder einen guten Link der
mir weiterhelfen kann ?

Danke im Voraus
Frank
 

Lesen sie die antworten

#1 Karsten Sosna
03/07/2008 - 07:02 | Warnen spam
"Sachsenhessi" schrieb im Newsbeitrag
news:
^^^^^^^^^^^^^^^^^^
Du erhöhst Deine Chance das Deine Frage über gelessen und qualifiziert
beantwortet wird, in dem Du hier Deinen vollen Namen(Vor- und Zuname)
einstellst.

vielleicht eine etwas einfache Frage, aber ich hatte bisher mit Grafik
noch
nix zu schaffen.
Problem:
Ich habe ein Array (oder DataSet) mit
(1.) Datum/Uhrzeit (DateTime z.B. 10.06.2008 08:25)
(2.) Wert (numerisch z.B. 10,5)



Vielleicht ein List(Of MeineParameter)?

Daraus muß ein Liniendiagramm erstellt werden.


Und, wo ist das Problem. ;=)

Die Anzahl der Messwerte ist variabel.



Und

(und ausdruckbar sollte es auch noch sein)



Und

Es handelt sich um eine WindowsForm.




Und

Hat jemand zufàllig ein Stückchen Beispielcode, oder einen guten Link der
mir weiterhelfen kann ?



Nö. ;=)

Gezeichnet wird im Paint-Event oder in der Methode OnPaint. Hier werden nur
Daten anzeigt aber nicht berechnet oder eingestellt.
\\\
Private myParameters As New List(Of Integer)

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or
ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint, True)
Me.UpdateStyles()

'Testdaten
For a As Single = 0 To 360 Step 0.5
myParameters.Add(CInt(Math.Sin(a * Math.PI / 180) * 100))
Next
End Sub

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint() 'Basisklassenaufruf verhindern
e.Graphics.Clear(SystemColors.Window)
e.Graphics.TranslateTransform(0, 250)
e.Graphics.ScaleTransform(1, -1)

Using Pen As New Pen(Color.Blue)
For i As Integer = 1 To myParameters.Count - 1
e.Graphics.DrawLine(Pen, i - 1, myParameters(i - 1), i,
myParameters(i))
Next
End Using
End Sub
///
Das Prinzip ist immer das Gleiche. Daten werden irgendwo zusammengestellt,
aber NICHT!!! in der Zeichenroutine. Will man das Neuzeichnen der Daten
erreichen ruft man einfach [Control/Form]Invalidate auf.
\\\
Private blnSinCos as Boolean

Private Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click
myParameters.Clear()
'Testdaten
If blnSinCos Then
For a As Single = 0 To 360 Step 0.5
myParameters.Add(CInt(Math.Sin(a * Math.PI / 180) * 100))
Next
Else
For a As Single = 0 To 360 Step 0.5
myParameters.Add(CInt(Math.Cos(a * Math.PI / 180) * 100))
Next
End If
blnSinCos = Not blnSinCos
Me.Invalidate()

End Sub
///
Umso aufwendiger die Daten umso aufwendiger wird die Zeichenroutine. Eine
Darstellung einer CAD-Zeichnung kommt hier ohne enormen Performanceverlust
nicht unter einige Dutzend Programmzeilen aus. Der Grund liegt darin zu
prüfen ob etwas zu zeichnen ist. Die Prüfung làuft aber schneller ab als der
Zeichenvorgang. Analog gilt hier zur Anfnahme der zuzeichnende Objekte
typengerechte Auflistungen zu benutzen, diese werden schneller durchlaufen
als bspw. eine DataTable. Aufwendiger Code bedeutet an der Stelle nicht
Performanceverlust in Sachen Geschwindigkeit, folgender Code sollte das
veranschaulichen:
\\\
If blnSinCos Then
For a As Single = 0 To 360 Step 0.5
myParameters.Add(CInt(Math.Sin(a * Math.PI / 180) * 100))
Next
Else
For a As Single = 0 To 360 Step 0.5
myParameters.Add(CInt(Math.Cos(a * Math.PI / 180) * 100))
Next
End If
'oder
For a As Single = 0 To 360 Step 0.5
If blnSinCos Then myParameters.Add(CInt(Math.Sin(a *
Math.PI / 180) * 100))

myParameters.Add(CInt(Math.Sin(a * Math.PI / 180) * 100))
Else
myParameters.Add(CInt(Math.Cos(a * Math.PI / 180) * 100))

End If
Next
///
Beide Programmteile machen das Gleiche, jedoch wird der erstere Code
schneller ausgeführt obwohl er mehr Programmzeilen beinhaltet. Der Grund
liegt in der Abfrage. Bei Zeichenoperationen schlàgt das dann massiv zu
Grunde.
Gruß Scotty

Ähnliche fragen