DBA-UL commited on
Commit
8216787
·
1 Parent(s): 791a20d

Ajout du bouton d'upload manuel et du README

Browse files
Files changed (4) hide show
  1. README.md +50 -11
  2. index.html +7 -0
  3. main.js +45 -1
  4. style.css +25 -0
README.md CHANGED
@@ -1,11 +1,50 @@
1
- ---
2
- title: Monitoring
3
- emoji: 💻
4
- colorFrom: green
5
- colorTo: red
6
- sdk: static
7
- pinned: false
8
- short_description: Analyse de donnees
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Monitoring des Appareils ⚡️
2
+
3
+ Un tableau de bord moderne et interactif pour la visualisation et l'analyse en temps réel de données électriques (tension et intensité) issues de différents appareils.
4
+
5
+ ## 🌟 Fonctionnalités
6
+
7
+ - **Interface Glassmorphism** : Un design moderne, dynamique et visuellement attractif avec mode sombre et animations subtiles.
8
+ - **Visualisation de Données** : Graphiques interactifs (via Chart.js) pour la tension (V) et l'intensité (A).
9
+ - **Filtrage Avancé** :
10
+ - Filtrage temporel (par dates de début et de fin).
11
+ - Sélection spécifique par appareil (Appareil 1, Appareil 2, Appareil 3 ou Tous).
12
+ - **Calcul en Temps Réel** : Affichage dynamique des sommes de tension et d'intensité en fonction des filtres appliqués.
13
+ - **Seuils d'Alerte** : Définition de seuils critiques visuels avec une ligne d'alerte sur les graphiques.
14
+ - **Tolérance aux Pannes (Upload CSV)** : Si le fichier de données par défaut n'est pas trouvé (ex: problème de chemin lors du déploiement), l'interface permet d'importer manuellement le fichier CSV local.
15
+
16
+ ## 🛠 Technologies Utilisées
17
+
18
+ - **HTML5** : Structure de la page.
19
+ - **CSS3 (Vanilla)** : Stylisation avancée avec variables CSS, animations clés (keyframes), et effet Glassmorphism.
20
+ - **JavaScript (ES6)** : Logique de l'application et gestion du DOM.
21
+ - **Chart.js** : Librairie pour le rendu des graphiques.
22
+ - **PapaParse** : Lecture et parsing performant des fichiers CSV côté client.
23
+
24
+ ## 🚀 Utilisation en Local
25
+
26
+ Puisque le projet charge un fichier CSV (`donnees_appareils (1).csv`) de manière asynchrone, il est recommandé de l'exécuter via un serveur web local pour éviter les erreurs CORS du navigateur.
27
+
28
+ 1. Ouvrez un terminal dans le dossier du projet.
29
+ 2. Lancez un serveur HTTP, par exemple avec Python :
30
+ ```bash
31
+ python3 -m http.server 8000
32
+ ```
33
+ 3. Ouvrez votre navigateur à l'adresse `http://localhost:8000`.
34
+
35
+ ## 🌐 Déploiement (Hugging Face Spaces)
36
+
37
+ Ce projet est parfaitement adapté pour être hébergé sur les **Spaces Hugging Face** en tant que site statique :
38
+ 1. Créez un nouveau Space et sélectionnez l'option **Static**.
39
+ 2. Uploadez les fichiers `index.html`, `style.css`, `main.js` et votre fichier `.csv`.
40
+ 3. Le site sera instantanément disponible publiquement avec un lien partageable !
41
+
42
+ ## 📁 Structure des données (CSV)
43
+
44
+ Le fichier CSV attendu doit contenir au minimum les colonnes suivantes (séparées par des virgules) :
45
+ - `Date` (format YYYY-MM-DD)
46
+ - `Heure` (format HH:MM:SS)
47
+ - `Tension_Appareil_1`, `Tension_Appareil_2`, `Tension_Appareil_3`
48
+ - `Intensite_Appareil_1`, `Intensite_Appareil_2`, `Intensite_Appareil_3`
49
+
50
+ *(S'il vous manque des données, l'application les ignorera ou mettra la valeur à 0 de manière sécurisée).*
index.html CHANGED
@@ -84,6 +84,13 @@
84
  </div>
85
  </div>
86
 
 
 
 
 
 
 
 
87
  <button id="apply-btn" class="glow-on-hover">Appliquer les filtres</button>
88
  </aside>
89
 
 
84
  </div>
85
  </div>
86
 
87
+ <div class="control-group" id="upload-group" style="display: none;">
88
+ <label id="upload-label" class="alert-text">Fichier CSV introuvable. Veuillez le charger :</label>
89
+ <div class="input-wrapper">
90
+ <input type="file" id="csv-upload" accept=".csv" class="file-input">
91
+ </div>
92
+ </div>
93
+
94
  <button id="apply-btn" class="glow-on-hover">Appliquer les filtres</button>
