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
Ce code me permet d'afficher en 14secondes les 2 series de 200 000 points de mon CSV de test
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); }
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 :
Avec ce passage par une base de donnée le temps de chargement et d'affichage passe à 30s.
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();
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
Partager