Files
notytex/docs/features/STUDENT_AVERAGES_HISTOGRAM.md

182 lines
6.1 KiB
Markdown

# 📊 Histogramme des Moyennes des Élèves
## 🎯 **Vue d'ensemble**
Cette fonctionnalité ajoute un **histogramme interactif** des moyennes individuelles des élèves dans la card "Résultats" du dashboard de classe. L'histogramme se met à jour dynamiquement selon le trimestre sélectionné et offre une visualisation claire de la distribution des performances de la classe.
## ✨ **Fonctionnalités**
### **Affichage visuel**
- **Graphique en barres** utilisant Chart.js
- **Bins de 1 point** : 0-1, 1-2, ..., 19-20, 20+
- **Couleurs orange** cohérentes avec le thème de la card résultats
- **Animation fluide** lors des changements de trimestre
- **Design responsive** s'adaptant à tous les écrans
### **Interactivité**
- **Tooltips informatifs** : affichage du nombre d'élèves au survol
- **Mise à jour automatique** lors du changement de trimestre
- **Gestion des cas vides** avec message explicatif
### **Données calculées**
- **Moyennes individuelles** : calculées pour chaque élève sur le trimestre sélectionné
- **Normalisation sur 20** : toutes les moyennes sont ramenées sur 20 pour comparaison
- **Distribution automatique** : regroupement en bins de 1 point
## 🏗️ **Architecture technique**
### **Backend - Calcul des données**
#### Méthode `get_class_results()` dans `models.py`
```python
# Calcul des moyennes finales des élèves
student_final_averages = []
for student_id, scores in student_averages.items():
if scores:
avg = statistics.mean(scores)
student_final_averages.append(round(avg, 2))
# Création de l'histogramme des moyennes
if student_final_averages:
avg_bins = list(range(0, 22)) # 0-1, 1-2, ..., 20+
avg_bin_counts = [0] * (len(avg_bins) - 1)
for avg in student_final_averages:
bin_index = min(int(avg), len(avg_bin_counts) - 1)
avg_bin_counts[bin_index] += 1
```
**Retour enrichi :**
- `student_averages` : Liste des moyennes individuelles
- `student_averages_distribution` : Histogramme avec format `{range, count}`
#### API `/classes/{id}/stats`
```json
{
"results": {
"average": 12.46,
"min": 4.77,
"max": 17.79,
"student_averages": [11.8, 13.46, 13.84, ...],
"student_averages_distribution": [
{"range": "9-10", "count": 1},
{"range": "10-11", "count": 1},
{"range": "11-12", "count": 5},
{"range": "12-13", "count": 11}
]
}
}
```
### **Frontend - Affichage**
#### Template HTML (`class_dashboard.html`)
```html
<div class="bg-orange-50 rounded-lg p-4 border border-orange-100">
<h4 class="text-sm font-semibold text-orange-900 mb-3">
Distribution des moyennes
</h4>
<div class="relative h-32">
<canvas id="studentAveragesChart" class="w-full h-full"></canvas>
<div class="absolute inset-0 flex items-center justify-center"
data-chart-no-data style="display: none;">
Aucune donnée disponible
</div>
</div>
</div>
```
#### JavaScript (`ClassDashboard.js`)
```javascript
updateStudentAveragesChart(distribution) {
const canvas = document.getElementById('studentAveragesChart');
// Configuration Chart.js
this.studentAveragesChart = new Chart(canvas, {
type: 'bar',
data: {
labels: distribution.map(item => item.range),
datasets: [{
label: 'Nombre d\'élèves',
data: distribution.map(item => item.count),
backgroundColor: 'rgba(251, 146, 60, 0.8)',
borderColor: 'rgba(251, 146, 60, 1)'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
// Configuration complète...
}
});
}
```
## 🔧 **Configuration et Personnalisation**
### **Couleurs**
- **Barres** : `rgba(251, 146, 60, 0.8)` (orange avec transparence)
- **Bordures** : `rgba(251, 146, 60, 1)` (orange plein)
- **Grille** : `rgba(251, 146, 60, 0.1)` (orange très léger)
### **Paramètres Chart.js**
- **Type** : `bar` (graphique en barres)
- **Hauteur** : 128px (8rem en Tailwind)
- **Animation** : 800ms avec easing `easeInOutCubic`
- **Responsive** : Activé avec `maintainAspectRatio: false`
### **Bins de distribution**
- **Plage** : 0 à 20+ (21 bins au total)
- **Largeur** : 1 point par bin
- **Format** : "X-Y" (ex: "12-13") ou "20+" pour le dernier
## 📊 **Exemple d'utilisation**
### **Cas concret - 6ème A, Trimestre 1**
- **28 élèves** évalués
- **Moyennes** : entre 9.76 et 13.87
- **Distribution** :
- 1 élève entre 9-10
- 1 élève entre 10-11
- 5 élèves entre 11-12
- **11 élèves entre 12-13** (pic principal)
- **10 élèves entre 13-14**
### **Interprétation pédagogique**
- **Concentration** : Majorité des élèves entre 11 et 14
- **Homogénéité** : Classe relativement homogène
- **Niveau global** : Bon niveau avec moyenne générale de 12.46
## 🚀 **Activation**
La fonctionnalité est **automatiquement active** sur toutes les pages de dashboard de classe :
1. **Navigation** : Aller sur `/classes/{id}/dashboard`
2. **Sélection trimestre** : Choisir un trimestre (1, 2, 3 ou Global)
3. **Visualisation** : L'histogramme apparaît dans la card "Résultats"
## 🔍 **Dépannage**
### **Histogramme vide**
- **Cause** : Aucune évaluation corrigée pour ce trimestre
- **Solution** : Vérifier que les évaluations ont des notes saisies
### **Erreur Chart.js**
- **Cause** : Problème de chargement de la librairie
- **Solution** : Vérifier la connexion CDN Chart.js
### **Données incohérentes**
- **Cause** : Problème dans le calcul des moyennes
- **Solution** : Vérifier les types de notation (notes vs score)
## 📈 **Évolutions futures**
- **Export** : Possibilité d'exporter l'histogramme en PNG/SVG
- **Comparaison** : Affichage de plusieurs trimestres simultanément
- **Filtres** : Filtrage par élèves ou groupes d'élèves
- **Statistiques avancées** : Ajout de la courbe normale théorique
- **Personnalisation** : Choix des bins et des couleurs par l'utilisateur
---
✨ **Cette fonctionnalité enrichit considérablement l'analyse des résultats de classe en offrant une visualisation intuitive et interactive des performances des élèves.**