IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Afficher sur un graph zoomable une grande quantité de données


Sujet :

C#

  1. #1
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut Afficher sur un graph zoomable une grande quantité de données
    Bonjour

    Besoin de base
    Je cherche à afficher sur un chart des séries de données de type Line avec possibilité de zoomer dans tous les sens très facilement (vue globale, vue de détail, vue d'un peu moins ensemble...)

    Problème de base
    Mon soucis vient de la grande quantité de points à afficher qui rend à la fois le chargement du chart très long et ensuite le zoom et autre sur le chart très lourd, inutilisable en pratique.
    J'ai jusqu'à une 12n de séries de plusieurs 100n de milliers de points à afficher.

    Pour le moment je travaille sur des CSV, dans l'avenir je pourrai optimiser un peu (j'espère) en passant par des fichiers binaires (donc moins gros)

    Quel code aujourd'hui ?
    J'arrive à afficher de 2 manières aujourd'hui
    solution avec lecture du CSV et ajout des points dans les séries au fil de l'eau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
                System.IO.StreamReader file = new System.IO.StreamReader(@"C:\0-PROJ\201306-220-11-MiniCoreV1\SOFT\WindowsFormsApplication3\WindowsFormsApplication3\ddd.csv");
     
                while (!file.EndOfStream) //tant que je ne suis pas à la fin du fichier
                {
                    string ligne = file.ReadLine(); //je lis une ligne
                    string[] tabCSV = ligne.Split(';'); //on recupère un tableau de string avec chaque contenu entre ;
                    //remplissage de la série
     
                    double date = DateTime.ParseExact(tabCSV[0], "dd/MM/yyyy HH:mm:ss", null).ToOADate();
                    double LaValeur1 = Convert.ToDouble(tabCSV[1]);
                    double LaValeur2 = Convert.ToDouble(tabCSV[2]);
     
                    chart2.Series["Series1"].Points.AddXY(date, LaValeur1);
                    chart2.Series["Series2"].Points.AddXY(date, LaValeur2);                
                }
    Ce code me permet d'afficher en 14secondes les 2 series de 200 000 points de mon CSV de test

    Autre solution en passant par une base de donnée SQL CE. On m'a consillié de faire avec ca, j'en ai bavé et le résultat est pas terrible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
                string cn = @"Data Source=C:\0-PROJ\201306-220-11-MiniCoreV1\SOFT\WindowsFormsApplication3\WindowsFormsApplication3\mesdata.sdf";
     
                SqlCeConnection connexion = new SqlCeConnection(cn);
     
                //vidage de la table
                string MaRequeteVidage = "DELETE FROM table1";
     
                SqlCeCommand cdeEffacement = new SqlCeCommand(MaRequeteVidage, connexion);
     
                cdeEffacement.Connection.Open();
                try
                {
                    cdeEffacement.ExecuteNonQuery();  //Execution de la requête 
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                cdeEffacement.Connection.Close();
     
     
                //  connexion.Open();
                string MaRequeteInsert = "INSERT INTO table1 ";
                MaRequeteInsert += " (DATE, Valeur1, Valeur2)";
                MaRequeteInsert += "VALUES(@ma_DATE, @ma_VALEUR1, @ma_VALEUR2)";
     
                //SqlCeCommand commande = connexion.CreateCommand();
                SqlCeCommand commande = new SqlCeCommand(MaRequeteInsert, connexion);
                int counter = 0;
                string line;
     
                // Read the file and display it line by line.
                System.IO.StreamReader file = new System.IO.StreamReader(@"C:\0-PROJ\201306-220-11-MiniCoreV1\SOFT\WindowsFormsApplication3\WindowsFormsApplication3\ccc.csv");
                line = file.ReadLine();
     
                commande.Parameters.Add("@ma_DATE", SqlDbType .BigInt);
                commande.Parameters.Add("@ma_VALEUR1", SqlDbType.BigInt);
                commande.Parameters.Add("@ma_VALEUR2", SqlDbType.BigInt);
     
     
                commande.Connection.Open();
                while ((line = file.ReadLine()) != null)
                {
                    string[] data = line.Split(';');
     
                    commande.Parameters["@ma_DATE"].Value = data[0];
                    commande.Parameters["@ma_VALEUR1"].Value = data[1];
                    commande.Parameters["@ma_VALEUR2"].Value = data[2];
     
                    int a = 0;
                    a++;
     
                    try
                    {
                        commande.ExecuteNonQuery();  //Execution de la requête 
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    counter++;
                }
     
                commande.Connection.Close();
                file.Close();
     
                // TODO: cette ligne de code charge les données dans la table 'mesdataDataSet.table1'. Vous pouvez la déplacer ou la supprimer selon vos besoins.
                this.table1TableAdapter.Fill(this.mesdataDataSet.table1);
                chart1.DataBind();
    Avec ce passage par une base de donnée le temps de chargement et d'affichage passe à 30s.

    2 questions
    1) Est il possible d'optimiser fortement mon code, avec ou sans BDD de manière à révolutionner les temps de chargement ?
    2) Sinon, comment puis je envisager l'affichage de mes données avec un zoom facile et fluide ?
    J'ai le sentiment qu'il est débile d'afficher autant de points sur un graph qui n'a pas autant de pixels à l’écran... mais en même temps, je ne vois pas comment afficher moins de points ('genre un point sur 1000) sans que ma vue perde tout son sens (que se passe t-il dans les 999 points que je n'aurais pas affiché!!???.

    Merci par avance pour vos critiques et vos idées
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Il faudrait déjà savoir si c'est la lecture du fichier (I/O), son analyse (parsing) ou l'affichage qui prend du temps. A mon avis c'est la lecture du fichier, sauf si le composant utilisé pour le graphe est très mal foutu (création de 200k objets WPF par exemple).

    Citation Envoyé par petitours Voir le message
    J'ai le sentiment qu'il est débile d'afficher autant de points sur un graph qui n'a pas autant de pixels à l’écran... mais en même temps, je ne vois pas comment afficher moins de points ('genre un point sur 1000) sans que ma vue perde tout son sens (que se passe t-il dans les 999 points que je n'aurais pas affiché!!???.
    En utilisant un index spatial tel qu'un quadtree : on divise l'espace en quatre. Chaque carré contient un booléen indiquant s'il y a ou non des points, et chaque carré contient à son tour quatre sous-carrés, et ainsi de suite.

    Avec ça tu as une structure de données capable de te dire en o(log(numObjets)) si tu dois afficher un point aux coordonnées (x, y), et très efficace pour déterminer la liste des pixels à peindre dans une région donnée. C'est ce qui est par exemple utilisé dans les jeux pour savoir quels objets de la scène dessiner à l'écran (version 3D : l'octree) .

    La construction prend du temps cependant, ce n'est rentable que si l'on n'affiche qu'une partie de l'espace et à nouveau il faudrait déjà savoir quel est le problème. Enfin et surtout c'est totalement superflu pour 200k points : un parcours direct pour créer un bitmap à la force brute serait simple et rapide (un CPU peut mouliner environ un milliard de points par seconde).

  3. #3
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Bonjour et un grand merci de mettre les pieds dans le plat.

    Est ce le chargement du CSV ou l'affichage sur le chart qui pose soucis ?
    A priori, d’après mes essais c'est très largement à cause du chart, que ce soit via le dataBing() ou via les points.Add

    Au delà du problème de chargement, il y a de toute manière problème avec le chart une fois rempli, il est très lent à réagir une fois rempli, les zooms prennent une éternité. L'application finale doit être archi fluent sur ces opérations là

    Pour illustrer au mieux le problème, voici le projet :
    www.68hc08.net/WindowsFormsApplication3.zip
    il y a tout dedans, y compris les csv de test.

    savoir "si le composant utilisé pour le graphe est très mal foutu " ?
    J'avais essayé il y a deux ans avec le composant Zedgraph. Ca allait un chouillia plus vite qu'avec le chart de MS intégré à Visual studio mais c'était plus difficile à utiliser.
    Aujourd'hui j'utilise chart de MS. Est il mal foutu avec la création de nombreux objets WPF ????? Il est très complet donc surement pas très léger de nature, mais je suis incompétent pour juger de son éventuelle état mal fichu.

    Faut il que je me crée mon propre composant ?, un truc tout léger qui fabrique à la force brute un bitmap ? (là il faut voir mon visage blanchir face à l'ampleur de la tâche bien que très excité à l'idée )

    Merci
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  4. #4
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bon ben le problème est donc que le contrôle n'a pas été prévu pour ça : MS a ciblé l'apparence et laissé de côté les scénarios avec un grand nombre de données. Pour un composant standard on ne peut pas leur en vouloir : ça répond aux besoins les plus communs.

    Du coup il faut avoir recours à la technique du bitmap, soit pour créer soi-même son graphe (ou en trichant avec un graphe sans points derrière lequel on mettra une image), soit pour éliminer les points redondants (en générant une vraie "bit map" : un booléen par pixel) voire carrément les points voisins en simpllifiant le graphe (un nuage de points je présume ?). Enfin il existe sans doute des composants optimisés pour de larges jeux de données.

  5. #5
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Bon ben le problème est donc que le contrôle n'a pas été prévu pour ça : MS a ciblé l'apparence et laissé de côté les scénarios avec un grand nombre de données. Pour un composant standard on ne peut pas leur en vouloir : ça répond aux besoins les plus communs.
    Je ne leur en veut pas, c'est un peu le sentiment que j'avais.
    Citation Envoyé par DonQuiche Voir le message
    Du coup il faut avoir recours à la technique du bitmap, soit pour créer soi-même son graphe (ou en trichant avec un graphe sans points derrière lequel on mettra une image), soit pour éliminer les points redondants (en générant une vraie "bit map" : un booléen par pixel) voire carrément les points voisins en simplifiant le graphe (un nuage de points je présume ?).
    Je n'ai pas tout compris sur ces 3 techniques envisageables.
    Simplifier le graph c'est la solution "compliquée" que j'avais en tête jusque là ; charger un chart MS avec beaucoup moins de points. Points sélectionnés, voir recalculés, en fonction du niveau de zoom. Mais ça fait de sacrés algos à monter ça ! Afficher pas tout,ok , mais quoi (le min ? le max ? une moyenne...) ???
    Ci joint une image d'un graph tel que j'ai besoin (des courbes, toutes sur le même axe X au format date, un ou plusieurs axes Y, un zoom ultra facile, un marquer qui indique le point de data, possibilité d'avoir une info bulle sur le point pour avoir la valeur, un curseur pour comparer plus facilement les courbes)
    Citation Envoyé par DonQuiche Voir le message
    Enfin il existe sans doute des composants optimisés pour de larges jeux de données.
    Des idées de où je peux trouver ca ? une idée de quoi ou dans quel domaine chercher ?

    Merci
    Images attachées Images attachées  
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  6. #6
    Membre expérimenté Avatar de callo
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2004
    Messages
    887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Togo

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 887
    Points : 1 699
    Points
    1 699
    Par défaut
    Citation Envoyé par petitours Voir le message
    Ci joint une image d'un graph tel que j'ai besoin (des courbes, toutes sur le même axe X au format date ...
    Merci
    Pour ça, tu peux utiliser les séries de MS Chart.
    N'oubliez pas le tag et

  7. #7
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Citation Envoyé par callo Voir le message
    Pour ça, tu peux utiliser les séries de MS Chart.
    C'est ce que j'utilise aujurd'hui, l'image que j'ai jointe est un MS chart.
    dans mon petit projet de test
    www.68hc08.net/WindowsFormsApplication3.zip
    j'utilise les séries via le Datasource et SQL CE
    ou directement en faisant des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chart1.Series[0].Points.AddXY(date,tabCSV[23]);
    J'obtiens exactement les fonctionnalités que je souhaite mais là avec seulement 2 séries de 200 000 points il me faut 14s pour charger le Chart.
    Les zoom et autres infos bulles sont ensuite quasi inutilisables sur le chart tellement il est alourdi par les séries.
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  8. #8
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par petitours Voir le message
    Je n'ai pas tout compris sur ces 3 techniques envisageables.
    Simplifier le graph c'est la solution "compliquée" que j'avais en tête jusque là ; charger un chart MS avec beaucoup moins de points. Points sélectionnés, voir recalculés, en fonction du niveau de zoom. Mais ça fait de sacrés algos à monter ça ! Afficher pas tout,ok , mais quoi (le min ? le max ? une moyenne...) ???
    Mais non, c'est super simple : mesure la largeur du composant "graph" et crée un tableau de booléens de même taille. Puis tu scannes tes points, tu convertis l'abscisse en index du tableau et si l'élément est "faux", tu le passes à vrai et tu ajoutes un point au graph. Dix lignes de code et tu t'en tirerais déjà avec moins de mille points affichés par série. Et si c'est toujours trop élevé et bien il faudra ensuite lisser la courbe, ce qui n'est pas si compliqué une fois que tu as ce tableau (en remplaçant les booléens par les ordonnées correspondantes).

  9. #9
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Mais non, c'est super simple : mesure la largeur du composant "graph" et crée un tableau de booléens de même taille. Puis tu scannes tes points, tu convertis l'abscisse en index du tableau et si l'élément est "faux", tu le passes à vrai et tu ajoutes un point au graph. Dix lignes de code et tu t'en tirerais déjà avec moins de mille points affichés par série. Et si c'est toujours trop élevé et bien il faudra ensuite lisser la courbe, ce qui n'est pas si compliqué une fois que tu as ce tableau (en remplaçant les booléens par les ordonnées correspondantes).
    Désolé mais je ne comprends toujours pas
    C'est la description de la création d'un bitmap ça ?

    Merci
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  10. #10
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Oui, c'est le procédure de création d'une "bit map" (sens propre).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    xmin, xmax, ymin, ymax = fenêtre affichée
    largeur = largeur du composant graph
    bitmap = new bool[largeur]
     
    pour chaque (x, y) à afficher
       index = xmin + 0.5 + (x * (xmax - xmin)) / largeur
     
       si bitmap [index] est faux
          bitmap [index] = vrai
          graph.AjouterPoint(x, y)
       fin
    fin

  11. #11
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Désolé mais je ne pige toujours pas le coup de l'index, vrai ou faux...
    il est défini à vrai ou faux où ?
    Le + 0.5 m'aide pas à comprendre avec X allant de 0 à 200000, l'index fait 0.5; 200.5, 400.5....

    L'idée c'est de dire que si j'ai 200000 points et que mon graph fait 1000 pixels alors je charge un point sur 200 sur mon graph ?
    Si oui, comment avoir un aperçu macroscopique des 199 points non affichés sur le graph ? Comment gérer le zoom dans ce ca, puisque le graph ne contient pas les points de détail ?

    Merci pour ta patience DonQuiche, je suis un peu dur de la feuille mais ça m'aide énormément !

    PS : Je viens de tenter un autre chargement de mon graphe, via un List<MaClass>. Le remplissage de la list prend une fraction de seconde, le databing() sur le graph prend une 12n de secondes ; c'est bien le chargement du graph qui prend des plombes !
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  12. #12
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Pas de problème.

    * Initialement chaque élément est faux et on passera un élément à vrai la première fois qu'on rencontrera un point correspondant. C'est simplement un moyen d'éviter de créer plusieurs fois des points dans cette case. D'ailleurs, sorti du contexte de cette discussion, il vaudrait mieux renommer "bitmap" en "initialized" ou quelque chose de ce genre.

    * Veut-on que le i-ème pixel correspond à la tranche [xi, xi + dx] ou [xi - dx / 2 ; xi + dx / 2] ? C'est le rôle du +0.5. C'est un détail et de toute façon pour être rigoureux il faut harmoniser cette formule avec l'abscisse utilisée pour représenter le point, ce que je n'ai pas fait (j'ai pris le premier couple x,y venu). Dans le même genre on devrait moyenner "y" en prenant tous les points de l'index. Mais tout ça sera quasiment invisible aux yeux de l'utilisateur, donc autant ne pas s'ennuyer, rester simple et virer le 0.5

    * Enfin index n'est pas égal à "*.5", c'est un réel quelconque puisque x est lui-même un réel quelconque. Il faudra le convertir en entier avant de l'utiliser comme indice, il aurait été plus pédagogue de ma part d'écrire explicitement cette conversion, je comprends que ça t'ait troublé.

    L'idée c'est de dire que si j'ai 200000 points et que mon graph fait 1000 pixels alors je charge un point sur 200 sur mon graph ?
    Si oui, comment avoir un aperçu macroscopique des 199 points non affichés sur le graph ? Comment gérer le zoom dans ce ca, puisque le graph ne contient pas les points de détail ?
    C'est bien l'idée et tu es supposé reconstruire les points à chaque fois que l'utilisateur zoome ou se déplace. Bref, chaque fois que largeur, xmin, xmax, ymin et ymax sont modifiés.

    Cela dit je ne connais pas assez le contrôle Graph pour garantir que ça fonctionnera comme attendu (encaissera t-il les mille points ? Peut-on déterminer la fenêtre visible et détecter son changement ?). Je ne fais pas de promesse, je me contente de détailler les pistes qui me viennent à l'esprit.

  13. #13
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Le problème n'est pas le chargement du fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    using System;
    using System.Collections.Generic;
    using System.Text;
     
    namespace TestLoadCvs
    {
      class Program
      {
        private struct toto
        {
          public double dt;
          public double LaValeur1;
          public double LaValeur2;
        }
     
        static void Main(string[] args)
        {
          List<toto> lt = new List<toto>();
     
          System.IO.StreamReader file = new System.IO.StreamReader(@"C:\TestLoadCvs\ddd.csv");
     
          while (!file.EndOfStream) //tant que je ne suis pas à la fin du fichier
          {
            string ligne = file.ReadLine(); //je lis une ligne
            string[] tabCSV = ligne.Split(';'); //on recupère un tableau de string avec chaque contenu entre ;
            //remplissage de la série
     
            toto tt = new toto();
     
            tt.dt = DateTime.ParseExact(tabCSV[0], "dd/MM/yyyy HH:mm:ss", null).ToOADate();
            tt.LaValeur1 = Convert.ToDouble(tabCSV[1]);
            tt.LaValeur2 = Convert.ToDouble(tabCSV[2]);
     
            lt.Add(tt);
          }
        }
      }
    }
    Le fichier que vous avez fourni se charge en une seconde avec le code ci-dessus (sans le Chart2), et certainement moins sur un PC dernier cri.

    Le problème vient après. C'est le genre d'application où j'utiliserais DirectX pour l'affichage.

  14. #14
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    Bonjour

    Si pour utiliser moins lourdement le composant chart je dois reconstituer les fonctionnalités de zoom le composant chart perd de son intérêt...et ça devient encore plus lourd

    Plus j'avance plus je vois qu'il va être délicat de contourner la création de mon propre composant ! outch.

    DirectX ? Ce serait pour créer mon propre affichage, sans passer par un composant tout fait ?

    Merci
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  15. #15
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Mais non, tu n'aurais pas besoin de recréer le zoom, seulement de le détecter. On parle de quinze lignes de code au total si c'est possible, on est loin de la recréation d'un contrôle ! Ca ce serait la dernière étape.

    Quant à DirectX, ça me semble personnellement une mauvaise idée : trop lourd, pas nécessaire, trop de problèmes de compatibilité. Si on avait eu beaucoup plus de points, oui, mais au-dessous de quelques millions ou dizaines de millions de points on peut toujours générer les pixels manuellement, ce qui est beaucoup plus simple.

  16. #16
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    encaissera t-il les mille points ? Peut-on déterminer la fenêtre visible et détecter son changement ?
    J'ai testé ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          float taille = chart1.ChartAreas[0].Position.Width;
                MessageBox.Show(taille.ToString());
    ca semble indiquer en % la taille du graphique. Le calcul en croix ne me donne pas un chiffre entier...étrange.

    Mille points c'est nettement moins lourd que 200000.

    peut on detecter le changement de la fenetre, oui:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            private void chart1_SizeChanged(object sender, EventArgs e)
            {
     
            }
     
            private void chart1_Resize(object sender, EventArgs e)
            {
                MessageBox.Show(" ca a changé!");
            }
    les deux fonctionnent. C'est juste pas très pratique quand on redimensionne à la fenetre par les curseurs manuels parce que ça déclenche pendant le déplacement, pas seulement une fois que l'on a fini le redimensionnement.

    On peut aussi savoir s'il y a eu zoom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            private void chart2_AxisViewChanging(object sender, ViewEventArgs e)
            {
                MessageBox.Show("On a demandé un zoom, il ne s'est pas encore fait");
            }
    c'est bon signe ca, non ?

    Si je comprends bien je dois faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Sur changement de zoom ou du lot de données
    =>regarder la taille du graphique
    =>taille d'un lot = quantité de data/taille graphique
    =>pour chaque lot, calculer la moyenne (ou autre) et ajouter le point au graphique
    c'est ca ?
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  17. #17
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par petitours Voir le message
    c'est bon signe ca, non ?
    Si tu peux tout détecter, pan & scan (défilement avec bouton de souris appuyé), zoom, etc, c'est très bon, oui.

    Il faut encore vérifier si on peut ajouter mille points à volée sans conséquence mais on verra vite ça.

    Sur changement de zoom ou du lot de données
    =>regarder la taille du graphique
    =>taille d'un lot = quantité de data/taille graphique
    =>pour chaque lot, calculer la moyenne (ou autre) et ajouter le point au graphique
    Si par lot tu veux dire les points d'un même pixel, en subtance c'est ça. Sauf que la taille d'un lot peut varier : si en moyenne c'est 10.3, ce sera parfois 10, parfois 11. Si tu veux agréger les points plutôt que de prendre le premier venu tu dois donc avoir deux tableaux : un comptant le nombre de points pour chaque pixel, l'autre la somme des ordonnées.

  18. #18
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    J'ai attaqué la montagne, ça n'avance pas vite mais je sens la solution au bout du clavier

    Petite question bigrement structurante que tout ça soulève :
    constat 1 : Mes données ont toutes en abscisse les dates que j'ai dans la première colonne de mon tableau
    constat 2 : Ces dates ne se suivent pas forcément à des inter vals de temps réguliers

    Comment je fais pour charger les bonnes données quand je zoome ?
    Ce n'est pas là que la base de données devient utile ? afin de filtrer mes données en fonction du xmin et Xmax choisi au moment du zoom ?

    Je n'aime pas la base de donnée mais là je me demande si c'est pas le plus simple du coup...

    Merci pour cette aide formidable !
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

  19. #19
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Non, on s'en cogne de la base de données.
    Ca ne sera pas plus simple, ça ne sera même pas plus rapide, ça sera juste plus lourd et verbeux.

    Ce que tu as à faire est simple :
    * D'abord tu dissocies le chargement de l'affichage. Tu charges une seule fois et tu gardes tout en mémoire dans une liste.
    * Ensuite tu reprends le code dont on a discuté jusque là, tu passes toute la liste en revue et tu zappes simplement les cas où index est en-dehors des bornes du tableau (0 <= x < array.Length) : ce sont les cas où les points sont en-dehors de la fenêtre actuellement visible du graphique.

    Avec ça on se fiche que tes points ne soient pas à intervalles réguliers, l'algo ne créera pas de point pour les pixels vides.

  20. #20
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 935
    Points : 2 013
    Points
    2 013
    Par défaut
    je fais ça à la force brute, en partant du début jusqu'à la fin, comme un bourrin mécano que je suis ?
    c'est vrai ? j'ai le droit ?
    Il y a 10 sortes de personnes dans le monde : ceux qui comprennent le binaire et les autres

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Envoyer une grande quantité de données dans un xml via http
    Par qdaemon_fr dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 03/03/2009, 09h51
  2. Manipulation d'une grande quantité de données
    Par sebastyen dans le forum Langage
    Réponses: 1
    Dernier message: 10/11/2008, 15h54
  3. Réponses: 11
    Dernier message: 23/09/2008, 15h39
  4. Une grande quantité de données sur Oracle 8i?
    Par bliml dans le forum Oracle
    Réponses: 13
    Dernier message: 01/03/2007, 11h45
  5. Réponses: 1
    Dernier message: 10/01/2007, 15h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo