typisiertes Dataset an Chart anbinden - mehrere Kurven anzeigen lassen

  • VB.NET

Es gibt 44 Antworten in diesem Thema. Der letzte Beitrag () ist von egon.

    Uff. Sehe ich es richtig, dass es keinen relativ einfachen Weg gibt um systemweit auf Daten zugreifen zu können. Dann war ja mein alter Code mir Arrays und einer kleinen Klasse "CurveData" für die Daten ja richtig übersichtlich und einfach zu überblicken.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class CurveData
    2. Public XValues() As Double
    3. Public XValues_Anzeige() As Double
    4. Public YValues() As Double
    5. Public YValues_Anzeige() As Double
    6. End Class

    Wie lösen andere ein solches Problem? Welchen Weg könnt ihr mir empfehlen?
    Der angedeute Superspezialweg von EdR kann für mich nicht richtig sein, da ich viel zu wenig von der Materie verstehe und kein Informatiker bin.

    Ist das

    VB.NET-Quellcode

    1. Friend WithEvents DataSet1 As DataSet1
    die Lösung? Hier bitte ich um weitere Erklärungen - auch wegen der Events. Ich kann leider damit keinen lauffähigen Code erzeugen. Leider habt ihr mich jetzt völlig verwirrt.
    Wenn Du Dich nicht in die EdR-Materie einarbeiten willst: Hier zwei Wege meinerseits, die ich bisher als ausreichend angesehen habe. Früher oder später tauchen bestimmt die Unzulänglichkeiten der beiden Methoden auf, aber dann bist Du schon ein Stück weit erfahrener und kannst wohl auch selber eine Lösung finden:
    1. Mein erster Schritt war ein "TdsManager": Du schreibst eine simple Shared Class (über das Thema "richtiges implementieren eines Singleton" ließe sich zu einem späteren Zeitpunkt reden; ich will's ja für den Anfang so leicht verständlich wie möglich machen):

    VB.NET-Quellcode

    1. Friend Shared Class TdsManager
    2. Private _Tds As DeinTdsKlassenName = Nothing
    3. Friend Property Tds As DeinTdsKlassenName
    4. Get
    5. Return _Tds
    6. End Get
    7. Set(NewTds As DeinTdsKlassenName)
    8. If _Tds Is Nothing Then _Tds = NewTds
    9. End Set
    10. End Property
    11. End Class

    (aus dem Kopf heraus, da für mich nicht mehr aktuell)
    Du programmierst Dein ganzes Programm so, dass Du nicht auf DataSet1 verweist, sondern immer stattdessen TdsManager.Tds schreibst:
    TdsManager.Tds.Messreihe(0).GettMesswertRows. Dazu müssen aber 2 Sachen beachtet werden: Jede BindingSource, die auf DataSet1 bisher verwies, muss auf TdsManager.Tds umgestöpselt werden: BsMessreihe.DataSource = TdsManager.Tds. Und recht früh zu Programmbeginn muss gesagt werden: TdsManager.Tds = DataSet1, also die Erstzuweisung, damit ein "Referenz-Tds" zugewiesen wird.

    2. Variante (verwende ich derzeit, bis ich auf unüberbrückbare Probleme stoße - bisher geht's): Belass alles bei den Form-eigenen tDS. Jedes Form hat seine eigene tDS-Instanz. Woher kommen jetzt die Daten, wenn ich ein neues Formular aufrufe? Ich gehe davon aus, dass ich ein Hauptformular habe, welches die anderen Forms aufruft. Dann schreib ich einfach an passender Stelle in Form1:

    VB.NET-Quellcode

    1. Using DlgMessreiheProperties As New FrmMessreiheProperties
    2. DlgMessreiheProperties.DataSet1 = DataSet1
    3. DlgMessreiheProperties.ShowDialog(Me)
    4. End Using

    Ich erzeuge und zeige also ein anderes Formular, ersetze aber einfach dessen tDS durch mein eigentliches, mit Daten befülltes tDS. Dadurch muss ich bis auf weiteres keine BindingSource-Datenquellen ändern, da plötzlich im 2. Formular dieselben (nicht die gleichen) Daten vorhanden sind, wie im Hauptformular.
    So, jetzt wird's Zeit für mich. Die tDS-Experten wie @VB1963 und @ErfinderDesRades dürfen gerne meine Vorschläge auseinanderfetzen.
    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.
    Gestern wurde ich von euren Beiträgen richtig erschlagen. Auch wenn ich die Variante von EdR noch nicht verstehe, möchte ich sie nicht so gleich verwerfen. Den Link von EdR werde ich mir nochmals vornehmen. Vielleicht klappt es heute besser.
    Ich bin gespannt welchen der drei Wege ihr mir letztlich empfehlen könnt (1. EdR; 2.VaporiZed: TdsManager; 3. VaporiZed: eigene tDS-Instanzen). Die Vor- und Nachteile kann ich nocht nicht überblicken. Folgeprobleme kann ich sowieso nicht überblicken. Daher bin ich auf euren Rat angewiesen.

    VaporiZed schrieb:

    dürfen gerne meine Vorschläge auseinanderfetzen.


    VaporiZed schrieb:

    VB.NET-Quellcode

    1. Friend Shared Class TdsManager
    Ist das ein neues vb.net - Sprachkonstrukt?
    Meines Wissens geht das nicht.

    Das hier kann eiglich auch nicht funzen, denk ich:

    VB.NET-Quellcode

    1. Using DlgMessreiheProperties As New FrmMessreiheProperties
    2. DlgMessreiheProperties.DataSet1 = DataSet1
    3. DlgMessreiheProperties.ShowDialog(Me)
    4. End Using
    Wenn FrmMessreiheProperties erstellt ist, und hat sein DataBinding im Designer eingerichtet, dann ist dort an dessen eigenes Dataset1 gebunden.
    Wenn du das Dataset1 nun ersetzst, interessiert das die Bindings nicht: Die sind nachwievor auf das vorherige Dataset1 gebunden - also nach meim Verständnis kann FrmMessreiheProperties auf diese Weise keine Daten anzeigen.
    Ich würde mit einer ListOf(ListOf Datapoint) arbeiten. Eine Funktion geht dabei mit entsprechenden Bedingungen die DataTable durch und erstellt Datenpunkte, die den einzelnen Listen zugeordnet werden.

    Im Anschluss wird mit jeder Subliste eine Serie im Chart erstellt.

    Aber ganz abgesehen davon würde ich es in Frage stellen, ob 20 Linien in einem Chart überhaupt Sinn machen. Je nachdem, wie volatil die Kurven sind, kann die Lesbarkeit schon jenseits der 3 Kurven massiv nachlassen.

    Im angehängten Beispiel sind ca. 10 Datenreihen enthalten, die die tagesbezogenen Fehlerzahlen in einem Produktionsbereich darstellen. Und wie man sieht, ist es ziemlich schwierig überhaupt etwas zu erkennen.

    Option strict = on

    If it's stupid and it works it ain't stupid.

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

    Nur kurz zu der Anzahl der Kurven. Natürlich macht es keinen Sinn, wenn man sich alle Kurven anzeigen lässt. Es besteht aber die Möglichkeit, dass man verschiedene Kurven einblenden kann. Je nach Anwendungsfall macht es aber auch Sinn sich mehr Kurven anzeigen zu lassen. Bei ähnlichen Kurven lassen sich so die Abweichungen deutlich anzeigen. Das wird dann aber sehr viel übersichtlicher aussehen als bei Nils_Kr. ;)

    Sonst arbeite ich mich in den Link aus der Post #19 von EdR weiter ein. Das geht aber sehr langsam. Ich habe es noch nicht hinbekommen die Erklärungen (Post#19) so umzusetzen , dass ich aus einer Klasse auf die Daten zugreifen kann.
    Wenn ich Edr und VaporiZed richtig verstehen, funktionieren ihre Vorschläge bei unterschiedllichen Forms. Wie ist das dann aber bei unterschiedlichen Klassen?

    In der Zwischenzeit bin ich gespannt, in welche Richtung sich eure Vorschläge entwickeln.

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

    Da es nach dem Kommentar von @ErfinderDesRades unsinnig wäre, den Post zu editieren, hier das nicht-aus-dem-Kopf-sondern-aus-einem-alten-Projekt-heraus:

    VB.NET-Quellcode

    1. Friend Module TdsHolder
    2. Private _TdsTest As TdsTest = Nothing
    3. Friend Property TdsTest As TdsTest
    4. Get
    5. Return _TdsTest
    6. End Get
    7. Set(NewTds As TdsTest)
    8. If _TdsTest Is Nothing Then _TdsTest = NewTds
    9. End Set
    10. End Property
    11. End Module


    Das mit dem 2. Vorschlag: Wo war ich da mit meinen Gedanken? Wohl noch im Schlaf. Vollkommen richtig. Das funktioniert nicht. Ich hatte es im Hinterkopf als "zu testen" abgespeichert, bin aber nicht dazu gekommen, es bei meinen Projekten zu probieren und das hat sich sinnfreierweise als Vorschlag manifestiert. Schande über mich.
    Klar müssen die Datenquellen der BindingSources direkt geändert werden. X/
    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“ ()

    VaporiZed: Könnte ich dich bitten deinen Vorschlag mal lauffähig in meinem Testprojekt umzusetzen? Ich habe es angehängt.
    Die Klasse "Testclass" soll mit der Sub test() einfach einen oder mehrere Werte hinzufügen (oder etwas anders machen).
    Dateien
    • Databinding.zip

      (312,26 kB, 76 mal heruntergeladen, zuletzt: )
    Klar, kein Ding. Ist ja einfach nur eine Parameterübergabe. Wichtig ist nur, dass Du die Testclass nicht zu früh erstellst. Das habe ich in die Form1_Shown-EventHandler-Sub verfrachtet, da vorher DataSet1 = Nothing ist, weil es eben noch nicht erstellt wurde.
    Dateien
    • DatabindingEx.zip

      (233,59 kB, 76 mal heruntergeladen, zuletzt: )
    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.
    Iiiih - der hat ja Strict Off!!

    Und den Deppen-Namespace auch.

    @egon: Ich hätte eiglich gedacht, darüber seist du inzwischen hinaus, und tätest die Visual Studio - Empfohlene Einstellungen geniessen.

    Also in diesem Zustand brauchst du dir eiglich über Zugriff aus Klasse und sowas keine Gedanken machen - erstmal ist obiges zu erledigen.
    Aber trotzdem ist der Code bisher sauber. Sogar keine VB-Namespace-Codes drin. =O
    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.
    Glücksache.
    Und ist ja wirklich Glück, weil umso einfacher kanner die Schlamperei in Ordnung bringen.

    Aber ich bin auch irritiert - ob wir es etwa versäumt haben, ihm die empfohlenen Einstellungen ans Herz zu legen?
    Oder ist das ein Fall von Beratungs-Resistenz?

    Und bei
    Schlamperei in Ordnung bringen
    befürchte ich jetzt, dassers eben schnell auf Projekt-Ebene macht, statt wie im Link empfohlen, das ein für allemal als VisualStudio-Einstellung zu korrigieren.
    Und dann geht der Sch... beim nächsten Projekt von vorne los.

    Ich empfehle übrigens, noch weitere General-Importe rauszuwerfen:
    • System.Collections - untypisierte Auflistungen
    • System.Data - untypisierte Data-Objekte
    • System.Xml.Linq - kaum einer weiss, was das ist, und noch weniger verwendens auch - was hat das inne General-Importe verloren?
    • System.Threading.Tasks - Nebenläufigkeit einzusetzen sollte man sich immer mindestens 2 mal überlegen - auch keinesfalls etwas für einen GeneralImport
    Aufgeräumte GeneralImporte sähen also so aus (meine Empfehlung)

    Und auch System.Diagnostics fliegt bei mir raus, weil häufig brauchen tut man davon nur den Debug.Print - Befehl.
    Und der ist bei mir ersetzt durch etwas praktischeres.

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

    VaporiZed schrieb:

    Aber trotzdem ist der Code bisher sauber.


    Also bei mir kompiliert die Mappe nicht ohne Korrektur. Dim FinalText As New Text.StringBuilder Text ist nicht eindeutig, könnte ja System.Text oder auch System.Drawing.Text sein. Also Zed, nicht CleanCode-Konform.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

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

    @NoIde: Kann ich jetzt nicht nachvollziehen. Bei mir interpretiert er das sauber als System.Text. Einstellungssache? VS-Unterschied (bei mir VS 2017 CE)? Aber wie auch immer: Die Zeile ist auf meinem Mist gewachsen.
    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.
    Also ich nutze VS 2010 und 2013 jeweils die Express-Editionen. Aber irgendwie Schade das MS den Kompiler in den neueren IDE's scheinbar einfach so machen lässt(auch wenns ersichtlich ist(StringBuilder)), gerade bei der Einsteigersprache schlechthin sollte auf korrektheit mehr Wert gelegt werden.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin
    Oder ist das ein Fall von Beratungs-Resistenz?

    Nein, das ist es nicht. Ich muss Asche auf mein Haupt streuen und mich verschämt in die Ecke stellen...
    Frag mich bitte nicht wie das passieren konnte. Meine anderen kleinen Testprojekte sind alle sauber. Bin gerade dabei mir eine aktualisierte und richtige Vorlage zu erstellen.

    @ 'ErfinderDesRades Was hältst du von dem Vorschlag von VaporiZed?

    Dann hätte ich noch ein Frage zu BindingSources. Ist das richtig, dass ich sie nur brauche, wenn ich mit DataGridView & Co arbeite und dass ich sie nicht braue, wenn ich alle Zugriffe auf die Daten auf Code-Ebene durchführe?


    Mich würde auch interessieren, ob mir die wichtigsten Zugriffsmöglichkeiten auf die Daten im typ. Dataset nun bekannt sind. (Im Fall Verwaltung von Messdaten)
    Hier mal eine Liste der mir bekannt Zugriffsmöglichkeiten:
    (1) Messreihe hinzufügen: DataSet1.Messreihe.AddMessreiheRow("Datensatz1")
    (2) Messwert hinzufügen: DataSet1.Messwert.AddMesswertRow(2, 3, 5, DataSet1.Messreihe(0))
    (3) Die X-Werte einer Messreihe in eine Liste oder in ein Array kopieren: test3 = _DataSetToUse.Messreihe(0).GetMesswertRows.Select(Function(x) x.X_Wert).ToList oder Test2 = _DataSetToUse.Messreihe(0).GetMesswertRows.Select(Function(x)x.X_Wert).ToArray
    Sonst muss ich das mit For Next oder mit For Each Next erledigen.
    (4) Bevor eine Messreihe mit neuen Werte belegt wird, muss sie gelöscht werden:

    VB.NET-Quellcode

    1. For Each Row In DataSet1.Messreihe(0).GetMesswertRows
    2. Row.Delete()
    3. Next

    (5) Daten von der Messreihe 0 nach Messreihe 2 kopieren:

    VB.NET-Quellcode

    1. For Each Row In DataSet1.Messreihe(0).GetMesswertRows ''Warum muss alles per Hand kopiert werden?
    2. DataSet1.Messwert.AddMesswertRow(Row.X_Wert, Row.Y1_Wert, Row.Y2_Wert, DataSet1.Messreihe(2))
    3. Next

    (6) Auf einen bestimmten X-Wert soll zugegriffen werden: DataSet1.Messreihe(0).GetMesswertRows(i).X_Wert

    Fehlt etwas Wichtiges?

    a) Wie kann man sich eigentlich alles X-Werte und Y-Wert für 3 < x < 7 anzeigen lassen?
    b) Wie kann man sich die Werte der Größe (der X-Werte) nach sortieren lassen? Ob diese Sortierung gebraucht wird, kann ich noch nicht sagen.
    c) Muss ich bei Programmende auf eine bestimmte Reihenfolge achten. In Verwendung mit DataGrids hatte EdR gewarnt.

    egon schrieb:

    @ 'ErfinderDesRades Was hältst du von dem Vorschlag von VaporiZed?
    jo - ist doch gut: Wenn du in einer Klasse auf ein Dataset zugreifen willst, gib das Dataset beim Erstellen der Klasse mit hinein (Sub New mit Parameter).

    egon schrieb:

    Mich würde auch interessieren, ob mir die wichtigsten Zugriffsmöglichkeiten...
    Dann sollte dich mein englisches Tut in höchstem Masse interessieren.
    Da sind die Zugriffsmöglichkeiten nämlich ausführlich abgeklappert, und man erkennt auch die Systematik dahinter.
    Weiters ist da der ObjectBrowser abgeklappert, mit dem du dir diese Informationen auch selber holen kannst (bzw. nochmal nachsehen)
    codeproject.com/Articles/1030969/Relational-Datamodel - hab ich dir noch nie empfohlen?

    Einiger deiner "wichtigen Zugriffsmöglichkeiten" sind nur zur Hälfte Zugriffsmöglichkeiten des Datasets, die annere Hälfte macht Linq - also sowas:
    test3 = _DataSetToUse.Messreihe(0).GetMesswertRows.Select(Function(x) x.X_Wert).ToList
    Alles was nach .GetMesswertRows() sind keine Dataset-Member.
    Wie gesagt: lerne programmieren, lern die Systematiken - etwa hier: Linq und anonyme Methoden sind eminent wichtig - und natürlich auch wenn man mit typDts unterwegs ist.
    (Von jeder typDataTable jedes typDatasets jede AddMethode, und jede GetRows()-Methode auswendig lernen zu wollen belastet unnötig viel ArbeitsSpeicher im Gehirn - und kannste schlecht nach-kaufen.)



    BindingSources brauchste, wennde Daten in datengebundenen Controls präsentierst. Dazu sind die da, und sind ein hervorragendes Instrument. Zu was annerem sind sie nicht nütze.

    egon schrieb:

    sie nicht braue, wenn ich alle Zugriffe auf die Daten auf Code-Ebene durchführe?
    ich bin nicht sicher was du meinst.
    Wie gesagt: du brauchst sie nicht, wenn du Daten manipulierst. Du brauchst sie, wenn du Daten präsentierst - also dem User zur Ansicht und Bearbeitung gibst.
    Was meinst du mit

    egon schrieb:

    DataGridView & Co
    ? Wenn du das meinst, was ich damit meinen würde, dann würdest du den genauen Begriff dafür verwenden: "DatagridView & Co" - das sind Controls Nicht mehr und nicht weniger.
    Also nochmal: BindingSources brauchst du, wenn du Daten in datengebundenen Controls präsentieren willst.

    Vlt. kommt etwas VErwirrung daher, dass du bei deim Chart derzeit gar kein Databinding verwendest. Stattdessen bubbelst du da jeden einzelnen Punkt händisch ein.
    Ist vlt. nicht verkehrt, und auch bei Databinding würde intern ja auch nix anneres passieren.
    Könnte Nachteile haben, wenn du im Designer das Chart gestalten willst: Ein gebundenes Chart ermöglicht die Gestaltung im Designer - bei ungebunden musste deutlich mehr herumexperimentieren, und ziemlich eierigen Code schreiben (etwa um zu bestimmen, dass die Zeitachse nur die Tage des Monats anzeigt oder sowas)



    achso nochma zu prgrammiern lernen: Datenverarbeitungs-Vorraussetzungen - aber habich dir bestimmt auch schon mehrmals gegeben, odr?
    datengebundenes Chart: dazu wieder meine Frage aus Post#6, die dem TE wichtig war:

    VaporiZed schrieb:

    @ErfinderDesRades: Ist das auch eine Lösung für folgendes, ohne jetzt noch interpolierte X-Werte einzufügen:

    egon schrieb:
    da alle Datensätze eine unterschiedliche Anzahl an X-Werten haben.
    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.
    jo - issn Problem - hatte ich auch wieder nicht dran gedacht.
    Eine Lösung wäre, für das doofe Chart eine eigene DataTable zu schaffen, mit vereinheitlichter X-Achse (also Y-Werte müssen interpoliert werden).
    Nee - das macht auch kein Spass, und ist guter Grund, Databinding im Chart eben nicht anzuwenden.