389 lines
13 KiB
Markdown
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 ?** 🚀
|