Dynamisches Erstellen von Chart Serien

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von HGR.

    Dynamisches Erstellen von Chart Serien

    Hallo verehrtes Forum,

    ich habe eine Aufgabenstellung bei der ich gerne dynamisch "Series" zu einem "Chart" hinzufügen möchte, je nachdem viele Kurven es zu zeichnen gibt. Des Weiteren möchte ich gerne von allen erstellten Kurven die Anzeige der einzelnen Kurven zur Laufzeit ein- und ausblenden können. Aktuell suche ich nach einem Ansatz, wie ich dies realisieren könnte.

    Hintergrund:
    Wir haben einen Datalogger, der pro Millisekunde bis zu 40 Prozessdaten aufnimmt und puffert realisiert. Wieviele bzw. welche Prozessdaten aufgenommen werden, kann verändert werden und ist daher variable.
    Die Aufzeichnung der Prozessdaten geschieht zunächst auf der ADwin Gold II, einer Echtzeitsteuerung mit recht flotten DSP und mit Ethernet-Anbindung an unsere VB.NET GUI.
    Unsere VB.NET GUI holt die Daten alle 100ms ab und schreibt sie in eine Datei. Es werden nur Wertänderungen geloggt um den die Logdateigröße klein zu halten.

    So ergibt sich folgendes Format der Logfiles:
    Zeitstempel; ID-Prozessdata; VALUE-Processdata; ID-Prozessdata; VALUE-Processdata; ID-Prozessdata; VALUE-Processdata ...etc.

    Ich habe eine Beispiel Datei angehängt!

    Das Loggen funktioniert einwandfrei, jetzt würden wir aber auch ganz gerne diese Daten komfortabel auf unserer GUI visualisieren.

    Ich habe mir hierfür Beiträge vom "Erfinder des Rades" angeschaut wie etwa diesen Hier:

    Chart - Sample

    Ich kann mit meinem Wissensstand schlecht abschätzen ob ich für meinen Verwendungszweck tatsächlich typisierte Datasets benötige oder nicht. Letztendlich möchte ich eine variable Anzahl an XY-Kurven in einem Chart anzeigen (mehr nicht).

    Ich dachte an eine Klasse, die alle Daten sowie eine property "ChartIsVisible" enthält, die dynamisch zur Laufzeit sooft instanziert wird, wie es eben Kurven zum zeichnen gibt.

    Mein Code sieht aktuell wie folgt aus:

    VB.NET-Quellcode

    1. Imports System.Windows.Forms.DataVisualization.Charting
    2. Imports System.IO
    3. Public Class FrmDatalogViewer
    4. Public MetaData As New List(Of String)
    5. Public PDMData As New List(Of String)
    6. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BtLoad.Click
    7. LoadDataFromFile()
    8. DrawChart()
    9. End Sub
    10. Sub LoadDataFromFile()
    11. Try
    12. Dim OFD As New OpenFileDialog()
    13. MetaData.Clear()
    14. PDMData.Clear()
    15. With OFD
    16. .Filter = "CSV-Files (*.csv)|*.csv"
    17. .RestoreDirectory = True
    18. .InitialDirectory = GTG_ODD_DEF_FOCUS_WOBBLE_SAVINGPATH
    19. If .ShowDialog() = Windows.Forms.DialogResult.OK Then
    20. If IO.File.Exists(.FileName) Then
    21. Using reader As StreamReader = New StreamReader(.FileName)
    22. Dim line As String
    23. line = reader.ReadLine ' Read first line.
    24. Dim i As Integer
    25. Do While (Not line Is Nothing) ' Loop over each line in file, While list is Not Nothing.
    26. If i <= 100 Then
    27. MetaData.Add(line) ' Meta
    28. Else
    29. PDMData.Add(line) ' PDM Data
    30. End If
    31. i += 1
    32. line = reader.ReadLine ' Read in the next line.
    33. Loop
    34. End Using
    35. End If
    36. End If
    37. End With
    38. Catch ex As Exception
    39. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    40. End Try
    41. End Sub
    42. Sub DrawChart()
    43. Try
    44. Dim ArrayLength As Integer
    45. Dim TimeInMs As Long
    46. Dim StringArr() As String
    47. Dim TimeStamp As String
    48. Dim TmpString As String
    49. Dim IxXlist As New List(Of Long)
    50. Dim IxYlist As New List(Of Single)
    51. Dim IyXlist As New List(Of Long)
    52. Dim IyYlist As New List(Of Single)
    53. Dim IlXlist As New List(Of Long)
    54. Dim IlYlist As New List(Of Single)
    55. Dim IbXlist As New List(Of Long)
    56. Dim IbYlist As New List(Of Single)
    57. Dim i As Long
    58. For Each element In PDMData
    59. TmpString = PDMData(i)
    60. i += 1
    61. If TmpString <> "" Then
    62. StringArr = TmpString.Split(";")
    63. ArrayLength = StringArr.Length
    64. TimeStamp = StringArr(0)
    65. Dim YValue As Single
    66. For k = 1 To ArrayLength Step 2
    67. Dim idx As Integer
    68. If Integer.TryParse(StringArr(k), idx) Then
    69. If Single.TryParse(StringArr(k + 1), YValue) Then
    70. Select Case idx
    71. Case 2
    72. IxXlist.Add(i)
    73. IxYlist.Add(YValue)
    74. Case 3
    75. IyXlist.Add(i)
    76. IyYlist.Add(YValue)
    77. Case 4
    78. IlXlist.Add(i)
    79. IlYlist.Add(YValue)
    80. Case 5
    81. IbXlist.Add(i)
    82. IbYlist.Add(YValue)
    83. End Select
    84. End If
    85. End If
    86. Next
    87. End If
    88. Next
    89. Chart1.Series.Clear()
    90. Dim SeriesIX = New DataVisualization.Charting.Series()
    91. SeriesIX.ChartType = DataVisualization.Charting.SeriesChartType.Point
    92. SeriesIX.Points.DataBindXY(IxXlist, IxYlist)
    93. Dim SeriesIY = New DataVisualization.Charting.Series()
    94. SeriesIY.ChartType = DataVisualization.Charting.SeriesChartType.Point
    95. SeriesIY.Points.DataBindXY(IyXlist, IyYlist)
    96. Dim SeriesIL = New DataVisualization.Charting.Series()
    97. SeriesIL.ChartType = DataVisualization.Charting.SeriesChartType.Point
    98. SeriesIL.Points.DataBindXY(IlXlist, IlYlist)
    99. Dim SeriesIB = New DataVisualization.Charting.Series()
    100. SeriesIB.ChartType = DataVisualization.Charting.SeriesChartType.Point
    101. SeriesIB.Points.DataBindXY(IbXlist, IbYlist)
    102. ' IX
    103. If CheckBox1.Checked Then
    104. Chart1.Series.Add(SeriesIX)
    105. Else
    106. Chart1.Series.Remove(SeriesIX)
    107. End If
    108. 'IY
    109. If CheckBox2.Checked Then
    110. Chart1.Series.Add(SeriesIY)
    111. Else
    112. Chart1.Series.Remove(SeriesIY)
    113. End If
    114. 'IL
    115. If CheckBox3.Checked Then
    116. Chart1.Series.Add(SeriesIL)
    117. Else
    118. Chart1.Series.Remove(SeriesIL)
    119. End If
    120. 'IB
    121. If CheckBox4.Checked Then
    122. Chart1.Series.Add(SeriesIB)
    123. Else
    124. Chart1.Series.Remove(SeriesIB)
    125. End If
    126. Catch ex As Exception
    127. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    128. End Try
    129. End Sub
    130. Private Sub FrmDatalogger_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    131. End Sub
    132. Private Sub Refresh_Click(sender As Object, e As EventArgs) Handles BtRefresh.Click
    133. DrawChart()
    134. End Sub
    135. End Class



    Ich möchte ganz dringend von solchen Konstrukten wie hier:

    VB.NET-Quellcode

    1. Dim SeriesIX = New DataVisualization.Charting.Series()
    2. SeriesIX.ChartType = DataVisualization.Charting.SeriesChartType.Point
    3. SeriesIX.Points.DataBindXY(IxXlist, IxYlist)
    4. Dim SeriesIY = New DataVisualization.Charting.Series()
    5. SeriesIY.ChartType = DataVisualization.Charting.SeriesChartType.Point
    6. SeriesIY.Points.DataBindXY(IyXlist, IyYlist)
    7. Dim SeriesIL = New DataVisualization.Charting.Series()
    8. SeriesIL.ChartType = DataVisualization.Charting.SeriesChartType.Point
    9. SeriesIL.Points.DataBindXY(IlXlist, IlYlist)
    10. Dim SeriesIB = New DataVisualization.Charting.Series()
    11. SeriesIB.ChartType = DataVisualization.Charting.SeriesChartType.Point
    12. SeriesIB.Points.DataBindXY(IbXlist, IbYlist)
    13. ' IX
    14. If CheckBox1.Checked Then
    15. Chart1.Series.Add(SeriesIX)
    16. Else
    17. Chart1.Series.Remove(SeriesIX)
    18. End If
    19. 'IY
    20. If CheckBox2.Checked Then
    21. Chart1.Series.Add(SeriesIY)
    22. Else
    23. Chart1.Series.Remove(SeriesIY)
    24. End If
    25. 'IL
    26. If CheckBox3.Checked Then
    27. Chart1.Series.Add(SeriesIL)
    28. Else
    29. Chart1.Series.Remove(SeriesIL)
    30. End If
    31. 'IB
    32. If CheckBox4.Checked Then
    33. Chart1.Series.Add(SeriesIB)
    34. Else
    35. Chart1.Series.Remove(SeriesIB)
    36. End If


    wegkommen. Ich bin mir sicher, dass die Instanzierung der Serien in einer Schleife geschehen kann, was mir fehlt ist der Ansatz, wie dies zu bewerkstelligen ist.

    Über konstruktive Ideen würde ich mich freuen.
    Dateien
    Willkommen im Forum.

    Ja, eine Instanziierung geht über ne Schleife. Du kannst dabei entscheiden, ob Du direkten Zugriff auf die Series behalten willst oder nicht. In diesem Fall wäre es sinnvoll:

    VB.NET-Quellcode

    1. Dim MySeries As New List(Of DataVisualization.Charting.Series)
    2. '…
    3. For i = 1 To 10 'oder ne andere Schleife oder andere Grenzen
    4. Dim NewSeries = New DataVisualization.Charting.Series
    5. NewSeries.ChartType = DataVisualization.Charting.SeriesChartType.Point
    6. MySeries.Add(NewSeries)
    7. Next

    So kannst Du immer über MySeries auf die einzelnen Series zugreifen. Aber! Der Spaß mit den CheckBoxen klappt nicht, weil Du die quasi mitgenerieren müsstest. Das geht, ist aber sicherlich anders besser zu lösen. Brauchst Du überhaupt CheckBoxen oder ist das ein Notbehelf? Das DataBindXY ist natürlich auch tricky. Du gibst hier fixe Punktdaten vor. Da stellt sich die Frage, was Du daran ändern willst.

    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden. Stichwort VB6-Namespace und Option Strict On
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi VaporiZed,

    vielen Dank für die super schnelle Antwort und den Tipp mit der Option. Ich habe gleich die Option "Option Strict On" gesetzt und siehe da: Mein Code musste hier und da modifiziert werden, damit es wieder lief ;)

    Deine Frage:

    ​ Brauchst Du überhaupt CheckBoxen oder ist das ein Notbehelf?


    Kann ich wie folgt beantworten:

    Nein, ich brauche keine Checkbox. Mir ist jede Variante die einfach zum Ziel führt recht. Letztendlich möchte ich, nachdem die Logfile eingelesen wurde, komfortabel die einzelnen Kurven ein- / ausblenden können.

    -> Was würdest Du in meinem Fall vorschlagen?

    Dein Ansatz mit der Liste hatte mir gefehlt, jetzt werden alle Kurven in einer Schleife Instanziiert, was ich schon mal sau geil finde! Ich Danke Dir vielmals schonmal dafür! Mein Code ist jetzt viel kompakter geworden:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Windows.Forms.DataVisualization.Charting
    3. Imports System.IO
    4. Public Class FrmDatalogViewer
    5. Public MetaData As New List(Of String)
    6. Public PDMData As New List(Of String)
    7. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BtLoad.Click
    8. LoadDataFromFile()
    9. DrawChart()
    10. End Sub
    11. Sub LoadDataFromFile()
    12. Try
    13. Dim OFD As New OpenFileDialog()
    14. MetaData.Clear()
    15. PDMData.Clear()
    16. With OFD
    17. .Filter = "CSV-Files (*.csv)|*.csv"
    18. .RestoreDirectory = True
    19. .InitialDirectory = GTG_ODD_DEF_FOCUS_WOBBLE_SAVINGPATH
    20. If .ShowDialog() = Windows.Forms.DialogResult.OK Then
    21. If IO.File.Exists(.FileName) Then
    22. Using reader As StreamReader = New StreamReader(.FileName)
    23. Dim line As String
    24. line = reader.ReadLine ' Read first line.
    25. Dim i As Integer
    26. Do While (Not line Is Nothing) ' Loop over each line in file, While list is Not Nothing.
    27. If i <= 100 Then
    28. MetaData.Add(line) ' Meta
    29. Else
    30. PDMData.Add(line) ' PDM Data
    31. End If
    32. i += 1
    33. line = reader.ReadLine ' Read in the next line.
    34. Loop
    35. End Using
    36. End If
    37. End If
    38. End With
    39. Catch ex As Exception
    40. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    41. End Try
    42. End Sub
    43. Sub DrawChart()
    44. Dim AlleKurven As New List(Of Kurve)
    45. Dim ClsKurve As New Kurve
    46. Dim TmpString As String
    47. Dim StringArr() As String
    48. Dim TimeStamp As String
    49. Dim i As Integer
    50. Dim AnzahlKurven As Integer
    51. Dim MySeries As New List(Of DataVisualization.Charting.Series)
    52. Dim Separator As Char
    53. Char.TryParse(";", Separator)
    54. AnzahlKurven = 20
    55. Try
    56. For i = 1 To AnzahlKurven
    57. AlleKurven.Add(ClsKurve)
    58. Next
    59. i = 0
    60. For Each element In PDMData
    61. TmpString = PDMData(i)
    62. If TmpString <> "" Then
    63. StringArr = TmpString.Split(Separator)
    64. TimeStamp = StringArr(0)
    65. Dim YValue As Single
    66. For k = 1 To StringArr.Length Step 2
    67. Dim idx As Integer
    68. If Integer.TryParse(StringArr(k), idx) Then
    69. If Single.TryParse(StringArr(k + 1), YValue) Then
    70. AlleKurven(idx).ListX.Add(i)
    71. AlleKurven(idx).ListY.Add(YValue)
    72. End If
    73. End If
    74. Next
    75. End If
    76. i += 1
    77. Next
    78. Chart1.Series.Clear()
    79. i = 0
    80. For Each element In AlleKurven
    81. Dim NewSeries = New DataVisualization.Charting.Series
    82. MySeries.Add(NewSeries)
    83. MySeries(i).ChartType = DataVisualization.Charting.SeriesChartType.Point
    84. MySeries(i).Points.DataBindXY(AlleKurven(i).ListX, AlleKurven(i).ListY)
    85. Chart1.Series.Add(MySeries(i))
    86. i += 1
    87. Next
    88. Catch ex As Exception
    89. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    90. End Try
    91. End Sub
    92. Private Class Kurve
    93. Public ListX As New List(Of Long)
    94. Public ListY As New List(Of Single)
    95. Public Visible As Boolean
    96. End Class
    97. Private Sub FrmDatalogger_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    98. End Sub
    99. Private Sub Refresh_Click(sender As Object, e As EventArgs) Handles BtRefresh.Click
    100. DrawChart()
    101. End Sub
    102. End Class


    Ich habe im Moment 20 Kurven drin (nicht 40), damit ich nicht immer so lange warten muss bis ich ein Ergebnis sehe.
    Ich habe mich schon etwas gewundert, warum das erzeugen der 20 Kurven ca. 30 Sekunden dauerte und machte einfach mal einen Versuch mit nur einer Kurve:

    VB.NET-Quellcode

    1. Sub DrawChart()
    2. Dim AlleKurven As New List(Of Kurve)
    3. Dim ClsKurve As New Kurve
    4. Dim TmpString As String
    5. Dim StringArr() As String
    6. Dim TimeStamp As String
    7. Dim i As Integer
    8. Dim AnzahlKurven As Integer
    9. Dim NewSeries = New DataVisualization.Charting.Series
    10. Dim MySeries As New List(Of DataVisualization.Charting.Series)
    11. Dim Separator As Char
    12. Char.TryParse(";", Separator)
    13. AnzahlKurven = 20
    14. Try
    15. For i = 1 To AnzahlKurven
    16. AlleKurven.Add(ClsKurve)
    17. Next
    18. i = 0
    19. For Each element In PDMData
    20. TmpString = PDMData(i)
    21. If TmpString <> "" Then
    22. StringArr = TmpString.Split(Separator)
    23. TimeStamp = StringArr(0)
    24. Dim YValue As Single
    25. For k = 1 To StringArr.Length Step 2
    26. Dim idx As Integer
    27. If Integer.TryParse(StringArr(k), idx) Then
    28. If Single.TryParse(StringArr(k + 1), YValue) Then
    29. AlleKurven(idx).xValue = i
    30. AlleKurven(idx).yValue = YValue
    31. If idx = 0 Then
    32. idx = 0
    33. End If
    34. End If
    35. End If
    36. Next
    37. End If
    38. i += 1
    39. Next
    40. Chart1.Series.Clear()
    41. MySeries.Add(NewSeries)
    42. MySeries(0).ChartType = DataVisualization.Charting.SeriesChartType.Point
    43. MySeries(0).Points.DataBindXY(AlleKurven(0).ListX, AlleKurven(0).ListY)
    44. Chart1.Series.Add(MySeries(0))
    45. 'i = 0
    46. 'For Each element In AlleKurven
    47. ' Dim NewSeries = New DataVisualization.Charting.Series
    48. ' MySeries.Add(NewSeries)
    49. ' MySeries(i).ChartType = DataVisualization.Charting.SeriesChartType.Point
    50. ' MySeries(i).Points.DataBindXY(AlleKurven(i).ListX, AlleKurven(i).ListY)
    51. ' Chart1.Series.Add(MySeries(i))
    52. ' i += 1
    53. 'Next
    54. Catch ex As Exception
    55. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    56. End Try
    57. End Sub


    Es fiel gleich auf, dass ich trotz Darstellung nur einer Kurve, sämtliche Datenpunkte angezeigt wurden was mich etwas stutzig machte.

    Zum Debuggen habe ich die Zeilen

    VB.NET-Quellcode

    1. If idx = 0 Then
    2. idx = 0
    3. End If


    hinzugefügt, und einen Haltepunkt bei

    VB.NET-Quellcode

    1. idx = 0


    gesetzt. Interessanterweise gibt es in der gesamten Logfile keinen einzigen geloggten Wert mit der ID=0, Das heißt im ersten Element der Liste "AlleKurven" sollte eigentlich kein einziger Wert hinzugefügt worden sein. Dennoch werden bei der Verknüpfung der Series(0) mit der Kurve(0) siehe:

    VB.NET-Quellcode

    1. MySeries(0).Points.DataBindXY(AlleKurven(0).ListX, AlleKurven(0).ListY)


    sämtliche Datenpunkte aller ID's, sprich alle Kurven aus dem Log in der Series(0) angezeigt... ?(



    Ich muss hier noch etwas debuggen bevor es weiter geht.
    Naja, der Link ist aber nicht nur Option Strict On betreffend, sondern mehr. Stichworte: MsgBox, vbNewLine

    Auch wenn's gerade nicht das Problem ist, aber kurze Einwürfe kribbeln mir unter den Fußnägeln:
    Das hier

    VB.NET-Quellcode

    1. Dim Separator As Char
    2. Char.TryParse(";", Separator)

    kannst Du durch das hier ersetzen: Dim Separator = ";"c

    Zu Deiner Importprozedur: Probier's mal mit:

    VB.NET-Quellcode

    1. MetaData.Clear()
    2. PDMData.Clear()
    3. '*
    4. If OfdDataFile.ShowDialog() <> Windows.Forms.DialogResult.OK OrElse Not IO.File.Exists(OfdDataFile.FileName) Then Return
    5. Dim DataLines = IO.File.ReadAllLines(OfdDataFile.FileName)
    6. Dim LastMetaDataLineIndex = 101
    7. MetaData.AddRange(DataLines.Take(LastMetaDataLineIndex))
    8. PDMData.AddRange(DataLines.Skip(LastMetaDataLineIndex))

    * in der nächsten Zeile habe ich Deinen lokalen OFD durch einen auf das Form gezogenen ersetzt. Erspart Dir Code in der Prozedur, aber ich tendiere manchmal auch zu einem lokal erstellten …
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Oh ja, ich kann noch viel lernen ;)

    -> Echt hammer geil, wie schnell einem hier im Forum geholfen wird. Top! :thumbsup:

    Ich habe versucht Deinen Code umzusetzen:

    VB.NET-Quellcode

    1. Sub LoadDataFromFile2()
    2. Try
    3. MetaData.Clear()
    4. PDMData.Clear()
    5. Dim OFD As New OpenFileDialog()
    6. With OFD
    7. .Filter = "CSV-Files (*.csv)|*.csv"
    8. .RestoreDirectory = True
    9. .InitialDirectory = GTG_ODD_DEF_FOCUS_WOBBLE_SAVINGPATH
    10. If .ShowDialog() <> Windows.Forms.DialogResult.OK OrElse Not IO.File.Exists(.FileName) Then Return
    11. Dim DataLines = IO.File.ReadAllLines(.FileName)
    12. Dim LastMetaDataLineIndex = 101
    13. MetaData.AddRange(DataLines.Take(LastMetaDataLineIndex))
    14. PDMData.AddRange(DataLines.Skip(LastMetaDataLineIndex))
    15. End With
    16. Catch ex As Exception
    17. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    18. End Try
    19. End Sub


    Allerdings mag VS die Zeile: "DataLines.Take" nicht, mit dem Hinweis: "Take ist kein member von String()".

    Ist im Moment nich sonderlich tragisch. Und ich bin an anderer Stelle etwas weitergekomen. Ich habe zumindest einen BUG gefunden, was die Darstellung der Kurven anbetrifft. Die folgende Zeile führte dazu, dass Werte wie etwa 0.00012346 zu 12346 geparsed wurden:

    VB.NET-Quellcode

    1. If Single.TryParse(StringArr(k + 1), YValue) Then


    Ich habe nun das daraus gemacht:

    VB.NET-Quellcode

    1. If Single.TryParse(StringArr(k + 1), Globalization.NumberStyles.Number, New Globalization.CultureInfo("en-US"), YValue) Then


    Und siehe da! Die Kurve sieht so aus wie sie sein sollte.

    Was mich noch beschäftigt ist, weshalb ich in AlleKurven(0) alle Werte sehe, die ich eigentlich nur in AlleKurven(4) geschrieben habe...

    ist in diesem Code reproduzierbar:

    VB.NET-Quellcode

    1. Sub DrawChart()
    2. Dim AlleKurven As New List(Of Kurve)
    3. Dim ClsKurve As New Kurve
    4. Dim TmpString As String
    5. Dim StringArr() As String
    6. Dim TimeStamp As String
    7. Dim i As Integer
    8. Dim AnzahlKurven As Integer
    9. Dim NewSeries = New DataVisualization.Charting.Series
    10. Dim MySeries As New List(Of DataVisualization.Charting.Series)
    11. Dim Separator = ";"c
    12. AnzahlKurven = 20
    13. Try
    14. For i = 1 To AnzahlKurven
    15. AlleKurven.Add(ClsKurve)
    16. Next
    17. i = 0
    18. For Each element In PDMData
    19. TmpString = PDMData(i)
    20. If TmpString <> "" Then
    21. StringArr = TmpString.Split(Separator)
    22. TimeStamp = StringArr(0)
    23. Dim YValue As Single
    24. For k = 1 To StringArr.Length Step 2
    25. Dim idx As Integer
    26. If Integer.TryParse(StringArr(k), idx) Then
    27. If Single.TryParse(StringArr(k + 1), Globalization.NumberStyles.Number, New Globalization.CultureInfo("en-US"), YValue) Then
    28. If idx = 4 Then
    29. AlleKurven(idx).xValue = i
    30. AlleKurven(idx).yValue = YValue
    31. End If
    32. End If
    33. End If
    34. Next
    35. End If
    36. i += 1
    37. Next
    38. MsgBox(AlleKurven(0).minPos & vbNewLine & AlleKurven(0).minVal)
    39. Chart1.Series.Clear()
    40. MySeries.Add(NewSeries)
    41. MySeries(0).ChartType = DataVisualization.Charting.SeriesChartType.Point
    42. MySeries(0).Points.DataBindXY(AlleKurven(0).ListX, AlleKurven(0).ListY)
    43. Chart1.Series.Add(MySeries(0))
    44. 'i = 0
    45. 'For Each element In AlleKurven
    46. ' Dim NewSeries = New DataVisualization.Charting.Series
    47. ' MySeries.Add(NewSeries)
    48. ' MySeries(i).ChartType = DataVisualization.Charting.SeriesChartType.Point
    49. ' MySeries(i).Points.DataBindXY(AlleKurven(i).ListX, AlleKurven(i).ListY)
    50. ' Chart1.Series.Add(MySeries(i))
    51. ' i += 1
    52. 'Next
    53. Catch ex As Exception
    54. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    55. End Try
    56. End Sub


    Es scheint, als ob das Hinzufügen von weiteren Klassen "ClsKurve" in der Schleife:


    VB.NET-Quellcode

    1. For i = 1 To AnzahlKurven
    2. AlleKurven.Add(ClsKurve)
    3. Next


    keine eigenen Instanzen innerhalb der Liste erzeugt. Ich probiere mal weiter...

    Ok, das war es. So muss es lauten:

    VB.NET-Quellcode

    1. For i = 1 To AnzahlKurven
    2. Dim ClsKurve As New Kurve
    3. AlleKurven.Add(ClsKurve)
    4. Next


    Jetzt funktioniert es schon richtig gut ;) Alle kurven werden geladen und das in unter 2 Sekunden! So macht es spaß. Jetzt fehlt mir nur noch die Möglichkeit die Kurven einzeln abwählen zu können. Gibt es dafür nicht eine Property des Charts? Ich suche mal weiter...

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „HGR“ ()

    Nachdem ich versucht habe, Deine LogFile runterzuladen, war bei mir das Forum nicht mehr erreichbar. Komisch ...
    Take ist kein Member von String()? Ich dachte MetaData ist eine List(Of String), kein String-Array. Komisch ...
    Achso, hast Du in den Projekteigenschaften bei Verweisen unten bei Importierte Namespaces bei System.Linq ein Häkchen? Das wäre notwendig.

    ##########

    Jau, die LogFile zerschießt mir meinen Forenzugang. Und wenn dann doch was runterladbar ist, dann ist das hier das Ergebnis:

    HTML-Quellcode

    1. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    2. <html><head>
    3. <title>500 Internal Server Error</title>
    4. </head><body>
    5. <h1>Internal Server Error</h1>
    6. <p>The server encountered an internal error or
    7. misconfiguration and was unable to complete
    8. your request.</p>
    9. <p>Please contact the server administrator at
    10. [no address given] to inform them of the time this error occurred,
    11. and the actions you performed just before this error.</p>
    12. <p>More information about this error may be available
    13. in the server error log.</p>
    14. <hr>
    15. <address>Apache Server at www.vb-paradise.de Port 443</address>
    16. </body></html>

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()


    Achso, hast Du in den Projekteigenschaften bei Verweisen unten bei Importierte Namespaces bei System.Linq ein Häkchen? Das wäre notwendig.


    Bingo! Das hatte bei mir gefehlt! Dein Code funktioniert wunderbar!

    Jetzt muss ich Deine Frage noch einmal aufgreifen:


    Brauchst Du überhaupt CheckBoxen oder ist das ein Notbehelf?


    und mich an dieser Stelle selbst Zitieren:


    Nein, ich brauche keine Checkbox. Mir ist jede Variante die einfach zum Ziel führt recht. Letztendlich möchte ich, nachdem die Logfile eingelesen wurde, komfortabel die einzelnen Kurven ein- / ausblenden können.-> Was würdest Du in meinem Fall vorschlagen?
    Nun, mir fällt auch Anhieb ne CheckedListBox ein. Ist etwas älter, aber dafür gemacht. Ansonsten könntest Du auch 2 ListBoxen und 2 Buttons nehmen. Eine ListBox zeigt die Namen aller Series an, die 2. die Namen von denen, die angezeigt werden sollen und die Buttons sind dafür da, um eine ausgewählte Series von der einen in die andere ListBox zu schieben bzw. anzuzeigende Series hinzuzufügen bzw. sie zu entfernen.

    Noch einfacher wäre natürlich ne ListBox, bei der du den SelectionMode auf MultiSimple oder MultiExtended schaltest und dann wählt man eben aus, welche Series angezeigt werden sollen.
    Oder Du nimmst n DGV mit 2 Spalten, eine Spalte mit Namen, die 2. mit CheckBoxen. Hach, es gibt so viele Möglichkeiten …
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Jau, die LogFile zerschießt mir meinen Forenzugang. Und wenn dann doch was runterladbar ist, dann ist das hier das Ergebnis:


    Krass... das tut mir leid...

    Die Idee mit dem DGV gefällt mir richtig gut! Ich checke das mal aus! Vielen Dank nochmal für die großartige Unterstützung!
    Hallo Zusammen,

    Ich habe es nun auf die schnelle doch mit der CheckedListBox gelöst. Mit dem DGV muss ich mich noch intensiver beschäftigen, ganz so einfach wie mit der CheckedListBox habe ich es mit der DGV nicht lösen können.

    Insgesamt bin ich mit der aktuellen Lösung sehr zufrieden. Vielen Dank noch einmal speziell an VaporiZed und an das ganze Forum! Viele Lösungen meiner Problemstellungen habe ich in eurem Forum gefunden. Eine super Community!


    Hier mein Code (falls jemand mal eine ähnliche Aufgabe hat):

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Windows.Forms.DataVisualization.Charting
    3. Imports System.IO
    4. Public Class FrmDatalogViewer
    5. Public MetaData As New List(Of String)
    6. Public PDMData As New List(Of String)
    7. Private AlleKurven As New List(Of Kurve)
    8. Private Sub FrmDatalogViewer_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    9. CLB.CheckOnClick = True
    10. End Sub
    11. Sub LoadDataFromFile()
    12. Try
    13. MetaData.Clear()
    14. PDMData.Clear()
    15. Dim OFD As New OpenFileDialog()
    16. With OFD
    17. .Filter = "CSV-Files (*.csv)|*.csv"
    18. .RestoreDirectory = True
    19. .InitialDirectory = GTG_ODD_PDM_SAVINGPATH
    20. If .ShowDialog() <> Windows.Forms.DialogResult.OK OrElse Not IO.File.Exists(.FileName) Then Return
    21. Dim DataLines = IO.File.ReadAllLines(.FileName)
    22. Dim LastMetaDataLineIndex = 101
    23. MetaData.AddRange(DataLines.Take(LastMetaDataLineIndex))
    24. PDMData.AddRange(DataLines.Skip(LastMetaDataLineIndex))
    25. End With
    26. Catch ex As Exception
    27. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    28. End Try
    29. End Sub
    30. Sub GetValues()
    31. Dim TmpString As String
    32. Dim StringArr() As String
    33. Dim TimeStamp As String
    34. Dim i, k As Integer
    35. Dim AnzahlKurven As Integer
    36. Dim Separator = ";"c
    37. AnzahlKurven = 40
    38. CLB.Items.Clear()
    39. Try
    40. For i = 1 To AnzahlKurven
    41. Dim ClsKurve As New Kurve
    42. AlleKurven.Add(ClsKurve)
    43. If i < 5 Then
    44. CLB.Items.Add("Series " & i, True)
    45. Else
    46. CLB.Items.Add("Series " & i, False)
    47. End If
    48. Next
    49. i = 0
    50. For Each element In PDMData
    51. TmpString = PDMData(i)
    52. If TmpString <> "" Then
    53. StringArr = TmpString.Split(Separator)
    54. TimeStamp = StringArr(0)
    55. Dim YValue As Single
    56. For k = 1 To StringArr.Length Step 2
    57. Dim idx As Integer
    58. If Integer.TryParse(StringArr(k), idx) Then
    59. If Single.TryParse(StringArr(k + 1), Globalization.NumberStyles.Number, New Globalization.CultureInfo("en-US"), YValue) Then
    60. AlleKurven(idx).xValue = i
    61. AlleKurven(idx).yValue = YValue
    62. AlleKurven(idx).DataExist = True
    63. End If
    64. End If
    65. Next
    66. End If
    67. i += 1
    68. Next
    69. Catch ex As Exception
    70. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    71. End Try
    72. End Sub
    73. Sub DrawChart()
    74. Try
    75. Dim MySeries As New List(Of DataVisualization.Charting.Series)
    76. Dim i, k As Integer
    77. Chart1.Series.Clear()
    78. i = 0
    79. k = 0
    80. For Each element In AlleKurven
    81. If CLB.CheckedItems.Count > 0 Then
    82. If CLB.GetItemCheckState(i) = CheckState.Checked Then
    83. Dim NewSeries = New DataVisualization.Charting.Series
    84. NewSeries.Name = CLB.GetItemText(CLB.Items(i))
    85. MySeries.Add(NewSeries)
    86. MySeries(k).ChartType = DataVisualization.Charting.SeriesChartType.Line
    87. MySeries(k).Points.DataBindXY(AlleKurven(i).ListX, AlleKurven(i).ListY)
    88. Chart1.Series.Add(MySeries(k))
    89. k += 1
    90. Application.DoEvents()
    91. End If
    92. End If
    93. i += 1
    94. Next
    95. Catch ex As Exception
    96. MsgBox(ex.Message & vbNewLine & ex.StackTrace)
    97. End Try
    98. End Sub
    99. Private Class Kurve
    100. Public ListX As New List(Of Long)
    101. Public ListY As New List(Of Single)
    102. Public Visible As Boolean
    103. Public DataExist As Boolean
    104. Dim i As Integer
    105. Dim _minVal As Single
    106. Dim _maxVal As Single
    107. Dim _minPos As Integer
    108. Dim _maxPos As Integer
    109. Dim _sum As Single
    110. Dim _avg As Single
    111. Dim _xValue As Long
    112. Dim _yValue As Single
    113. Public ReadOnly Property minVal As Single
    114. Get
    115. Return _minVal
    116. End Get
    117. End Property
    118. Public ReadOnly Property maxVal As Single
    119. Get
    120. Return _maxVal
    121. End Get
    122. End Property
    123. Public ReadOnly Property minPos As Integer
    124. Get
    125. Return _minPos
    126. End Get
    127. End Property
    128. Public ReadOnly Property maxPos As Integer
    129. Get
    130. Return _maxPos
    131. End Get
    132. End Property
    133. Public Property xValue As Long
    134. Get
    135. Return _xValue
    136. End Get
    137. Set(value As Long)
    138. _xValue = value
    139. ListX.Add(_xValue)
    140. End Set
    141. End Property
    142. Public Property yValue As Single
    143. Get
    144. Return _yValue
    145. End Get
    146. Set(value As Single)
    147. _yValue = value
    148. If _yValue < _minVal Then
    149. _minVal = _yValue
    150. _minPos = i
    151. End If
    152. If _yValue > _maxVal Then
    153. _minVal = _yValue
    154. _maxPos = i
    155. End If
    156. _sum += _yValue
    157. ListY.Add(_yValue)
    158. i += 1
    159. End Set
    160. End Property
    161. Public Property avg As Single
    162. Get
    163. Return _avg
    164. End Get
    165. Set(value As Single)
    166. _avg = value
    167. _avg = _sum / ListY.Count
    168. End Set
    169. End Property
    170. End Class
    171. Private Sub Refresh_Click(sender As Object, e As EventArgs)
    172. DrawChart()
    173. End Sub
    174. Private Sub OpenFileToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenFileToolStripMenuItem.Click
    175. LoadDataFromFile()
    176. GetValues()
    177. DrawChart()
    178. End Sub
    179. Private Sub CLB_SelectedValueChanged(sender As Object, e As EventArgs) Handles CLB.SelectedValueChanged
    180. DrawChart()
    181. End Sub
    182. End Class