Arbeiten mit Charts

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von Linkai.

    Arbeiten mit Charts

    Liebe Communty,
    ich habe derzeit in meiner Firma eine neue Aufgabe bekommen: Eine visuelle Ausgabe von rund 5 mio Datensätzen.
    Es handelt sich dabei um Strommessungen von Produktionsmaschinen, welche über 3 Phasen verfügen. Die Messsoftware ist bereits von einem Kollegen fertig gestellt, sodass die Ergebnisse in einer Datenbank (MySQL) gespeichert sind.
    Nun möchte der Kunde das ganze in Form eines Liniendiagrams ausgegeben bekommen.
    Die X-Achse des Diagrams soll das Datum / Die Zeit anzeigen, von wann das Ergebnis (in kW auf der Y-Achse) ist.
    Nun habe ich noch nie mit dem Chart gearbeitet und habe keinerlei Anhaltspunkte, wie ich einem Punkt, den ich nun hinzufügen möchte, sage dass der X wert z.B ein Datum ist.

    Ich füge dem Chart zurzeit einen Punkt mit folgender Zeile hinzu:

    VB.NET-Quellcode

    1. Chart1.Series(0).Points.Add(1,1)


    Hat einer von euch eine Idee?
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    Dort ist es schon umgestellt, doch wie erzeuge ich damit einen neuen Punkt? ich muss mit meiner Methode zur Punkterzeugung werte vom Typ Double angeben.
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    danke @ErfinderDesRades,
    ich werde mich da mal durchlesen. Ich habe bislang noch nicht wirklich mit Databindings gearbeitet. Wird wohl mal Zeit für mich :D
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    So, ich habe nun folgendes Szenario:
    Ich habe eine 2. Form mit einem
    DGV erstellt. Mit folgendem Code, befülle ich es mit einer bestimmten
    Anzahl an Datensätzen. Klappt auch alles wunderbar.

    VB.NET-Quellcode

    1. Sub fetchingData()
    2. Dim config As New Dictionary(Of String, String)
    3. config = Mainform.core.config
    4. Dim constring As String = "server=" & config("mysql_host") & ";user=" & config("mysql_user") & ";database=" & config("mysql_db") & ";port=" & config("mysql_port") & ";password=" & config("mysql_password") & ";"
    5. Dim db_con As New MySqlClient.MySqlConnection(constring)
    6. Dim cmd As New MySqlCommand("SELECT * FROM messung Limit " & config("InitialRowCount"), db_con)
    7. Dim da = New MySqlDataAdapter(cmd)
    8. Dim dt = New DataTable()
    9. da.Fill(dt)
    10. Me.Invoke(Sub() BindingSource1.DataSource = dt) ' here assign the DataTable'
    11. With Me.DataGridView1
    12. .AutoGenerateColumns = True
    13. Me.Invoke(Sub() .DataSource = BindingSource1)
    14. End With


    Auf meiner 1. Form habe ich nun mein Chart. Ich bekomme es aber nicht auf die Kette jetzt beides miteinander zu Verbinden-.-...
    Mein versuch war der dem Chart die selbe Datenquelle zu geben wie dem DGV.

    VB.NET-Quellcode

    1. Public Sub setDS()
    2. With Me.Chart1
    3. .DataSource = hiddenDGV.BindingSource1
    4. End With
    5. MsgBox("done")
    6. End Sub

    Die MessageBox wird auch angezeigt (msgbox ist out i know- ging schneller zum Debuggen).
    Es passiert aber sonst nichts weiter. Jemand ne Idee?
    Ich habe im Chart alles so eingestellt wie hier von EDR erklärt: Chart - Sample


    EDIT: Okay, gelöst.

    VB.NET-Quellcode

    1. .DataBind()

    Fehlte

    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Linkai“ ()

    zunächstmal arbeite ich natürlich mit typisiertem Dataset. Dabei kann man die ValueMember auswählen, denn dann ist dem Chart der Datentyp bekannt, an den es gebunden wird.

    Dann ists natürlich immer schwierig, mit Daten in mehreren Forms zu hantieren.

    Weiters ist für's Chart dein DGV vollkommen irrelevant und unnötig. Das Chart zeigt nicht ein DGV an, sondern es zeigt eine DataTable an.

    Und natürlich gibt es keine DatagridView.BindingSource1 - Property.

    also wenn man mit typisierten Datasets arbeitet ists vergleichsweise einfach, aber das geht eben sehr anders, als was du da versuchst.
    Du müsstest es also erstmal hinkriegen, ein typDataset zu erstellen, und dann, es richtig zu befüllen.

    Dann kannste auch ein Chart an eine der typisierten DataTables des typDatasets binden.


    Ist halt immer lausig, wenn man gleich mit der DB anfängt, da muss man auf Anhieb sehr viel richtig machen, und es ist eiglich ausgeschlossen, dass man nicht auf einen Holzweg gerät. Du etwa betrittst ihn mit

    VB.NET-Quellcode

    1. Dim dt = New DataTable()
    , weil das ist keine typisierte DataTable.
    Ein typDataset tut man befüllen, aber man erstellt keine neuen DataTables, sondern man muss die (typisierten) Tabellen befüllen, die bereits da sind.

    Und wie gesagt: mit mehreren Forms zu arbeiten ist nochmal problematisch - das am besten erstmal unterlassen.



    Also nochmal, und beachte auch die Reihenfolge:
    1. Du brauchst ein typDataset, und darin muss eine typDataTable angelegt sein , im Dataset-Designer
    2. Daran kannst du das Chart binden, im Form-Designer, und das Property-Fenster der Series bietet dir dann auch die Properties an, an die XValues/YValues gebunden werden kann.
    3. Dann musst du diese typisierte DataTable befüllen. Diese! Keine neue erstellen, sondern die befüllen, die da ist, die der Designer aufs Form gemacht hat.
    4. Ein ebenfalls an dieselbe Tabelle gebundenes DGV ist sehr praktisch für die Entwicklung - zB zur Daten-Kontrolle - hat aber mit dem Charting absolut nix zu tun, und kann anschließend wieder weg.
    Das Befüllen wird übrigens einiges an Aus-Siebe-Logik erfordern, denn Millionen Datenpunkte gehen nicht gut auf ein Chart.

    Also vlt. erstmal ohne Chart entwickeln, nur das DGV - bis das mit dem Daten-holen richtig klappt.
    Und danach erst das Chart daneben-stellen (so wie im Tut)
    Und evtl. dann das DGV auch wieder runterschmeissen.
    danke @ErfinderDesRades,
    ich bin wohl im Eifer des Gefechts etwas durcheinander geraten. Das DGV war erstmal zum üben.
    Dass ich die Daten nicht aus dem DGV lese ist mir bereits bewusst, ist wohl irgendwie durcheinander geraten. Nun denn:
    Meine Methode funktioniert nun mit folgendem Code ohne Probleme:

    Nachdem die Daten geladen wurden, wird die BindingSource als Parameter mitgegeben. Warum bei mir nichts angezeigt wurde: .DataBind() fehlte ;)

    VB.NET-Quellcode

    1. Public Sub setBS(ByVal db As BindingSource)
    2. With Me.Chart1
    3. .DataSource = db
    4. .DataBind()
    5. End With
    6. MsgBox("done")
    7. End Sub
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    cool!

    ich eier ja immer auf Typisierung rum, daher Frage: Funzt das jetzt bei dir auch ohne?

    Weil sollte theoret. auch möglich sein, halt nur mit dem Nachteil, dass man beim Chart-Konfigurieren keine Designer-Auswahlen angeboten bekommt.

    Und kannst du das Chart dann nicht auch direkt an die DataTable binden, und die BindingSource sogar weglassen?

    Ich bin mit dem Charting nämlich nicht so ganz fröhlich - mir widerstrebt etwas, typisierte DataTables anzulegen - nur damit ein Chart die anzeigen kann - deren Daten ansonsten aber nicht verarbeitet werden, und auch nicht abzuspeichern sind.
    Ist ähnlich unschön wie mit den ReportViewern - da muss man auch besondere typisierte DataTables erzeugen, welche eigentlich in einem Datenmodell nix verloren hätten (denn sie modellieren keine Realität, sondern enthalten ausschließlich generierte Daten, zum füttern eines Controls).

    Als nächstes dann würde ich für Threading den Async-Pattern empfehlen - ist einfacher als Invoking, hat eine geringere Code-Komplexität, und ist stärker erweiterungsfähig - man sollte es einfach einüben.



    Naja - grad sehe ich das hier:

    VB.NET-Quellcode

    1. Dim config As New Dictionary(Of String, String)
    2. config = Mainform.core.config
    Also das ist in vielfacher Hinsicht sehr problematisch.

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

    ErfinderDesRades schrieb:

    Naja - grad sehe ich das hier:
    VB.NET-Quellcode

    Dim config As New Dictionary(Of String, String)
    config = Mainform.core.config

    Also du hast noch grundlegendere Probleme, denkich.


    Das ist derzeit alles nur zum Debuggen und Testen. Das ganze wird später mit XML laufen.

    ErfinderDesRades schrieb:

    Und kannst du das Chart dann nicht auch direkt an die DataTable binden, und die BindingSource sogar weglassen?

    Das habe ich grade getestet, weil das eine relativ interessante Idee ist: JA es geht :)
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    So, ich muss mich hier nochmal zu Wort melden.

    Ich habe ein Chart nun an eine DataTable gebunden.
    Alles klappt mit ausnahme der Y Achse.
    Der Wert, welcher auf der Y-Achse ausgegeben werden soll ist eine Kommazahl: 323,2 zB
    diese wird auf der Y - Achse aber als 3232 angezeit...

    Hab leider keine Idee wie ich das lösen kann..
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    Das ist mir grad auch aufgefallen, wie kann ich das nun am elegantesten lösen?

    EDIT##

    VB.NET-Quellcode

    1. Dim dt2 As New DataTable
    2. dt2.Columns.Add("stromwandler_ID")
    3. dt2.Columns.Add("phase1")
    4. dt2.Columns.Add("time")
    5. For Each row As DataRow In dt.Rows
    6. Dim completeCalc As Double = row.Item("phase1") + row.Item("phase2") + row.Item("phase3")
    7. ' MsgBox(completeCalc.ToString)
    8. Dim dr1 As DataRow
    9. dr1 = dt2.NewRow
    10. dr1.Item(0) = row.Item(0)
    11. dr1.Item(1) = completeCalc.toString.replace(".",",") 'Damit hab ichs auch schon versucht aber ohne auswirkung. Wenn ich die Phasen einzelnd ausgebe wird auch richtig angezeigt nur wenn ich alle zusammen Addiere gehts nicht ..
    12. dr1.Item(2) = row.Item("time")
    13. dt2.Rows.Add(dr1)
    14. Next

    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:

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

    Ich hab noch immer folgendes Problem:

    Linkai schrieb:

    Der Wert, welcher auf der Y-Achse ausgegeben werden soll ist eine Kommazahl: 323,2 zB
    diese wird auf der Y - Achse aber als 3232 angezeit...



    Linkai schrieb:

    EDIT##
    VB.NET-Quellcode

    VB.NET-Quellcode

    1. Dim dt2 As New DataTable
    2. dt2.Columns.Add("stromwandler_ID")
    3. dt2.Columns.Add("phase1")
    4. dt2.Columns.Add("time")
    5. For Each row As DataRow In dt.Rows
    6. Dim completeCalc As Double = row.Item("phase1") + row.Item("phase2") + row.Item("phase3")
    7. ' MsgBox(completeCalc.ToString)
    8. Dim dr1 As DataRow
    9. dr1 = dt2.NewRow
    10. dr1.Item(0) = row.Item(0)
    11. dr1.Item(1) = completeCalc.toString.replace(".",",") 'Damit hab ichs auch schon versucht aber ohne auswirkung. Wenn ich die Phasen einzelnd ausgebe wird auch richtig angezeigt nur wenn ich alle zusammen Addiere gehts nicht ..
    12. dr1.Item(2) = row.Item("time")
    13. dt2.Rows.Add(dr1)
    14. Next


    und das hab ich versucht und es klappt nicht -.-...
    ich habe auch bereits folgende Dinge versucht.
    msdn.microsoft.com/de-de/library/s2dy91zy.aspx
    mycsharp.de/wbb2/thread.php?threadid=2036
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    Ich hab mal das Problem als Screenshot in den Anhang gepackt.
    Zu sehen ist im Hintergrund das Chart und im Vordergrund ein DataGridview mit der gleichen DataSource.
    Ich hoffe dies ist verständlicher als das geschriebene..
    Bilder
    • Das Problem.png

      19,35 kB, 723×499, 271 mal angesehen
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    ich glaub, letztendlich ein Option Strict Off - Problem.
    Scheints werden Strings geparst, und dabei der Dezimal-Trenner übersehen - warum genau weiß ich auch nicht.
    Wo da der Datentyp String ins Spiel kommt - obwohls doch eiglic um Doubles gehen sollte - bleibt erstmal unklar, denn bei Strict Off weiß man ja garnet, was wo in was umgewandelt wird.

    Grundsätzliche Empfehlung: Visual Studio - Empfohlene Einstellungen
    Vll solltest den Datacolumns die richtigen Typen mitgeben und nicht String ?

    row.Item("phase1") + row.Item("phase2") + row.Item("phase3")

    Was ist das row.Item("phase1") für ein Datentyp?

    Verwendest du Option Strict On?
    Das ist meine Signatur und sie wird wunderbar sein!
    Option Strict: ON ist bereits an.
    (nachdem es so nicht geklappt hat hab ich das bereits getestet und die Datentypen Explizit angegeben)
    Die werde sind Cdbl()
    In der DataTable sind die Werde alle Korrekt errechnet. Nur werden Sie falsch ausgegeben.


    Dem Chart ist auch mitgeteilt, dass es sich bei den Werten der Y Achse um den Typ Double handelt.
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    Cdbl ist kein Datentyp sondern eine VB6 Konvertierungsfunktion.


    VB.NET-Quellcode

    1. dt2.Columns.Add("phase1")
    2. dr1 = dt2.NewRow
    3. dr1.Item(0) = row.Item(0)
    4. dr1.Item(1) = completeCalc.toString.replace(".",",") 'Damit hab ichs


    dr1.Item(1) ist definitiv String.
    Das ist meine Signatur und sie wird wunderbar sein!

    Mono schrieb:

    dr1.Item(1) ist definitiv String.


    Wurde bereits ersetzt. Aktueller Code:

    VB.NET-Quellcode

    1. Dim dt2 As New DataTable
    2. dt2.Columns.Add("stromwandler_ID")
    3. dt2.Columns.Add("phase1")
    4. dt2.Columns.Add("time")
    5. For Each row As DataRow In dt.Rows
    6. Dim completeCalc As Double = CDbl(row.Item("phase1")) + CDbl(row.Item("phase2")) + CDbl(row.Item("phase3"))
    7. ' MsgBox(completeCalc.ToString)
    8. Dim dr1 As DataRow
    9. dr1 = dt2.NewRow
    10. dr1.Item(0) = row.Item(0)
    11. dr1.Item(1) = completeCalc
    12. dr1.Item(2) = row.Item("time")
    13. dt2.Rows.Add(dr1)
    14. Next


    Die Werte werden alle korrekt berechnet wie bereits erwähnt. Im DGV ist die selbe DataTable als Source wie bei dem Char. (Sie werden nach dieser Verarbeitung hinterinander Gebinded)

    VB.NET-Quellcode

    1. 'Bezeichnungen der Controls werden noch angepasst ;)
    2. dtForm.DataGridView1.DataSource = dt2
    3. Chart1.DataSource = dt2
    4. Chart1.DataBind()

    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love: