Files
webval/module/ETAPE_3_AJUSTEE_TABLEAU_NOTES.md

389 lines
13 KiB
Markdown

# 📊 ÉTAPE 3 AJUSTÉE : TABLEAU NOTES + GRAPHIQUES PAR CLASSE
## 🎯 **AJUSTEMENTS SELON SPECS NICOLAS**
### Graphiques
-**Histogramme distribution notes PAR CLASSE** (multi-barres)
-**Courbe progression PAR ÉLÈVE** (line chart multiple students)
-**Pas de pie chart** (supprimé)
### Tentatives
- **Normale** : 1 seule tentative par élève
- **Exception** : Si pb connexion, plusieurs tentatives possibles
- **Affichage** : Dernière tentative de chaque élève
### Export
- **Réutiliser** : `export.php` existant (CSV/JSON) ✅
- **Lien** : Bouton vers `export.php?id_evaluation=X&format=csv`
- **Pas de modifications** : Minimiser changements code fonctionnel
### Pagination
- **Aucune** : Affichage complet sans pagination
- **Raisons** :
- Classes fixes : Max 30 élèves
- Groupe soutien : Max 60-70 élèves
- Performance suffisante pour 100 lignes
---
## 📋 **SPÉCIFICATIONS FONCTIONNELLES AJUSTÉES**
### Vue Tableau
**Colonnes** :
1. Rang (calculé selon note)
2. Nom Prénom
3. Classe
4. Note (/20)
5. Pourcentage (%)
6. Temps passé (HH:MM:SS)
7. Statut (Terminé / En cours)
8. Date soumission
**Fonctionnalités** :
- Tri par colonne (clic header)
- Filtrage par classe (dropdown)
- Filtrage par statut (terminé/en cours)
- Recherche élève (nom, prénom)
- **Export CSV** : Lien vers export.php existant
- **Pas de pagination** : Affichage complet
### Statistiques Générales
**Bloc 1 : Synthèse**
- Nombre d'élèves total
- Nombre terminé / en cours
- Taux participation (%)
- Temps moyen passé
**Bloc 2 : Notes**
- Moyenne générale
- Médiane
- Note min / max
- Écart-type
- Taux réussite (≥10/20) en %
**Bloc 3 : Par Classe**
- Nombre élèves par classe
- Moyenne par classe
- Meilleure classe (moyenne max)
**Bloc 4 : Questions**
- Question la plus réussie (% bonnes réponses)
- Question la plus échouée (% mauvaises réponses)
### Graphiques Chart.js
**Graphique 1 : Histogramme Distribution Notes par Classe**
- Type : Bar chart (multi-datasets)
- X : Tranches notes (0-5, 5-10, 10-15, 15-20)
- Y : Nombre élèves
- Datasets : 1 barre par classe (couleurs différentes)
- Légende : Classes affichées
- Couleurs : Palette distincte par classe
**Graphique 2 : Courbe Progression par Élève**
- Type : Line chart (multiple lines)
- X : Numéro question (Q1, Q2, Q3, ...)
- Y : Points cumulés (0 à note_totale)
- Lines : Top 5 élèves + moyenne classe
- Légende : Noms élèves
- Couleurs : Palette distincte par élève
- Tooltip : Détail question + points
---
## 🗂️ **STRUCTURE FICHIERS**
### Fichier principal
**`resultats_evaluation.php`** (~30 KB estimé)
- Localisation : `/var/www/mathematiques/enseignant/`
- Rôle : Interface HTML + CSS + JavaScript inline
- Chart.js : CDN `https://cdn.jsdelivr.net/npm/chart.js@4.4.0`
- Paramètre : `?id_evaluation=X`
- **Réutilise** : Lien export.php existant
### API Backend
**`resultats_ajax.php`** (~20 KB estimé)
- Localisation : `/var/www/mathematiques/enseignant/`
- Rôle : Retourne JSON avec notes + stats + graphiques data
- Authentification : `$_SESSION['user_id']` + `type_libelle === 'enseignant'`
- Requêtes SQL optimisées
---
## 🔧 **ARCHITECTURE TECHNIQUE**
### Colonnes tentatives_eleves (vérifiées)
```
id_tentative (INT)
id_eleve (INT)
id_evaluation (INT)
statut (VARCHAR) : 'en_cours', 'terminee'
reponses_json (TEXT)
note (DECIMAL) : Note obtenue
note_sur (DECIMAL) : Note maximale (20)
pourcentage (DECIMAL) : Pourcentage réussite
temps_passe (INT) : Secondes écoulées
date_debut (TIMESTAMP)
date_fin (TIMESTAMP)
derniere_sauvegarde (TIMESTAMP)
```
### Requête SQL Principale (Dernière tentative par élève)
```sql
SELECT
te.id_tentative,
te.id_eleve,
te.note,
te.note_sur,
te.pourcentage,
te.temps_passe,
te.statut,
te.date_fin,
te.reponses_json,
u.nom,
u.prenom,
u.login,
c.nom_classe,
c.id_classe,
-- Calcul rang global
(SELECT COUNT(*) + 1
FROM tentatives_eleves te2
WHERE te2.id_evaluation = te.id_evaluation
AND te2.note > te.note
AND te2.id_tentative IN (
-- Sous-requête: dernière tentative de chaque élève
SELECT MAX(id_tentative)
FROM tentatives_eleves
WHERE id_evaluation = te.id_evaluation
GROUP BY id_eleve
)
) as rang
FROM (
-- Sous-requête: dernière tentative par élève
SELECT id_eleve, MAX(id_tentative) as max_id
FROM tentatives_eleves
WHERE id_evaluation = ?
GROUP BY id_eleve
) dernieres
JOIN tentatives_eleves te ON te.id_tentative = dernieres.max_id
JOIN utilisateurs u ON te.id_eleve = u.id_utilisateur
LEFT JOIN classes c ON u.id_classe = c.id_classe
ORDER BY te.note DESC, te.date_fin ASC
```
### Calculs Statistiques (PHP)
```php
// Notes array (dernières tentatives uniquement)
$notes = array_column($tentatives, 'note');
// Moyenne
$moyenne = array_sum($notes) / count($notes);
// Médiane
sort($notes);
$count = count($notes);
$mediane = ($count % 2 === 0)
? ($notes[$count/2 - 1] + $notes[$count/2]) / 2
: $notes[floor($count/2)];
// Écart-type
$variance = 0;
foreach ($notes as $note) {
$variance += pow($note - $moyenne, 2);
}
$ecart_type = sqrt($variance / count($notes));
// Taux réussite
$reussites = count(array_filter($notes, fn($n) => $n >= 10));
$taux_reussite = ($reussites / count($notes)) * 100;
// Stats par classe
$par_classe = [];
foreach ($tentatives as $t) {
$classe = $t['nom_classe'] ?? 'Sans classe';
if (!isset($par_classe[$classe])) {
$par_classe[$classe] = ['notes' => [], 'count' => 0];
}
$par_classe[$classe]['notes'][] = $t['note'];
$par_classe[$classe]['count']++;
}
foreach ($par_classe as $classe => &$data) {
$data['moyenne'] = array_sum($data['notes']) / count($data['notes']);
}
```
### Données Graphiques
**Histogramme par Classe** :
```json
{
"labels": ["0-5", "5-10", "10-15", "15-20"],
"datasets": [
{
"label": "TCV",
"data": [1, 3, 8, 12],
"backgroundColor": "rgba(59, 130, 246, 0.6)"
},
{
"label": "1A",
"data": [0, 2, 5, 8],
"backgroundColor": "rgba(34, 197, 94, 0.6)"
}
]
}
```
**Courbe Progression** :
```json
{
"labels": ["Q1", "Q2", "Q3", "Q4", "Q5"],
"datasets": [
{
"label": "DUPONT Jean (19/20)",
"data": [4, 8, 12, 16, 19],
"borderColor": "rgb(59, 130, 246)",
"tension": 0.3
},
{
"label": "MARTIN Sophie (18/20)",
"data": [3, 7, 11, 14, 18],
"borderColor": "rgb(34, 197, 94)",
"tension": 0.3
},
{
"label": "Moyenne classe",
"data": [2.5, 5.2, 8.1, 11.3, 14.5],
"borderColor": "rgb(249, 115, 22)",
"borderDash": [5, 5],
"tension": 0.3
}
]
}
```
---
## 🎨 **DESIGN INTERFACE**
### Layout 3 Zones
```
┌────────────────────────────────────────────────────────┐
│ 📊 Résultats Évaluation : [Titre Évaluation] │
│ [Retour Dashboard] [Export CSV] │
├────────────────────────────────────────────────────────┤
│ 📈 STATISTIQUES GÉNÉRALES │
│ ┌────────┬────────┬────────┬────────┬────────┐ │
│ │ 42 │ 38 │ 15.2 │ 8.5 │ 19.0 │ │
│ │ Élèves │ Terminé│ Moyenne│ Min │ Max │ │
│ └────────┴────────┴────────┴────────┴────────┘ │
│ ┌────────┬────────┬────────┬────────┬────────┐ │
│ │ 14.8 │ 3.2 │ 90% │ TCV │ 01:23 │ │
│ │ Médiane│ Écart-σ│ Réussite│Meilleure│ Temps │ │
│ └────────┴────────┴────────┴────────┴────────┘ │
├────────────────────────────────────────────────────────┤
│ 📊 GRAPHIQUES ANALYTIQUES │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Histogramme Distribution Notes par Classe │ │
│ │ [Chart.js Bar - Multi-datasets] │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Courbe Progression par Élève (Top 5 + Moyenne) │ │
│ │ [Chart.js Line - Multiple lines] │ │
│ └──────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────┤
│ 📋 TABLEAU DÉTAILLÉ │
│ [Filtre Classe ▼] [Filtre Statut ▼] [Recherche 🔍] │
│ ┌────┬──────────┬────────┬──────┬────────┬──────────┐│
│ │ Rg │ Élève │ Classe │ Note │ % │ Temps ││
│ ├────┼──────────┼────────┼──────┼────────┼──────────┤│
│ │ 1 │ DUPONT │ TCV │19/20 │ 95% │ 01:23:45 ││
│ │ 2 │ MARTIN │ TCV │18/20 │ 90% │ 01:05:12 ││
│ │ 3 │ BERNARD │ 1A │17/20 │ 85% │ 00:58:30 ││
│ │ .. │ ... │ ... │ ... │ ... │ ... ││
│ └────┴──────────┴────────┴──────┴────────┴──────────┘│
│ Total : 42 élèves affichés │
└────────────────────────────────────────────────────────┘
```
---
## ✅ **CHECKLIST DÉVELOPPEMENT**
### Étape 1 : Vérification Structure BDD ✅
- [x] Colonnes tentatives_eleves vérifiées
- [x] Format temps_passe : INT secondes
- [x] Requête dernière tentative par élève
- [x] Jointures users/classes
### Étape 2 : Backend API
- [ ] Créer `resultats_ajax.php`
- [ ] Authentification `$_SESSION` (pattern export.php)
- [ ] Requête SQL dernières tentatives + rang
- [ ] Calculs statistiques (moyenne, médiane, écart-type)
- [ ] Stats par classe
- [ ] Analyse questions (% réussite par question)
- [ ] Progression par élève (points cumulés)
- [ ] Formatage données graphiques
- [ ] Test retour JSON valide
### Étape 3 : Frontend Interface
- [ ] Créer `resultats_evaluation.php`
- [ ] Header + navigation
- [ ] Section statistiques (8 cards)
- [ ] Graphique histogramme par classe
- [ ] Graphique courbe progression élèves
- [ ] Tableau notes complet
- [ ] Filtres classe/statut (JavaScript)
- [ ] Recherche élève (JavaScript)
- [ ] Tri colonnes (JavaScript)
- [ ] Bouton export CSV (lien export.php)
- [ ] Responsive design
### Étape 4 : Tests
- [ ] Tester avec évaluation 23 (test.tcv)
- [ ] Vérifier stats cohérentes
- [ ] Vérifier graphiques par classe
- [ ] Vérifier courbe progression
- [ ] Tester filtres/recherche/tri
- [ ] Tester export CSV
- [ ] Performance <2s chargement 70 élèves
---
## 📊 **ESTIMATION DURÉE AJUSTÉE**
| Tâche | Durée | Détails |
|-------|-------|---------|
| Vérification BDD | 15 min | **Complété** |
| Backend API | 60 min | SQL complexe + stats + progression |
| Frontend HTML/CSS | 45 min | Layout + stats + graphiques |
| Frontend JavaScript | 45 min | Filtres + tri + recherche + charts |
| Tests validation | 20 min | Données réelles multi-classes |
| **TOTAL** | **3h05** | Estimation réaliste |
---
## 🚀 **PROCHAINE ACTION**
**Démarrer Backend API** : Créer `resultats_ajax.php`
1. Requête SQL dernières tentatives
2. Calculs statistiques
3. Données graphiques
4. Test JSON
**Puis Frontend** : Interface complète avec Chart.js
---
**Prêt à développer ?** 🚀