diff --git a/nupes-elections-front/src/App.js b/nupes-elections-front/src/App.js
index 461e7db..fbe4eb8 100644
--- a/nupes-elections-front/src/App.js
+++ b/nupes-elections-front/src/App.js
@@ -10,28 +10,12 @@ function App() {
element: ,
},
{
- path: "/elections/europeennes/2024/france/",
- element: ,
+ path: "/elections/europeennes/2024/:typeResultats/",
+ element: ,
},
{
- path: "/elections/europeennes/2024/region/:zoneId/",
- element: ,
- },
- {
- path: "/elections/europeennes/2024/circonscription/:zoneId/",
- element: ,
- },
- {
- path: "/elections/europeennes/2024/departement/:zoneId/",
- element: ,
- },
- {
- path: "/elections/europeennes/2024/commune/:zoneId/",
- element: ,
- },
- {
- path: "/elections/europeennes/2024/bureau_vote/:zoneId/",
- element: ,
+ path: "/elections/europeennes/2024/:typeResultats/:zoneId/",
+ element:
},
])
diff --git a/nupes-elections-front/src/Elections2024.js b/nupes-elections-front/src/Elections2024.js
index 35d9913..58158be 100644
--- a/nupes-elections-front/src/Elections2024.js
+++ b/nupes-elections-front/src/Elections2024.js
@@ -16,6 +16,7 @@ import {useEffect, useMemo, useState} from "react"
import {GeoJSON, MapContainer, Popup, TileLayer, useMap} from "react-leaflet"
import 'leaflet/dist/leaflet.css'
+import {MenuItem, Select} from "@mui/material";
highchartsItem(Highcharts)
@@ -125,8 +126,22 @@ function ParticipationTable({resultats}) {
>
}
-function RegionGeoJSON({resultats_region, listes, blocs, nuances, grouperParBloc = false}) {
- const voix_listes = resultats_region?.voix_listes ?? {}
+function ZoneGeoJSON({resultatsZone, typeZone, listes, blocs, nuances, grouperParBloc = false}) {
+ const [idZone, nomZone] = useMemo(() => {
+ if (!resultatsZone[typeZone])
+ return ["", ""]
+
+ if (typeZone === "region" || typeZone === "departement" || typeZone === "commune")
+ return [resultatsZone[typeZone].code_insee, resultatsZone[typeZone].nom]
+ else if (typeZone === "circonscription")
+ return [resultatsZone.circonscription.id, `Circonscription ${resultatsZone.circonscription.id}`]
+ else if (typeZone === "bureau_vote")
+ return [resultatsZone.bureau_vote.id, resultatsZone.bureau_vote.libelle]
+ else
+ return ["", ""]
+ }, [typeZone, resultatsZone])
+
+ const voix_listes = resultatsZone?.voix_listes ?? {}
const listes_triees = listes.toSorted((l1, l2) => {
return (voix_listes[l2.numero] || 0) - (voix_listes[l1.numero] || 0)
})
@@ -141,8 +156,8 @@ function RegionGeoJSON({resultats_region, listes, blocs, nuances, grouperParBloc
}
for (let liste of listes) {
- voixParBloc[liste.bloc] += resultats_region.voix_listes[liste.numero] || 0
- voixParNuance[liste.nuance] += resultats_region.voix_listes[liste.numero] || 0
+ voixParBloc[liste.bloc] += resultatsZone.voix_listes[liste.numero] || 0
+ voixParNuance[liste.nuance] += resultatsZone.voix_listes[liste.numero] || 0
}
let couleur = 'grey'
@@ -166,89 +181,43 @@ function RegionGeoJSON({resultats_region, listes, blocs, nuances, grouperParBloc
}
return
+ data={{'type': "Feature", 'geometry': resultatsZone.geometry}}
+ style={{fillColor: couleur, fillOpacity: 0.5, color: 'white', weight: 1}}>
- {resultats_region.region.nom}
+ {nomZone}
{listes_triees.slice(0, 5).map(liste =>
- - {liste.nom} : {voix_listes[liste.numero]} ({(100 * voix_listes[liste.numero] / resultats_region.exprimes).toFixed(2)} %)
)}
+ - {liste.nom} : {voix_listes[liste.numero]} ({(100 * voix_listes[liste.numero] / resultatsZone.exprimes).toFixed(2)} %)
)}
}
-
-function DepartementGeoJSON({resultats_departement, listes, blocs, nuances, grouperParBloc = false}) {
- const voix_listes = resultats_departement?.voix_listes ?? {}
- const listes_triees = listes.toSorted((l1, l2) => {
- return (voix_listes[l2.numero] || 0) - (voix_listes[l1.numero] || 0)
- })
-
- const voixParBloc = {}
- const voixParNuance = {}
- for (let bloc of blocs) {
- voixParBloc[bloc.nom] = 0
- }
- for (let nuance of nuances) {
- voixParNuance[nuance.code] = 0
- }
-
- for (let liste of listes) {
- voixParBloc[liste.bloc] += resultats_departement.voix_listes[liste.numero] || 0
- voixParNuance[liste.nuance] += resultats_departement.voix_listes[liste.numero] || 0
- }
-
- let couleur = 'grey'
- if (grouperParBloc) {
- let maxVoix = 0
- for (let bloc of blocs) {
- if (voixParBloc[bloc.nom] > maxVoix) {
- maxVoix = voixParBloc[bloc.nom]
- couleur = bloc.couleur
- }
- }
- }
- else {
- let maxVoix = 0
- for (let nuance of nuances) {
- if (voixParNuance[nuance.code] > maxVoix) {
- maxVoix = voixParNuance[nuance.code]
- couleur = nuance.couleur
- }
- }
- }
-
- console.log(resultats_departement.departement.code_insee, resultats_departement.geometry)
-
- return
-
- {resultats_departement.departement.nom}
-
- {listes_triees.slice(0, 5).map(liste =>
- - {liste.nom} : {voix_listes[liste.numero]} ({(100 * voix_listes[liste.numero] / resultats_departement.exprimes).toFixed(2)} %)
)}
-
-
-
-}
-
-function ContenuCarte({typeResultats, resultats, listes, blocs, nuances, grouperParBloc = false}) {
+function ContenuCarte({typeResultats, resultats, typeZone, listes, blocs, nuances, grouperParBloc = false}) {
const map = useMap()
+ console.log(typeZone)
+
const [resultatsZones, setResultatsZones] = useState([])
- const [typeZone, zones] = useMemo(() => {
- if (typeResultats === "france") {
- return ["regions", resultats?.france?.regions ?? []]
- }
- else if (typeResultats === "regions") {
- return ["departements", resultats?.region?.departements ?? []]
- }
- }, [typeResultats, resultats])
+ const zones = useMemo(() => {
+ const data = resultats[typeResultats]
+ if (!data)
+ return []
+
+ if (typeZone === "region")
+ return data?.regions ?? []
+ else if (typeZone === "departement")
+ return data?.departements ?? []
+ else if (typeZone === "circonscription")
+ return data?.circonscriptions ?? []
+ else if (typeZone === "commune")
+ return data?.communes ?? []
+ else if (typeZone === "bureau_vote")
+ return data?.bureaux_vote ?? []
+ else
+ return []
+ }, [typeResultats, resultats, typeZone])
useEffect(() => {
if (!zones)
@@ -262,25 +231,24 @@ function ContenuCarte({typeResultats, resultats, listes, blocs, nuances, grouper
})
}, [typeZone, zones, resultats])
- if (typeZone === "regions") {
- return <>
- {resultatsZones.filter(resultatsZone => resultatsZone.geometry['type']).map(resultatsZone =>
- )}
- >
- }
- else if (typeZone === "departements") {
- return <>
- {resultatsZones.filter(resultatsZone => resultatsZone.geometry['type']).map(resultatsZone =>
- )}
- >
+ function getZoneIdentifier(typeZone, zone) {
+ if (typeZone === "region" || typeZone === "departement" || typeZone === "commune")
+ return zone.code_insee
+ else if (typeZone === "circonscription" || typeZone === "bureau_vote")
+ return zone.id
+ else
+ return ""
}
+
+ return <>
+ {resultatsZones.filter(resultatsZone => resultatsZone.geometry['type']).map(resultatsZone =>
+ )}
+ >
}
-function Carte({typeResultats, resultats, listes, blocs, nuances, grouperParBloc = false}) {
+function Carte({typeResultats, resultats, typeZone, listes, blocs, nuances, grouperParBloc = false}) {
const center = [46.603354, 1.888334]
return <>
@@ -289,13 +257,50 @@ function Carte({typeResultats, resultats, listes, blocs, nuances, grouperParBloc
attribution='© Les contributeur⋅rices OpenStreetMap'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
-
+
>
}
-export default function Election2024({typeResultats = "france"}) {
- const {zoneId} = useParams()
+function SelectionAffichage({typeResultats, typeZone, setTypeZone}) {
+ const items = useMemo(() => {
+ const items = []
+ if (typeResultats === "france") {
+ setTypeZone("region")
+ items.push()
+ }
+
+ if (typeResultats === "france" || typeResultats === "region") {
+ if (typeResultats !== "france")
+ setTypeZone("departement")
+ items.push()
+ }
+
+ if (typeResultats === "france" || typeResultats === "region" || typeResultats === "departement") {
+ if (typeResultats !== "france" && typeResultats !== "region")
+ setTypeZone("circonscription")
+ items.push()
+ }
+
+ if (typeResultats === "departement") {
+ items.push()
+ }
+
+ if (typeResultats === "circonscription" || typeResultats === "commune") {
+ setTypeZone("bureau_vote")
+ items.push()
+ }
+
+ return items
+ }, [typeResultats, setTypeZone])
+
+ return
+}
+
+export default function Election2024() {
+ const {typeResultats, zoneId} = useParams()
const [zoneName, setZoneName] = useState("France")
const [grouperParBloc, setGrouperParBloc] = useState(false)
@@ -312,6 +317,7 @@ export default function Election2024({typeResultats = "france"}) {
const [categoriesVoix, setCategoriesVoix] = useState([])
const [dataVoix, setDataVoix] = useState([])
const [dataSieges, setDataSieges] = useState([])
+ const [typeZone, setTypeZone] = useState("region")
useEffect(() => {
fetch("/data/resultats/europeennes2024/blocs.json").then(response => response.json())
@@ -336,19 +342,22 @@ export default function Election2024({typeResultats = "france"}) {
setZoneName("")
else if (typeResultats === "france")
setZoneName("France")
- else if (typeResultats === "regions")
+ else if (typeResultats === "region")
setZoneName(`Région ${resultats.region.nom}`)
- else if (typeResultats === "departements")
+ else if (typeResultats === "departement")
setZoneName(`Département ${resultats.departement.nom}`)
- else if (typeResultats === "circonscriptions")
- setZoneName(`Circonscription ${resultats.circonscription.nom}`)
- else if (typeResultats === "communes")
+ else if (typeResultats === "circonscription")
+ setZoneName(`Circonscription ${resultats.circonscription.id}`)
+ else if (typeResultats === "commune")
setZoneName(`Commune ${resultats.commune.nom}`)
- else if (typeResultats === "bureaux_vote")
+ else if (typeResultats === "bureau_vote")
setZoneName(resultats.bureau_vote.libelle)
}, [typeResultats, resultats])
useEffect(() => {
+ if (!resultats['voix_listes'])
+ return
+
const parBloc = {}
const parNuance = {}
for (let bloc of blocs) {
@@ -387,6 +396,9 @@ export default function Election2024({typeResultats = "france"}) {
}, [voixParBloc, voixParNuance, grouperParBloc])
useEffect(() => {
+ if (!resultats['voix_listes'])
+ return
+
const MAX_SIEGES = 81
const sieges = {}
const listesElues = []
@@ -537,6 +549,10 @@ export default function Election2024({typeResultats = "france"}) {
/>
-
+
+ }
+ label="Type d'affichage pour la carte" />
+
+
>
}
diff --git a/nupes/models/geographie.py b/nupes/models/geographie.py
index 9e2b743..a372c38 100644
--- a/nupes/models/geographie.py
+++ b/nupes/models/geographie.py
@@ -27,6 +27,7 @@ class Departement(Base):
geometry: Mapped[dict] = mapped_column(JSON())
region: Mapped[Region] = relationship(Region, back_populates="departements")
+ circonscriptions: Mapped[List["Circonscription"]] = relationship("Circonscription", back_populates="departement")
communes: Mapped[List["Commune"]] = relationship("Commune", back_populates="departement")
resultats2024 = relationship("ResultatsDepartement", back_populates="departement")
@@ -54,7 +55,7 @@ class Circonscription(Base):
numero: Mapped[int] = mapped_column(Integer())
geometry: Mapped[dict] = mapped_column(JSON())
- departement: Mapped[Departement] = relationship(Departement)
+ departement: Mapped[Departement] = relationship(Departement, back_populates="circonscriptions")
bureaux_vote: Mapped[List["BureauVote"]] = relationship("BureauVote", back_populates="circonscription")
resultats2024 = relationship("ResultatsCirconscription", back_populates="circonscription")
diff --git a/nupes/scripts/export_resultats_2024.py b/nupes/scripts/export_resultats_2024.py
index 54fe926..8f91393 100644
--- a/nupes/scripts/export_resultats_2024.py
+++ b/nupes/scripts/export_resultats_2024.py
@@ -140,7 +140,7 @@ def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
for voix_liste in resultats_region.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix
- file = DATA_DIR / "resultats" / "europeennes2024" / "regions" / f"{region.code_insee}.json"
+ file = DATA_DIR / "resultats" / "europeennes2024" / "region" / f"{region.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
@@ -149,7 +149,7 @@ def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
session.commit()
- regions_file = DATA_DIR / "resultats" / "europeennes2024" / "regions" / "regions.json"
+ regions_file = DATA_DIR / "resultats" / "europeennes2024" / "region" / "regions.json"
if not regions_file.parent.is_dir():
regions_file.parent.mkdir(parents=True)
@@ -166,6 +166,7 @@ def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> No
for departement in iterator:
departement_json = {'code_insee': departement.code_insee, 'nom': departement.libelle,
'region': departement.region_code,
+ 'circonscriptions': [circo.id for circo in departement.circonscriptions],
'communes': [commune.code_insee for commune in departement.communes]}
departements_json.append(departement_json)
@@ -194,7 +195,7 @@ def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> No
for voix_liste in resultats_departement.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix
- file = DATA_DIR / "resultats" / "europeennes2024" / "departements" / f"{departement.code_insee}.json"
+ file = DATA_DIR / "resultats" / "europeennes2024" / "departement" / f"{departement.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
@@ -203,7 +204,7 @@ def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> No
session.commit()
- departements_file = DATA_DIR / "resultats" / "europeennes2024" / "departements" / "departements.json"
+ departements_file = DATA_DIR / "resultats" / "europeennes2024" / "departement" / "departements.json"
if not departements_file.parent.is_dir():
departements_file.parent.mkdir(parents=True)
@@ -248,7 +249,7 @@ def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -
for voix_liste in resultats_circonscription.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix
- file = DATA_DIR / "resultats" / "europeennes2024" / "circonscriptions" / f"{circonscription.id}.json"
+ file = DATA_DIR / "resultats" / "europeennes2024" / "circonscription" / f"{circonscription.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
@@ -257,7 +258,7 @@ def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -
session.commit()
- circonscriptions_file = DATA_DIR / "resultats" / "europeennes2024" / "circonscriptions" / "circonscriptions.json"
+ circonscriptions_file = DATA_DIR / "resultats" / "europeennes2024" / "circonscription" / "circonscriptions.json"
if not circonscriptions_file.parent.is_dir():
circonscriptions_file.parent.mkdir(parents=True)
@@ -302,7 +303,7 @@ def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
for voix_liste in resultats_commune.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix
- file = DATA_DIR / "resultats" / "europeennes2024" / "communes" / f"{commune.code_insee}.json"
+ file = DATA_DIR / "resultats" / "europeennes2024" / "commune" / f"{commune.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
@@ -311,7 +312,7 @@ def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
session.commit()
- communes_file = DATA_DIR / "resultats" / "europeennes2024" / "communes" / "communes.json"
+ communes_file = DATA_DIR / "resultats" / "europeennes2024" / "commune" / "communes.json"
if not communes_file.parent.is_dir():
communes_file.parent.mkdir(parents=True)
@@ -357,7 +358,7 @@ def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> No
for voix_liste in resultats_bureau_vote.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix
- file = DATA_DIR / "resultats" / "europeennes2024" / "bureaux_vote" / f"{bureau_vote.id}.json"
+ file = DATA_DIR / "resultats" / "europeennes2024" / "bureau_vote" / f"{bureau_vote.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
@@ -366,7 +367,7 @@ def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> No
session.commit()
- bureaux_vote_file = DATA_DIR / "resultats" / "europeennes2024" / "bureaux_vote" / "bureaux_vote.json"
+ bureaux_vote_file = DATA_DIR / "resultats" / "europeennes2024" / "bureau_vote" / "bureaux_vote.json"
if not bureaux_vote_file.parent.is_dir():
bureaux_vote_file.parent.mkdir(parents=True)