95
  </aside>
96
 
main.js CHANGED
@@ -17,6 +17,7 @@ const colors = {
17
  document.addEventListener('DOMContentLoaded', () => {
18
  loadCSVData();
19
  document.getElementById('apply-btn').addEventListener('click', updateDashboard);
 
20
  });
21
 
22
  function loadCSVData() {
@@ -50,7 +51,50 @@ function loadCSVData() {
50
  },
51
  error: function(err) {
52
  console.error("Erreur CSV:", err);
53
- alert("Erreur lors de la lecture du fichier 'donnees_appareils (1).csv'.");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
  });
56
  }
 
17
  document.addEventListener('DOMContentLoaded', () => {
18
  loadCSVData();
19
  document.getElementById('apply-btn').addEventListener('click', updateDashboard);
20
+ document.getElementById('csv-upload').addEventListener('change', handleFileUpload);
21
  });
22
 
23
  function loadCSVData() {
 
51
  },
52
  error: function(err) {
53
  console.error("Erreur CSV:", err);
54
+ document.getElementById('upload-group').style.display = 'block';
55
+ console.log("Affichage du champ de chargement manuel activé.");
56
+ }
57
+ });
58
+ }
59
+
60
+ function handleFileUpload(event) {
61
+ const file = event.target.files[0];
62
+ if (!file) return;
63
+
64
+ Papa.parse(file, {
65
+ header: true,
66
+ dynamicTyping: true,
67
+ skipEmptyLines: true,
68
+ complete: function(results) {
69
+ console.log("Uploaded CSV Parsed:", results.data);
70
+ rawData = results.data;
71
+
72
+ if (rawData.length > 0) {
73
+ const dates = rawData.map(d => d.Date).filter(d => d);
74
+ if (dates.length > 0) {
75
+ const minDate = dates[0];
76
+ const maxDate = dates[dates.length - 1];
77
+
78
+ document.getElementById('start-date').value = minDate;
79
+ document.getElementById('end-date').value = maxDate;
80
+ document.getElementById('start-date').min = minDate;
81
+ document.getElementById('start-date').max = maxDate;
82
+ document.getElementById('end-date').min = minDate;
83
+ document.getElementById('end-date').max = maxDate;
84
+ }
85
+ }
86
+
87
+ if (!voltageChart || !currentChart) {
88
+ initializeCharts();
89
+ }
90
+ updateDashboard();
91
+
92
+ document.getElementById('upload-label').innerText = "Fichier chargé avec succès !";
93
+ document.getElementById('upload-label').style.color = "#00ff66";
94
+ },
95
+ error: function(err) {
96
+ console.error("Erreur lors du parse du fichier uploadé:", err);
97
+ alert("Erreur lors de la lecture du fichier uploadé.");
98
  }
99
  });
100
  }
style.css CHANGED
@@ -138,6 +138,31 @@ input:focus { border-color: var(--accent-blue); box-shadow: 0 0 10px rgba(0, 240
138
  .chart-container h2 { font-size: 1.3rem; margin-bottom: 1rem; color: var(--text-primary); }
139
  canvas { flex-grow: 1; width: 100% !important; height: 100% !important; }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  @media (max-width: 900px) {
142
  .dashboard { grid-template-columns: 1fr; }
143
  .summary-cards { grid-template-columns: 1fr; }
 
138
  .chart-container h2 { font-size: 1.3rem; margin-bottom: 1rem; color: var(--text-primary); }
139
  canvas { flex-grow: 1; width: 100% !important; height: 100% !important; }
140
 
141
+ .alert-text {
142
+ color: var(--accent-red);
143
+ font-size: 0.9rem;
144
+ font-weight: 600;
145
+ line-height: 1.4;
146
+ }
147
+
148
+ .file-input {
149
+ width: 100%;
150
+ background: rgba(0, 0, 0, 0.3);
151
+ border: 1px solid var(--accent-red);
152
+ color: white;
153
+ padding: 0.8rem;
154
+ border-radius: 10px;
155
+ font-family: var(--font-main);
156
+ font-size: 0.9rem;
157
+ outline: none;
158
+ transition: all 0.3s ease;
159
+ }
160
+
161
+ .file-input:focus {
162
+ border-color: var(--accent-blue);
163
+ box-shadow: 0 0 10px rgba(0, 240, 255, 0.2);
164
+ }
165
+
166
  @media (max-width: 900px) {
167
  .dashboard { grid-template-columns: 1fr; }
168
  .summary-cards { grid-template-columns: 1fr; }