| |
VB.NET - Ein- und UmsteigerWie kann man Chart Control und DataGridView mit Messwerten aus List of T füllen | | | Autor: Bibobernie | Datum: 02.07.12 15:28 |
| Hallo
Ich schreibe gerade an einem Programm welches Messwerte von einem Gerät (über eine RS232 Schnittstelle) aufnimmt und verarbeitet. Nach anfänglichen Schwierigkeiten funktioniert das schon mal ganz gut. Beim Auswerten stoß ich nun jedoch auf große Probleme. Grob zur Funktion bzw. wo ich hin will:
Das Programm fragt timergeteuert beim Gerät verschiedene Messwerte ab. Diese werden aufbereitet und in entsprechende Listen (List of Double, String oder Integer) eingetragen. Zudem existieren noch zwei Listen für den Laufindex und die Zeit. So kommen im Idealfall alle x Sekunden neue Messwerte hinzu.
Jetzt würde ich gern die Messwerte in Spalten eines DataGridView (DGV) anzeigen lassen. Das DGV habe ich auf der Form platziert und auch entsprechende Spalten manuell eingefügt. Wie ich jetzt aber die Daten in die Spalten rein bekommen soll ist mir ein Rätsel.
Ein ebensolches Rätsel ist die Bindung des Diagramms an die Listendaten. Ist sowas überhaupt möglich oder kann man das vielleicht auch mit den Werten des DGV aktualisieren?
Ahnungsloser ahnungsloser... | |
Re: Wie kann man Chart Control und DataGridView mit Messwerten aus List of T füllen | | | Autor: Manfred X | Datum: 02.07.12 15:34 |
| Hallo!
Willst Du einen Realtimechart erstellen?
In dem Fall kannst Du Dir diesen Themenbaum mal anschauen.
http://www.vbarchiv.net/forum/id22_i78332t78324_real-time-chart-teil1.html
Ansonsten:
Daten in eine Datatable schreiben bzw. aktuelle Daten als neue Zeilen dort anhängen.
Nicht direkt ins Grid. Die direkte Datenbindung von Spalten an das ChartControl ist möglich -
falls das ausreicht (Transformationen? Validierungen? Aussonderung von Fehlmessungen? etc.)
MfG
Manfred
Beitrag wurde zuletzt am 02.07.12 um 15:35:17 editiert. | |
Re: Wie kann man Chart Control und DataGridView mit Messwerten aus List of T füllen | | | Autor: Manfred X | Datum: 02.07.12 15:54 |
| Hallo!
Die Datatable-Klasse steht im Namespace System.Data und wird am besten per
Bindingsource (Windows.Forms) an das Grid (Datasource-Eigenschaft) gebunden.
Das Realtimchart-Beispiel sammelt die übergebenen Werte in einer Liste, die
jederzeit abgefragt und in eine Table eingetragen werden können.
Du kannst das Beispiel aber abwandeln und auch direkt eine Datatable füllen.
MfG
Manfred | |
Re: Wie kann man Chart Control und DataGridView mit Messwerten aus List of T füllen | | | Autor: Bibobernie | Datum: 08.07.12 00:27 |
| So ich habe mich nun endlich mal intensiver mit deinem tollen RealTimeChart auseinander setzen können. Das ganze funktioniert auch schon mal sehr gut. Aber wie das so bei Anfängern ist fragen die hilfreichen Menschen gern mal löcher in den Bauch...:
Und zwar habe ich mir gedacht, das es ja ganz nützlich wäre wenn man sowohl die Anzahl der Werte als auch die ymax/ymin Werte zur Laufzeit ändern könnte (und die Änderungen dann gleich ins Chart übertragen werden). Über ein erneutes initialisieren des Diagramms habe ich das auch schon hin bekommen allerdings dachte ich eher an so was wie eine ReDraw Methode welche die entsprechenden Messwerte (so vorhanden) gleich einträgt.
Da die einzelnen Messwerte ja in einer Datatable gespeichert sind (und zusätzlich auch noch in einer separaten Liste) müsste es doch auch möglich sein z.B. gleich die letzten 10 Werte anzeigen zu lassen, oder? Dachte an so was in der Art:
Public Sub ReDraw(ByVal PointsToShow As Integer, ByVal _
ymin As Double, ByVal ymax As Double,
Optional ByVal ShowPointMarker As Boolean = False)
If Not _Initialized Then Exit Sub 'Kein Chart da > Exit
If DataList.Count < PointsToShow Then > Genügend Messpunkte vorhanden?
MessageBox.Show("Zu wenig Datenpunkte verfügbar!", "Fehler")
Exit Sub
End If
ymax = Math.Max(ymin + 0.0001, ymax)
_maxpoints = PointsToShow : _starttime = Now.Ticks
_showmarker = ShowPointMarker
'Achsen einrichten
With MyBase.ChartAreas(0)
With .AxisX
.CustomLabels.Clear()
.MajorGrid.Enabled = False
.MajorTickMark.TickMarkStyle = Charting.TickMarkStyle.AcrossAxis
.MajorTickMark.Enabled = True
.MajorTickMark.Size = 6
.LabelAutoFitStyle = Charting.LabelAutoFitStyles.DecreaseFont
.IntervalType = Charting.DateTimeIntervalType.Number
.Interval = cTicksPerSecond
End With
.AxisY.Minimum = ymin : .AxisY.Maximum = ymax
End With
MyBase.Series.Clear() : MyBase.Legends.Clear()
'Datenserie einrichten
MyBase.Series.Add(cDataSeries)
With MyBase.Series(cDataSeries)
.ChartType = Charting.SeriesChartType.Line
.BorderWidth = 2
End With
MyBase.Series.Add(cDataSeries2)
With MyBase.Series(cDataSeries2)
.ChartType = Charting.SeriesChartType.Line
.BorderWidth = 2
End With
'Hier müsste ich dann die Daten in das Chart eintragen lassen. Aber wie
' bekomme ich die aus der Datatable rausgelöst?
If Werte = 1 Then 'Nur eine Kurve?
For i As Integer = 0 To PointsToShow 'Wieviel Werte?
t = Zeitwert(i) 'Werte irgendwie aus Datatable holen
v1 = y(-Wert(i))
AddDataPoint(t, v1) 'Werte irgendwie ins Diagramm bekommen
Next
ElseIf Werte = 2 Then 'Zwei Kurven?
For i As Integer = 0 To PointsToShow
t = Zeitwert(i)
v1 = y-Wert1(i))
v2 = y - Wert2(i)
AddDataPoint(t, v1, v2)
Next
End If
_Initialized = True
End Sub Es ergeben sich für mich dabei gleich zwei Probleme. Zum einen weiß ich nicht wie ich die Daten aus der Datetable raus bekomme, Zum anderen muss ich dabei irgendwie feststellen ob die Table einen oder zwei Kurven enthält. Steh da grad ein bissl aufm Schlauch. eventuell ists ja auch ganz einfach aber mir fällt nix ein.
Ahnungsloser ahnungsloser... | |
RealtimeChart II | | | Autor: Manfred X | Datum: 08.07.12 20:09 |
| Hallo!
In dem Fall würde ich eine Datatable an das ChartControl übergeben,
die eine Zeitstempel-Spalte und Messwertspalten umfasst.
Angehängt wird jeweils eine Zeile an die Datatable.
Hier eine Primitiv-Version:
Imports System.Windows.Forms.DataVisualization
Public Class RealTimeChart_II
Inherits Charting.Chart
'Datengrenzen
Private _MinValue As Double = Double.MinValue
Private _Maxvalue As Double = Double.MaxValue
Private _MaxPoints As Integer = 10
'Tabelle und Spaltenangaben
Private _ColumnList As List(Of String)
Private _TimeColumn As String
Private _data As DataTable
Const cDataSeries As String = "DataSeries"
Const cBaseArea As String = "BaseArea"
Const cTicksPerSecond As Long = CLng(10 ^ 7) 'Anzahl Ticks pro Sekunde
Private Sub SetYAxis()
With Me.ChartAreas(cBaseArea)
.AxisY.Minimum = _MinValue : .AxisY.Maximum = _Maxvalue
End With
End Sub
Public Property MinValue() As Double
Set(ByVal value As Double)
If _Maxvalue < value Then _Maxvalue += Math.Abs(value) * 1.1
_MinValue = value
SetYAxis()
End Set
Get
Return _MinValue
End Get
End Property
Public Property MaxValue() As Double
Set(ByVal value As Double)
If _MinValue > value Then _MinValue -= Math.Abs(value) * 1.1
_Maxvalue = value
SetYAxis()
End Set
Get
Return _Maxvalue
End Get
End Property
Public Property MaxPoints() As Integer
Set(ByVal value As Integer)
If value < 5 Then value = 5
_MaxPoints = value
End Set
Get
Return _MaxPoints
End Get
End Property
Public Sub New(ByVal dt As DataTable, _
ByVal ChartMinvalue As Double, ByVal ChartMaxValue As Double, _
ByVal ChartMaxDataPoints As Integer, _
ByVal ChartTimeColumn As String, ByVal ParamArray DataColumns() As _
String)
Me.ChartAreas.Add(cBaseArea)
MinValue = ChartMinvalue : MaxValue = ChartMaxValue
MaxPoints = ChartMaxDataPoints
_TimeColumn = ChartTimeColumn
_ColumnList = New List(Of String)(DataColumns)
_data = dt
Init()
End Sub
Private Sub Init()
'Achsen einrichten
With MyBase.ChartAreas(cBaseArea)
With .AxisX
.CustomLabels.Clear()
.MajorGrid.Enabled = False
.MajorTickMark.TickMarkStyle = Charting.TickMarkStyle.AcrossAxis
.MajorTickMark.Enabled = True
.MajorTickMark.Size = 6
.LabelAutoFitStyle = Charting.LabelAutoFitStyles.DecreaseFont
.IntervalType = Charting.DateTimeIntervalType.Number
.Interval = cTicksPerSecond
End With
.AxisY.Minimum = _MinValue : .AxisY.Maximum = _Maxvalue
End With
Dim colors As New List(Of Color)
With colors
.Add(Color.Red) : .Add(Color.Green) : .Add(Color.Blue)
End With
MyBase.Series.Clear() : MyBase.Legends.Clear()
'Datenserien einrichten
For i As Integer = 0 To _ColumnList.Count - 1
Dim sn As String = cDataSeries & "_" & _ColumnList(i)
MyBase.Series.Add(sn)
With MyBase.Series(sn)
.ChartType = Charting.SeriesChartType.Line
.BorderWidth = 2
.Color = colors(i Mod colors.Count)
End With
Next i
End Sub
Public Sub AddRow(ByVal values() As Object)
_data.Rows.Add(values)
Dim IndexFirstChartPoint As Integer = _
Math.Max(0, _data.Rows.Count - _MaxPoints - 1)
Dim value As Double
For col As Integer = 0 To _ColumnList.Count - 1
With MyBase.Series(cDataSeries & "_" & _ColumnList(col))
.Points.Clear()
For rowindex As Integer = _
IndexFirstChartPoint To _data.Rows.Count - 1
value = CDbl(_data.Rows(rowindex)(_ColumnList(col)))
value = Math.Min(value, MyBase.ChartAreas(0).AxisY.Maximum)
value = Math.Max(value, MyBase.ChartAreas(0).AxisY.Minimum)
.Points.AddXY(CDate(_data.Rows(rowindex)(_TimeColumn)), value)
Next rowindex
End With
Next col
With MyBase.Series(0)
MyBase.ChartAreas(0).AxisX.Minimum = .Points(0).XValue
MyBase.ChartAreas(0).AxisX.Maximum = _
.Points(.Points.Count - 1).XValue
End With
Me.Invalidate()
End Sub
End Class
Beitrag wurde zuletzt am 08.07.12 um 20:10:49 editiert. | |
Anwendungsbeispiel | | | Autor: Manfred X | Datum: 08.07.12 20:13 |
| Hier werden die Anzeigeparameter (Datenlimits, Anzahl angezeigt Punkte)
regelmäßig geändert.
Public Class frmRealtimeChart
Dim rtc As RealTimeChart_II
Dim WithEvents dt As DataTable
Dim WithEvents tim As New Timer With {.Enabled = True, .Interval = 500}
Dim rndm As New Random(123456)
Private Sub frmRealtimeChart_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
dt = New DataTable
dt.Columns.Add("TimeStamp", GetType(Date))
dt.Columns.Add("Channel1", GetType(Double))
dt.Columns.Add("Channel2", GetType(Double))
rtc = New RealTimeChart_II(dt, -100, 100, 10, _
"Timestamp", "Channel1", "Channel2")
rtc.Parent = Me : rtc.Dock = DockStyle.Fill
End Sub
Private Sub tim_Tick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles tim.Tick
If rndm.NextDouble > 0.6 Then
If dt.Rows.Count Mod 10 = 0 Then
With rtc
'Anzeigewerte ändern
.MaxValue = 1.2 * .MaxValue : .MinValue = 1.2 * .MinValue
.MaxPoints += 4
End With
End If
rtc.AddRow({Now, -100 + rndm.NextDouble * 200, -80 + _
rndm.NextDouble * 160})
End If
End Sub
End Class | |
Erläuterungen zum Beispiel | | | Autor: Manfred X | Datum: 10.07.12 14:20 |
| Das habe ich in meinem Beispiel doch gezeigt.
Du benötigst eine Datatable (z.B. ohne Datenzeilen), die über die
Messwertspalten verfügt und eine weitere Spalte (Date)
für den Zeitstempel der Messungen. Sie wird im Konstruktor
der RealtimechartInstanz übergeben, zusammen mit den (im
Chart gewünschten) Spaltennamen.
Das Eintragen der Messwerte vollzieht sich jeweils über ein
Array des Typs Object, in dem - in der korrekten Reihenfolge
der Datenspalten - die Messwerte für einen Zeitpunkt stehen
plus der Zeitpunkt der Messungen. (Diese Messzeiten müssen
natürlich kontinuierlich fortlaufend sein - Realtime eben.)
Das gefüllte Object-Array wird jeweils an die RealtimeChart-Instanz
übergeben (Addrow-Methode). Dadurch werden diese Daten als neue Zeile
in die Table eingetragen und im Chart angezeigt.
Beitrag wurde zuletzt am 10.07.12 um 14:22:00 editiert. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
vb@rchiv CD Vol.6 vb@rchiv Vol.6
Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
Online-Update-Funktion Entwickler-Vollversionen u.v.m.Jetzt zugreifen Tipp des Monats sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere Infos
|