Skip to content
Snippets Groups Projects
Commit 3aabdf20 authored by Besson Lucas's avatar Besson Lucas
Browse files

Ajout de la répartition des scores par commune

parent 55083e85
No related branches found
No related tags found
No related merge requests found
const { generateDepartmentAveragesAndColors } = require('./indicateurs.js'); const { generateDepartmentAveragesAndColors } = require('./indicateurs.js');
const { generateMoyenne, generateMoyenneByYear, generateTop5Communes, generateFlop5Communes } = require('./metrics.js'); const { generateMoyenne, generateMoyenneByYear, generateTop5Communes, generateFlop5Communes, generateCommuneAveragesByScoreType } = require('./metrics.js');
const express = require("express"); const express = require("express");
const cors = require("cors"); const cors = require("cors");
...@@ -60,8 +60,20 @@ app.get("/api/communetopandflop5", async (req, res) => { ...@@ -60,8 +60,20 @@ app.get("/api/communetopandflop5", async (req, res) => {
} }
}); });
// exemple d'url pour la commune app.get("/api/communeaverage", async (req, res) => {
// http://localhost:5003/api/communetopandflop5?dept=1&year=2024&type=indicateurs const { dept = "1", year = "2024", type = "indicateurs" } = req.query;
try {
console.log(dept)
const averages = await generateCommuneAveragesByScoreType(dept, year, type);
res.json({ averages });
} catch (error) {
console.error('Erreur lors du calcul des moyennes par commune :', error);
res.status(500).send('Erreur lors du traitement des fichiers CSV');
}
});
// exemple d'url pour la commune average
// http://localhost:5003/api/communeaverage?dept=1&year=2024&type=indicateurs
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`Serveur lancé sur http://localhost:${PORT}`); console.log(`Serveur lancé sur http://localhost:${PORT}`);
......
...@@ -159,5 +159,6 @@ module.exports = { ...@@ -159,5 +159,6 @@ module.exports = {
generateMoyenne, generateMoyenne,
generateMoyenneByYear, generateMoyenneByYear,
generateTop5Communes, generateTop5Communes,
generateFlop5Communes generateFlop5Communes,
generateCommuneAveragesByScoreType
}; };
...@@ -11,6 +11,7 @@ const MetricMoyenneDepTop = ({ selectedDept = "1", typeIndic = "indicateurs", se ...@@ -11,6 +11,7 @@ const MetricMoyenneDepTop = ({ selectedDept = "1", typeIndic = "indicateurs", se
useEffect(() => { useEffect(() => {
setIsLoading(true); setIsLoading(true);
// Effectuer la requête pour récupérer les top5 et flop5 // Effectuer la requête pour récupérer les top5 et flop5
console.log("selectedDept : ", selectedDept)
axios axios
.get(`http://localhost:5003/api/communetopandflop5?dept=${selectedDept}&year=${selectedYear}&type=${typeIndic}`) .get(`http://localhost:5003/api/communetopandflop5?dept=${selectedDept}&year=${selectedYear}&type=${typeIndic}`)
.then((res) => { .then((res) => {
......
...@@ -2,6 +2,7 @@ import PropTypes from "prop-types"; ...@@ -2,6 +2,7 @@ import PropTypes from "prop-types";
import MetricsGraph from "./MetricsGraph"; import MetricsGraph from "./MetricsGraph";
import MetricMoyenne from "./MetricMoy"; import MetricMoyenne from "./MetricMoy";
import { MetricMoyenneDepTop, MetricMoyenneDepFlop } from "./MetricMoyDep"; import { MetricMoyenneDepTop, MetricMoyenneDepFlop } from "./MetricMoyDep";
import CommuneBarChart from "./MetricsGraphRep";
// Composant représentant un bloc de métrique // Composant représentant un bloc de métrique
const MetricBlock = ({ title, children, type }) => { const MetricBlock = ({ title, children, type }) => {
...@@ -48,19 +49,18 @@ const MetricsComponent = ({ ...@@ -48,19 +49,18 @@ const MetricsComponent = ({
scrollbarColor: "#213547 #f9f9f9", // Firefox scrollbarColor: "#213547 #f9f9f9", // Firefox
}} }}
> >
<h2 style={{ textAlign: "center" }}>📊 Statistiques</h2>
{/* Moyenne nationale */}
<MetricMoyenne typeIndic={typeIndic} selectedYear={selectedYear} />
{/* Graphique des moyennes */}
<MetricBlock title="Moyenne nationale du score selon les années">
<MetricsGraph typeIndic={typeIndic} selectedYear={selectedYear} selectedDept={selectedDept} />
</MetricBlock>
{/* Affichage conditionnel selon le département sélectionné */} {/* Affichage conditionnel selon le département sélectionné */}
{isDeptSelected ? ( {isDeptSelected ? (
<> <>
<h2 style={{ textAlign: "center" }}>📊 Statistiques (Département {selectedDept})</h2>
{/* Afficher la repartition des scores du département */}
<MetricBlock title={`Repartition des scores des communes du département ${selectedDept} en ${selectedYear}`}>
<CommuneBarChart typeIndic={typeIndic} selectedYear={selectedYear} selectedDept={selectedDept} />
</MetricBlock>
{/* Afficher les communes si un département est sélectionné */} {/* Afficher les communes si un département est sélectionné */}
<MetricBlock title={`Les 5 meilleures communes du département ${selectedDept} en ${selectedYear}`} type="top"> <MetricBlock title={`Les 5 meilleures communes du département ${selectedDept} en ${selectedYear}`} type="top">
<MetricMoyenneDepTop typeIndic={typeIndic} selectedYear={selectedYear} selectedDept={selectedDept} /> <MetricMoyenneDepTop typeIndic={typeIndic} selectedYear={selectedYear} selectedDept={selectedDept} />
...@@ -71,6 +71,14 @@ const MetricsComponent = ({ ...@@ -71,6 +71,14 @@ const MetricsComponent = ({
</> </>
) : ( ) : (
<> <>
<h2 style={{ textAlign: "center" }}>📊 Statistiques </h2>
{/* Moyenne nationale */}
<MetricMoyenne typeIndic={typeIndic} selectedYear={selectedYear} />
{/* Graphique des moyennes */}
<MetricBlock title="Moyenne nationale du score selon les années">
<MetricsGraph typeIndic={typeIndic} selectedYear={selectedYear} selectedDept={selectedDept} />
</MetricBlock>
{/* Afficher les départements si aucun département n'est sélectionné */} {/* Afficher les départements si aucun département n'est sélectionné */}
<MetricBlock title={`Les 5 meilleurs départements en ${selectedYear}`} type="top"> <MetricBlock title={`Les 5 meilleurs départements en ${selectedYear}`} type="top">
<ol> <ol>
......
import { useEffect, useState } from "react";
import * as d3 from "d3";
import axios from "axios";
import PropTypes from "prop-types";
const CommuneBarChart = ({ selectedDept = "", typeIndic = "indicateurs", selectedYear = "2024" }) => {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
setIsLoading(true);
axios
.get(`http://localhost:5003/api/communeaverage?dept=${selectedDept}&year=${selectedYear}&type=${typeIndic}`)
.then((res) => {
setData(res.data.averages);
setIsLoading(false);
})
.catch((err) => {
console.error("Erreur lors du chargement des moyennes par commune:", err);
setIsLoading(false);
});
}, [selectedDept, typeIndic, selectedYear]);
useEffect(() => {
if (data.length === 0) return;
// Définir les marges et dimensions du graphique
const margin = { top: 20, right: 30, bottom: 50, left: 50 },
width = 300 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
d3.select("#chart").selectAll("*").remove();
const svg = d3
.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// Trouver la valeur min et max des moyennes
const minValue = d3.min(data, (d) => d.average);
const maxValue = d3.max(data, (d) => d.average);
// Définir 10 intervalles de taille égale
const numBins = 10;
const binSize = (maxValue - minValue) / numBins;
const bins = d3.range(minValue, maxValue, binSize);
// Compter le nombre de communes par intervalle
const histogram = bins.map((binStart, i) => {
const binEnd = bins[i + 1] ?? maxValue;
return {
range: `${binStart.toFixed(2)} - ${binEnd.toFixed(2)}`,
count: data.filter((d) => d.average >= binStart && d.average < binEnd).length,
};
});
// Définir les échelles
const x = d3
.scaleBand()
.domain(histogram.map((d) => d.range))
.range([0, width])
.padding(0.2);
const y = d3
.scaleLinear()
.domain([0, d3.max(histogram, (d) => d.count)])
.nice()
.range([height, 0]);
// Ajouter les axes
svg
.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x).tickSize(5))
.selectAll("text")
.attr("transform", "rotate(-45)")
.style("text-anchor", "end")
.style("font-size", "10px");
svg.append("g").call(d3.axisLeft(y).tickSize(5));
// Ajouter les barres
svg
.selectAll(".bar")
.data(histogram)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", (d) => x(d.range))
.attr("y", (d) => y(d.count))
.attr("width", x.bandwidth())
.attr("height", (d) => height - y(d.count))
.attr("fill", "steelblue");
}, [data]);
return <div>{isLoading ? "Chargement des données..." : <div id="chart"></div>}</div>;
};
CommuneBarChart.propTypes = {
selectedDept: PropTypes.string,
typeIndic: PropTypes.string.isRequired,
selectedYear: PropTypes.string.isRequired,
};
export default CommuneBarChart;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment