Close Menu
Le Méridien
  • Actualités
  • Monde
  • Politique
  • Police
  • Société
  • Education
  • Entreprise
  • Justice
  • Culture
  • Sciences et Tech
  • Plus
    • Environnement
    • Communiqué de Presse
    • Les Tendances
What's Hot
« La baisse du nombre d’élèves ne doit pas se traduire par le démantèlement progressif des écoles rurales »

« La baisse du nombre d’élèves ne doit pas se traduire par le démantèlement progressif des écoles rurales »

mars 4, 2026
A Dubaï, la nouvelle réalité des influenceurs français sous les frappes iraniennes

A Dubaï, la nouvelle réalité des influenceurs français sous les frappes iraniennes

mars 4, 2026
Confrontés aux attaques de drones, les voisins de l’Iran découvrent leur vulnérabilité

Confrontés aux attaques de drones, les voisins de l’Iran découvrent leur vulnérabilité

mars 4, 2026
Facebook X (Twitter) Instagram
Facebook X (Twitter) Instagram YouTube
Se Connecter
mars 4, 2026
Le Méridien
Histoires Web Bulletin
  • Actualités
  • Monde
  • Politique
  • Police
  • Société
  • Education
  • Entreprise
  • Justice
  • Culture
  • Sciences et Tech
  • Plus
    • Environnement
    • Communiqué de Presse
    • Les Tendances
Le Méridien
Home»Environnement
Environnement

La population de votre commune est-elle en déclin naturel ? Vérifiez avec notre outil de visualisation

Espace PresseBy Espace Pressejanvier 13, 2026
Facebook Twitter WhatsApp Copy Link Pinterest LinkedIn Tumblr Email Telegram
La population de votre commune est-elle en déclin naturel ? Vérifiez avec notre outil de visualisation

6 000 décès de plus que de naissances en 2025 en France. Le solde naturel devient négatif pour la première fois depuis la seconde guerre mondiale et, surtout, pour la première fois dans un contexte de paix depuis le début du XXe siècle. C’est le constat du dernier bilan démographique français pour l’année 2025 publié, mardi 13 janvier, par l’Institut national de la statistique et des études économiques.

S’il a fallu attendre 2025 pour franchir ce point de bascule symbolique au niveau national, il l’avait déjà été il y a plusieurs années dans de nombreuses parties de la France. Qu’en est-il dans votre commune ou votre département ?

`

}

fillHtml();

const deptDict = {
« 01 »: { « nom_d »: « Ain », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 02 »: { « nom_d »: « Aisne », « code_r »: « 032 », « nom_r »: « Hauts-de-France » },
« 03 »: { « nom_d »: « Allier », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 04 »: { « nom_d »: « Alpes-de-Haute-Provence », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 05 »: { « nom_d »: « Hautes-Alpes », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 06 »: { « nom_d »: « Alpes-Maritimes », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 07 »: { « nom_d »: « Ardèche », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 08 »: { « nom_d »: « Ardennes », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 09 »: { « nom_d »: « Ariège », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 10 »: { « nom_d »: « Aube », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 11 »: { « nom_d »: « Aude », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 12 »: { « nom_d »: « Aveyron », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 13 »: { « nom_d »: « Bouches-du-Rhône », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 14 »: { « nom_d »: « Calvados », « code_r »: « 028 », « nom_r »: « Normandie » },
« 15 »: { « nom_d »: « Cantal », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 16 »: { « nom_d »: « Charente », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 17 »: { « nom_d »: « Charente-Maritime », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 18 »: { « nom_d »: « Cher », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 19 »: { « nom_d »: « Corrèze », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 21 »: { « nom_d »: « Côte-d’Or », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 22 »: { « nom_d »: « Côtes-d’Armor », « code_r »: « 053 », « nom_r »: « Bretagne » },
« 23 »: { « nom_d »: « Creuse », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 24 »: { « nom_d »: « Dordogne », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 25 »: { « nom_d »: « Doubs », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 26 »: { « nom_d »: « Drôme », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 27 »: { « nom_d »: « Eure », « code_r »: « 028 », « nom_r »: « Normandie » },
« 28 »: { « nom_d »: « Eure-et-Loir », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 29 »: { « nom_d »: « Finistère », « code_r »: « 053 », « nom_r »: « Bretagne » },
« 30 »: { « nom_d »: « Gard », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 31 »: { « nom_d »: « Haute-Garonne », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 32 »: { « nom_d »: « Gers », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 33 »: { « nom_d »: « Gironde », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 34 »: { « nom_d »: « Hérault », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 35 »: { « nom_d »: « Ile-et-Vilaine », « code_r »: « 053 », « nom_r »: « Bretagne » },
« 36 »: { « nom_d »: « Indre », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 37 »: { « nom_d »: « Indre-et-Loire », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 38 »: { « nom_d »: « Isère », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 39 »: { « nom_d »: « Jura », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 40 »: { « nom_d »: « Landes », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 41 »: { « nom_d »: « Loir-et-Cher », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 42 »: { « nom_d »: « Loire », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 43 »: { « nom_d »: « Haute-Loire », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 44 »: { « nom_d »: « Loire-Atlantique », « code_r »: « 052 », « nom_r »: « Pays-de-la-Loire » },
« 45 »: { « nom_d »: « Loiret », « code_r »: « 024 », « nom_r »: « Centre-Val de Loire » },
« 46 »: { « nom_d »: « Lot », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 47 »: { « nom_d »: « Lot-et-Garonne », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 48 »: { « nom_d »: « Lozère », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 49 »: { « nom_d »: « Maine-et-Loire », « code_r »: « 052 », « nom_r »: « Pays-de-la-Loire » },
« 50 »: { « nom_d »: « Manche », « code_r »: « 028 », « nom_r »: « Normandie » },
« 51 »: { « nom_d »: « Marne », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 52 »: { « nom_d »: « Haute-Marne », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 53 »: { « nom_d »: « Mayenne », « code_r »: « 052 », « nom_r »: « Pays-de-la-Loire » },
« 54 »: { « nom_d »: « Meurthe-et-Moselle », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 55 »: { « nom_d »: « Meuse », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 56 »: { « nom_d »: « Morbihan », « code_r »: « 053 », « nom_r »: « Bretagne » },
« 57 »: { « nom_d »: « Moselle », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 58 »: { « nom_d »: « Nièvre », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 59 »: { « nom_d »: « Nord », « code_r »: « 032 », « nom_r »: « Hauts-de-France » },
« 60 »: { « nom_d »: « Oise », « code_r »: « 032 », « nom_r »: « Hauts-de-France » },
« 61 »: { « nom_d »: « Orne », « code_r »: « 028 », « nom_r »: « Normandie » },
« 62 »: { « nom_d »: « Pas-de-Calais », « code_r »: « 032 », « nom_r »: « Hauts-de-France » },
« 63 »: { « nom_d »: « Puy-de-Dôme », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 64 »: { « nom_d »: « Pyrénées-Atlantiques », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 65 »: { « nom_d »: « Hautes-Pyrénées », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 66 »: { « nom_d »: « Pyrénées-Orientales », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 67 »: { « nom_d »: « Bas-Rhin », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 68 »: { « nom_d »: « Haut-Rhin », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 69 »: { « nom_d »: « Rhône », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 70 »: { « nom_d »: « Haute-Saône », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 71 »: { « nom_d »: « Saône-et-Loire », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 72 »: { « nom_d »: « Sarthe », « code_r »: « 052 », « nom_r »: « Pays-de-la-Loire » },
« 73 »: { « nom_d »: « Savoie », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 74 »: { « nom_d »: « Haute-Savoie », « code_r »: « 084 », « nom_r »: « Auvergne-Rhône-Alpes » },
« 75 »: { « nom_d »: « Paris », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 76 »: { « nom_d »: « Seine-Maritime », « code_r »: « 028 », « nom_r »: « Normandie » },
« 77 »: { « nom_d »: « Seine-et-Marne », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 78 »: { « nom_d »: « Yvelines », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 79 »: { « nom_d »: « Deux-Sèvres », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 80 »: { « nom_d »: « Somme », « code_r »: « 032 », « nom_r »: « Hauts-de-France » },
« 81 »: { « nom_d »: « Tarn », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 82 »: { « nom_d »: « Tarn-et-Garonne », « code_r »: « 076 », « nom_r »: « Occitanie » },
« 83 »: { « nom_d »: « Var », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 84 »: { « nom_d »: « Vaucluse », « code_r »: « 093 », « nom_r »: « Provence-Alpes-Côte d’Azur » },
« 85 »: { « nom_d »: « Vendée », « code_r »: « 052 », « nom_r »: « Pays-de-la-Loire » },
« 86 »: { « nom_d »: « Vienne », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 87 »: { « nom_d »: « Haute-Vienne », « code_r »: « 075 », « nom_r »: « Nouvelle-Aquitaine » },
« 88 »: { « nom_d »: « Vosges », « code_r »: « 044 », « nom_r »: « Grand-Est » },
« 89 »: { « nom_d »: « Yonne », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 90 »: { « nom_d »: « Territoire de Belfort », « code_r »: « 027 », « nom_r »: « Bourgogne-Franche-Comté » },
« 91 »: { « nom_d »: « Essonne », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 92 »: { « nom_d »: « Hauts-de-Seine », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 93 »: { « nom_d »: « Seine-Saint-Denis », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 94 »: { « nom_d »: « Val-de-Marne », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 95 »: { « nom_d »: « Val-d’Oise », « code_r »: « 011 », « nom_r »: « Ile-de-France » },
« 2A »: { « nom_d »: « Corse-du-Sud », « code_r »: « 094 », « nom_r »: « Corse » },
« 2B »: { « nom_d »: « Haute-Corse », « code_r »: « 094 », « nom_r »: « Corse » },
« 971 »: { « nom_d »: « Guadeloupe », « code_r »: «  », « nom_r »: «  » },
« 972 »: { « nom_d »: « Martinique », « code_r »: «  », « nom_r »: «  » },
« 973 »: { « nom_d »: « Guyane », « code_r »: «  », « nom_r »: «  » },
« 974 »: { « nom_d »: « La Réunion », « code_r »: «  », « nom_r »: «  » },
« 975 »: { « nom_d »: « Saint-Pierre-et-Miquelon », « code_r »: «  », « nom_r »: «  » },
« 976 »: { « nom_d »: « Mayotte », « code_r »: «  », « nom_r »: «  » },
« 977 »: { « nom_d »: « Saint-Martin/Saint-Barthélemy », « code_r »: «  », « nom_r »: «  » },
« 978 »: { « nom_d »: « Saint-Martin/Saint-Barthélemy », « code_r »: «  », « nom_r »: «  » },
« 986 »: { « nom_d »: « Wallis et Futuna », « code_r »: «  », « nom_r »: «  » },
« 987 »: { « nom_d »: « Polynésie française », « code_r »: «  », « nom_r »: «  » },
« 988 »: { « nom_d »: « Nouvelle-Calédonie », « code_r »: «  », « nom_r »: «  » },
« 99 »: { « nom_d »: « Français de l’étranger », « code_r »: «  », « nom_r »: «  » }
};

const days = [‘dimanche’, ‘lundi’, ‘mardi’, ‘mercredi’, ‘jeudi’, ‘vendredi’, ‘samedi’];
const months = [‘janvier’, ‘février’, ‘mars’, ‘avril’, ‘mai’, ‘juin’, ‘juillet’, ‘août’, ‘septembre’, ‘octobre’, ‘novembre’, ‘décembre’];

const formatNb = (x) => {
let loc = lang == ‘fr’ ? ‘fr-FR’ : ‘en-GB’;
return x.toLocaleString(loc);
}

// Everything we need for canvas tooltip

let booleanPointInPolygon = turf.booleanPointInPolygon.default;

const delaunayNextring = (delaunay, currentZone, kernel) => {
if (!kernel) kernel = [];
let nextring = currentZone.flatMap((d, i, self) => […delaunay.neighbors(d)].filter(e => !self.includes(e) && !kernel.includes(e)));
return […new Set(nextring)];
};

// Define app and device situation

let inApp = window.location.href.match(/apps.([a-z]+-)?lemonde.fr/);

let isMobile = window.innerWidth <= 820 ? true : false;

if (!isMobile && window.innerHeight < 600) {
document.querySelector(« .eu_map_restrainer »).style.width= »78% »;
}

//d3.json(« https://assets-decodeurs.lemonde.fr/decodeurs/assets/20240325_europeennes/communes_2024.json »).then((comTopo) => {
d3.json(« https://assets-decodeurs.lemonde.fr/decodeurs/assets/Demographie2025/communes_2024_FR.json »).then((comTopo)=>{

// 0. Stop spinner

document.querySelector(« .eu_map_loader »).style.display = « none »;
document.querySelector(« .eu_map_restrainer »).style.display = « block »;
document.querySelector(« .eu_map_instrtxt »).innerHTML = isMobile ? `${text.zoom_m}` : `${text.zoom}`;

// 1. Prepare geo data

const communes = topojson.feature(comTopo, comTopo.objects.a_com);
const dept = topojson.feature(comTopo, comTopo.objects.a_dept);
const features = new Map(communes.features.map(d => [d.properties.c, d]));
const bordersFrance = topojson.merge(comTopo, comTopo.objects.a_dept.geometries);
const bordersDept = topojson.mesh(comTopo, comTopo.objects.a_dept, (a, b) => a !== b);
const separators = topojson.feature(comTopo, comTopo.objects.l_separateur);

// 2. Define dimensions

let dimensions = {
width: document.querySelector(« .eu_map »).offsetWidth,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
};

dimensions.height = dimensions.width * 1.1;

// 3. Define projection

let projDef = (w, h, layer) => {
return d3.geoIdentity().reflectY(true).fitExtent([[dimensions.margin.left, dimensions.margin.top], [w – dimensions.margin.right, h – dimensions.margin.bottom]], layer);
};
let proj = projDef(dimensions.width, dimensions.height, bordersFrance);
const pathGenerator = d3.geoPath(proj);

// 4. Format data

let tooltip = d3.select(« .eu_map_tooltip »);
let centroids = communes.features.map(f => d3.geoPath(proj).centroid(f));
let delaunay = d3.Delaunay.from(centroids);
let comData;
let currentDept;
let zoomedIn = false;

// les données par commune
const resMap = new Map(Object.entries( dataDemoOk).map(d => [d[0], d]));

// Par ici on définit les couleurs

let categ = ‘solde2024’;

extent = [-2800, 550]
const colorScaleSoldeNew = d3.scaleDivergingSymlog(t => d3.interpolateRdBu(1-t)).domain([extent[0], 0, extent[1]])

let dataC = communes.features.map(d => {

// dataDemoOk structure :
// com: commune INSEE number
//POPTOT_2022 : population totale
//NAI_2024 : nombre de naissances
//RIP_2024 : nombre de décès

let com = d.properties.c == ‘fe’ ? ’99’ : d.properties.c;
let a;
let ft = d;
let res;

let scsolde2024;
let solde2024 = « #f6f6f6 »;

//let s;

try {
res = resMap.get(com);
}
catch (error) {
console.log(« e »);
}

if (com == ’99’) console.log(res)

// Handle communes mortes de la Meuse
if (typeof (res) == ‘undefined’) {
//console.log(« undef », com)

if (com === ‘55039’ || com === ‘55239’ || com === ‘55189’ || com === ‘55307’ || com === ‘55139’ || com === ‘55050’)
n = 104;
else {
//console.log(« undefined! », com, res)
n = 103;
}
w = null;
}
else if (res[1] === null) {
console.log(« null », res[1])
n = 105;
w = null;
}
// TODO Other conditions
else {
naissances2024 = res[1][‘NAI_2024’];
deces2024 = res[1][‘RIP_2024’];
scsolde2024 = res[1][‘RIP_2024’] – res[1][‘NAI_2024’];
csolde2024 = scsolde2024 == ‘d’ || scsolde2024 == ‘u’ || scsolde2024 == ‘n’ ? ‘#BDC1C8’ : colorScaleSoldeNew(scsolde2024);
poptot2022 = res[1][‘POPTOT_2022’];
}

return {
com,
ft: ft,
naissances2024,
deces2024,
scsolde2024,
csolde2024,
poptot2022
}
}).sort((a, b) => a[‘sc’ + categ] < b[‘sc’ + categ] ? -1 : 1);

// Draw legend

Legend(« .eu_legend_wrapper », colorScaleSoldeNew, {
width: « 300 »,
tickValues: [0]
});

txtNeutre = d3.select(« div.eu_map_restrainer > div.eu_map_legend_nb > div > svg > g > g:nth-child(1) > text »).text(« Plus de naissances   <––   0   ––>       Plus de décès     « );

// 5. Init canvas

let comCanvas = document.querySelector(« canvas[data-layer= »com »] »);
let dpr = window.devicePixelRatio;

comCanvas.width = dimensions.width * dpr;
comCanvas.height = dimensions.height * dpr;

let comContext = comCanvas.getContext(‘2d’, { willReadFrequently: true });
comContext.scale(dpr, dpr);

// 6. Init svg (frame and borders)

const svg = d3.select(« .eu_map_wrapper »)
.append(« svg »)
.attr(« preserveAspectRatio », « xMinYMin meet »)
.attr(« viewBox », `0 0 ${dimensions.width} ${dimensions.height}`)
.attr(« class », « eu_map_svgcontent »)
.attr(« aria-label », « Carte communes européennes 2024 »);

const bg = svg.append(« g »)
.append(« rect »)
.attr(« width », dimensions.width)
.attr(« height », dimensions.height)
.attr(« class », « eu_map_svgbg »)
.attr(« fill », « transparent »)
.on(« click », resetMe);

const g = svg.append(« g »);

// 7. Draw zones

const borderColor = « var(–eu-dept-border-color) »;
const comStroke = dimensions.width * 0.0025;
const bdStroke = dimensions.width * 0.0012;
const bdStrokeZoomed = dimensions.width * 0.005;

const zones = g.append(« g »).selectAll(« .eu_map_zone »)
.data(dept.features)
.enter().append(« path »)
.attr(« class », « eu_map_zone »)
.attr(« name », d => d.properties.d)
.attr(« stroke-linejoin », « round »)
.attr(« d », pathGenerator)
.attr(« fill », « transparent »);

// 8. Draw borders

const intBorders = g.append(« path »)
.attr(« class », « eu_map_border »)
.datum(bordersDept)
.attr(« fill », « none »)
.attr(« stroke », borderColor)
.attr(« stroke-width », bdStroke)
.attr(« stroke-linejoin », « round »)
.attr(« d », pathGenerator)
.attr(« pointer-events », « none »);

const extBorders = g.append(« path »)
.attr(« class », « eu_map_border »)
.datum(bordersFrance)
.attr(« fill », « none »)
.attr(« stroke », borderColor)
.attr(« stroke-width », bdStroke)
.attr(« stroke-linejoin », « round »)
.attr(« d », pathGenerator)
.attr(« pointer-events », « none »);

let comBorders;

// Draw separators

const sepLines = g.append(« path »)
.datum(separators)
.attr(« class », « l_map_lines »)
.attr(« stroke-linejoin », « round »)
.attr(« d », pathGenerator)
.attr(« stroke-linejoin », « round »)
.attr(« stroke », « var(–eu-map-sep) »)
.attr(« stroke-width », 1);

// Add overseas legend

// const textOverseas = g.append(« text »)
// .attr(« y », isMobile ? dimensions.height * 0.9 : dimensions.height * 0.895)
// .attr(« x », dimensions.width * 0.15)
// .attr(« fill », « var(–eu-map-sep-text) »)
// .attr(« font-size », isMobile ? « 11px » : « 12px »)
// .attr(« pointer-events », « none »)
// .text(`${text.ov}`);

// 9. Draw communes

const drawMap = (x = 0, y = 0, k = 1) => {

comContext.clearRect(0, 0, comCanvas.width, comCanvas.height);

if (k > 1) {

comContext.save();
comContext.translate(x, y);
comContext.scale(k, k);
comContext.rect(0, 0, dimensions.width, dimensions.height);
comContext.clip();
}

let lastColor;
let geoPath = d3.geoPath(proj, comContext);
dataC.forEach(d => {
comContext.beginPath();

if (d[‘c’ + categ] != lastColor) {
comContext.fillStyle = d[‘c’ + categ];
}
geoPath(d.ft);
lastColor = d[‘c’ + categ];
comContext.fill();

});
if (k > 1) {
comContext.restore();
}

}

//let topPos = window.scrollY + document.querySelector(« .lmui-chart__title »).getBoundingClientRect().top – 300;
let bottomPos = window.scrollY + document.querySelector(« .eu_map_wrapper »).getBoundingClientRect().bottom + 200;

const handleMouseEvents = () => {
if (isMobile) {
d3.select(« .eu_map_tooltipcross »).on(« click », onMouseLeave);
svg.selectAll(« .eu_map_zone »)
.on(« mouseleave », onMouseLeave)
.on(« click touch », clicked);
d3.select(« .eu_map_wrapper »).on(« touchleave mouseleave », onMouseLeave);
d3.select(« .eu_peripheral_top »).on(« click », onMouseLeave);
d3.select(« .eu_map_accessibility »).on(« click », onMouseLeave);
/*if (!inApp) {
window.onscroll = () => {
let currentPos = window.pageYOffset;
if ((currentPos > bottomPos && currentPos > topPos) || (currentPos < topPos && currentPos < bottomPos)) {
tooltip.transition().duration(50)
.style(« transform », « translate(0, 150px) »)
.transition().delay(50)
.style(« display », « none »);
}
}
}*/
}
else {
d3.select(« .eu_map_wrapper »).on(« mousemove », moveDesktop).on(« mouseleave », onMouseLeave);
d3.selectAll(« .eu_map_zone »).on(« mouseleave », onMouseLeave).on(« click », clicked);
}
}

// Manage zoom on click

const zoom = d3.zoom().on(« zoom », zoomed);

async function clicked(event, d) {

document.querySelector(« .eu_map_instrtxt »).innerHTML = isMobile ? `${text.cta_com_m}` : `${text.cta_com}`;

if (isMobile) {
tooltip.transition().duration(200)
.style(« transform », « translate(0, 100px) »)
.transition().delay(200)
.style(« display », « none »);
}
else
tooltip.style(« display », « none »);

const [[x0, y0], [x1, y1]] = pathGenerator.bounds(d);

event.stopPropagation();

let dNb = d.properties.d == ‘978’ ? ‘977’ : d.properties.d;

if (dNb == ‘fe’) dNb = ’99’;
if (zoomedIn == true && currentDept == dNb && dNb != ‘977’) return;

document.querySelector(« .eu_map_deptname »).innerHTML = (lang == ‘en’ && dNb == ’99’) ? `${text.tt_fe}` : deptDict[dNb].nom_d;

d3.select(« .eu_map_reset »)
.transition().duration(50)
.style(« opacity », 1)
.transition().duration(100)
.style(« display », « block »);

if (comBorders) comBorders.transition().duration(50).attr(« stroke », null).remove();

// Adapt zoom max to device and dept shape
let zoomMax = 100;

if (dNb == 75 || dNb == 92 || dNb == 93 || dNb == 94 || dNb == 90)
zoomMax = 50;
else if (dNb == ’02’)
zoomMax = isMobile ? 9.5 : 100;
else if (dNb == 25)
zoomMax = isMobile ? 10 : 11;
else if (dNb == 31)
zoomMax = isMobile ? 8.5 : 11;
else if (dNb == 67)
zoomMax = 11;
else if (dNb == ‘2B’)
zoomMax = isMobile ? 8.5 : 100;

svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity
.translate(dimensions.width / 2, dimensions.height / 2)
.scale(Math.min(zoomMax, 1 / Math.max((x1 – x0) / dimensions.width, (y1 – y0) / dimensions.height)))
.translate(-(x0 + x1) / 2, -(y0 + y1) / 2),
);

try {
comData = await d3.json(`https://assets-decodeurs.lemonde.fr/decodeurs/elections_snippets/europeennes/exports2024TEST/export_communes${dNb}.json`);
}
catch (error) {
comData = undefined;
}

currentDept = dNb;

const extract = {
type: « FeatureCollection »,
features: communes.features.filter(k => k.properties.d == d.properties.d)
};

comBorders = g.append(« g »).selectAll(« .eu_map_com »)
.data(extract.features)
.enter().append(« path »)
.attr(« class », « eu_map_com »)
.attr(« fill », « none »)
.attr(« name », d => d.properties.d)
.attr(« d », pathGenerator);

if (isMobile) {
comBorders.on(« click mouseover », mouseEnterCom).on(« mouseout », onMouseLeave);
}

else {
d3.select(« .eu_map_wrapper »).on(« touchmove mousemove », null);
comBorders.on(« mouseover », mouseEnterCom).on(« mouseout », onMouseLeave);
}

zones.attr(« fill », « var(–eu-map-overlay) »);

d3.select(this).attr(« fill », « none »);

zoomedIn = true;
}

// Zoom and redraw

let k = 1;
let x = 0;
let y = 0;

function zoomed(event) {
let { transform } = event;
g.attr(« transform », transform);

// Scale strokes
if (zoomedIn === true) {
intBorders.transition().duration(50).ease(d3.easeCubicInOut).attr(« stroke-width », bdStrokeZoomed / transform.k);
extBorders.attr(« stroke-width », bdStrokeZoomed / transform.k);
}
else {
intBorders.attr(« stroke-width », bdStroke / transform.k);
extBorders.attr(« stroke-width », bdStroke / transform.k);
}

if (comBorders)
comBorders.attr(« stroke-width », comStroke / transform.k).attr(« stroke », borderColor).attr(« stroke-opacity », 0.5).attr(« stroke-linejoin », « round »);

drawMap(transform.x, transform.y, transform.k);

x = transform.x;
y = transform.y;
k = transform.k;

}

// Reset map on click

function resetMe() {

if (zoomedIn == false) return;
document.querySelector(« .eu_map_instrtxt »).innerHTML = isMobile ? `${text.zoom_m}` : `${text.zoom}`;

// Reset svg additions
if (comBorders) comBorders.transition().duration(50).attr(« stroke », null).remove();
zones.attr(« fill », « transparent »);

// Hide arrow
d3.selectAll(« .eu_map_reset »).transition().duration(100).style(« opacity », 0);

// Dezoom
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity,
d3.zoomTransform(svg.node()).invert([dimensions.width / 2, dimensions.height / 2])
);

// Reset mouse events
handleMouseEvents();

// Hide tooltip
if (isMobile) {
tooltip.transition().duration(200).style(« transform », « translate(0, 100px) »).transition().duration(200).style(« display », « none »);
}
else {
tooltip.style(« display », « none »);
}

zoomedIn = false;
}

// Manage tooltips

function onMouseLeave(event, d) {
if (isMobile) {
tooltip.transition().duration(200)
.style(« transform », « translate(0, 100px) »)
.transition().delay(200)
.style(« display », « none »);
}
else {
tooltip.style(« display », « none »);
}
d3.select(this).attr(« stroke-width », comStroke / k);
}

const percentage = (value, total) => {
return (Math.round(((value / total) * 100) * 10) / 10).toString().replace(‘.’, ‘,’);
};

// Zoomed in tooltip
function mouseEnterCom(event, datum) {

d3.select(this).attr(« stroke-width », comStroke * 2 / k);

const toFind = datum.properties.c == ‘fe’ ? ’99’ : datum.properties.c;
const link = toFind === ‘fe’ ? « https://www.lemonde.fr/resultats-europeennes-2024/outre-mer/francais-de-l-etranger/ » : `https://www.lemonde.fr/resultats-europeennes-2024/commune-${toFind}/`;

/*let locData;

locData = comData === undefined ? undefined : comData[toFind];*/

let locData = dataC.find(d => d.com == toFind);
let score = locData[‘sc’ + categ];
console.log(locData, score);
let title = `

${currentDept == ’99’ ? `${text.tt_fe}` : `${datum.properties.l}`}

`;

let content= » »;
if (toFind === ‘55039’ || toFind === ‘55239’ || toFind === ‘55189’ || toFind === ‘55307’ || toFind === ‘55139’ || toFind === ‘55050’) {
content = `${text.tt_meuse}`;
}
else if (locData == undefined || score == undefined) {
content = `${text.tt_nores}`;
if (!isMobile) {
content += `

${text.tt_nores}

`
}
}
else if (score == ‘n’) {
content = `

`;
}

else {
if (categ == ‘solde2024’) {
console.log(locData);
let plural = Math.abs(score > 1)|| Math.abs(score < -1) ? ‘s’ :  »;

let rise = score >= 0
? score == 0
? ` Autant de naissances que de décès`
: `${new String(score).replace(‘.’, ‘,’)} décès de plus que de naissances`
: `${new String(score).replace(‘-‘,  »).replace(‘.’, ‘,’)} naissance${plural} de plus que de décès`;
content = `

${rise}.
${locData[‘naissances2024’]} naissances et ${locData[‘deces2024’]} décès en 2024, pour ${locData[‘poptot2022’]} habitants (2022)

`;
}
}

// Fill and show

tooltip.select(‘.eu_map_tooltiptitle’)
.attr(‘aria-label’, `Titre infobulle`)
.html(title);

tooltip.select(‘.eu_map_tooltipvalue’)
.attr(‘aria-label’, ‘Contenu infobulle’)
.html(content);

if (!isMobile) {
const [x, y] = d3.pointer(event, svg.node());
tooltip.style(« transform », `translate(`
+ `calc(-50% + ${x >= Math.round(dimensions.width * 0.5) ? x – 70 : x + 70}px),`
+ `calc(-110% + ${y}px))`);
}
if (isMobile) {
tooltip.style(« display », « block »).transition().duration(200).style(« transform », « translate(0, -100px) »);
}
else {
tooltip.style(« display », « block »);
}
}

// Desktop non-zoomed tooltip
function moveDesktop(e,) {
let geoPath = d3.geoPath(proj, comContext);

let ptMouse, l, j, iter = 0;
const [x, y] = this ? d3.pointer(e) : [200, 200];
j = delaunay.find(x, y, j);
//let isHovering = comCanvas.getContext(‘2d’).getImageData(x, y, 1, 1).data[3] > 60;
let isHovering = true;

if (isHovering) {
ptMouse = proj.invert([x, y]);
let inPolygon = booleanPointInPolygon(ptMouse, communes.features[j]);
if (!inPolygon && j != 1) {
let currentZone = [j], kernel = [], nextZone;

while (l === undefined && iter++ < 4) {
nextZone = delaunayNextring(delaunay, currentZone, kernel);
l = nextZone.find(k => booleanPointInPolygon(ptMouse, communes.features[k]));
kernel = kernel.concat(currentZone);
currentZone = nextZone;
}
if (l !== undefined) j = l;
else j = undefined;
}
if (j === undefined) {
tooltip.style(« display », « none »);
return;
}
if (j == 1) j = 99;

if (j !== undefined) {
let com;
let deptNb;
let comName;
let data;
if (j == 99) {
com = communes.features.find(d => d.properties.c == ‘fe’);
deptNb = j;
comName = com.properties.l;
data = dataC.find(d => d.com == ’99’);
}
else {
com = communes.features[j].properties;
deptNb = com.c.slice(0, -3);
if (deptNb !== ‘2A’ && deptNb !== ‘2B’ && parseInt(deptNb) >= 96) deptNb = com.c.slice(0, -2);
comName = com.l;
data = dataC.find(d => d.com == com.c);
}
let score = data[‘sc’ + categ];

let deptName = deptDict[deptNb].nom_d;
let title = deptNb == 99 ? `${text.tt_fe}` : `${comName} (${deptName})`;
let content;

if (data.n == 103)
content = `${text.tt_nores}`;
else if (data.n == 104)
content = `${text.tt_meuse}`;
else if (data.n == 105)
content = `${text.tt_cc}`;
else {
if (score == ‘u’ || score == ‘undefined’)
content = « Solde naturel non disponible. »;
else if (categ == ‘solde2024’) {
let plural = Math.abs(score > 1) ||Math.abs(score < -1) ? ‘s’ :  »;
let rise = score >= 0
? score == 0
? ` Autant de naissances que de décès`
: `${new String(score).replace(‘.’, ‘,’)} décès de plus que de naissances`
: `${new String(score).replace(‘-‘,  »).replace(‘.’, ‘,’)} naissance${plural} de plus que de décès`;
content = `

${rise} en 2024

${text.tt_cta_dz}

`;
}
}

tooltip.select(‘.eu_map_tooltiptitle’)
.attr(‘aria-label’, ‘Infobulle’)
.html(`${title}`);

tooltip.select(‘.eu_map_tooltipvalue’)
.html(`

${content}

`);

tooltip.style(« transform », `translate(`
+ `calc(-50% + ${x >= Math.round(dimensions.width * 0.3) ? (x >= Math.round(dimensions.width * 0.6)) ? x – 70 : x : x + 70}px),`
+ `calc(-110% + ${y}px)`
+ `)`).style(« display », « block »);
}
else {
tooltip.style(« display », « none »);
}
}
else {
tooltip.style(« display », « none »);
}
}

// Watch categ buttons
document.querySelectorAll(« .eu_map_select »).forEach(button => {
button.onclick = (e) => {
let newCateg = button.getAttribute(« name »);
if (newCateg != categ) {
categ = newCateg;
dataC.sort((a, b) => a[‘c’ + categ] < b[‘c’ + categ] ? -1 : 1);
document.querySelectorAll(« .eu_map_select »).forEach(b => {
b.classList.remove(« eu_map_selected »);
});
button.classList.add(« eu_map_selected »);
drawMap(x, y, k);
drawLegend({
color: categ == ‘solde2024’ ? colorScaleSolde : colorScaleRatio,
divWidth: dimensions.width,
});
}
}
});

// Watch reset button

document.querySelector(« .eu_map_reset »).onclick = (e) => {
resetMe();
}

// Watch visibility change

document.onvisibilitychange = async (evt) => {
if (document.visibilityState === « hidden ») {
console.log(« hidden »);
} else {
console.log(« visible »);
drawMap(x, y, k);
}
};

drawMap();
handleMouseEvents();

}).catch((error) => {
throw error;
});

}

initMap(« fr »);

Il vous reste 56.75% de cet article à lire. La suite est réservée aux abonnés.

Share. Facebook Twitter Pinterest LinkedIn Telegram WhatsApp Email

Articles Liés

L’usage de pesticides bouleverserait en profondeur la biodiversité microbienne des sols

L’usage de pesticides bouleverserait en profondeur la biodiversité microbienne des sols

Environnement mars 4, 2026
L’effet de la guerre contre l’Iran est déjà visible pour le consommateur américain

L’effet de la guerre contre l’Iran est déjà visible pour le consommateur américain

Environnement mars 4, 2026
A Paris, Anne Hidalgo laisse un espace public radicalement transformé, au prix d’une négligence dans l’entretien

A Paris, Anne Hidalgo laisse un espace public radicalement transformé, au prix d’une négligence dans l’entretien

Environnement mars 3, 2026
Au Brésil, les peuples amazoniens mobilisés contre les projets d’infrastructures obtiennent une victoire

Au Brésil, les peuples amazoniens mobilisés contre les projets d’infrastructures obtiennent une victoire

Environnement mars 3, 2026
à Miquelon, premier village français voué à être déplacé face à la montée des eaux, le consensus citoyen fait taire les batailles politiques

à Miquelon, premier village français voué à être déplacé face à la montée des eaux, le consensus citoyen fait taire les batailles politiques

Environnement mars 3, 2026
Autoroute A69 : l’Etat indemnise à hauteur de 79 millions d’euros le concessionnaire pour l’interruption du chantier en 2025

Autoroute A69 : l’Etat indemnise à hauteur de 79 millions d’euros le concessionnaire pour l’interruption du chantier en 2025

Environnement mars 3, 2026
Face à une surpêche toujours élevée, les scientifiques recommandent de baisser les captures

Face à une surpêche toujours élevée, les scientifiques recommandent de baisser les captures

Environnement mars 3, 2026
La dissuasion nucléaire française fait un grand pas vers l’Europe

La dissuasion nucléaire française fait un grand pas vers l’Europe

Environnement mars 3, 2026
Nucléaire : Emmanuel Macron annonce la « mise en place progressive d’une dissuasion avancée »

Nucléaire : Emmanuel Macron annonce la « mise en place progressive d’une dissuasion avancée »

Environnement mars 2, 2026

Actualité à la Une

A Dubaï, la nouvelle réalité des influenceurs français sous les frappes iraniennes

A Dubaï, la nouvelle réalité des influenceurs français sous les frappes iraniennes

mars 4, 2026
Confrontés aux attaques de drones, les voisins de l’Iran découvrent leur vulnérabilité

Confrontés aux attaques de drones, les voisins de l’Iran découvrent leur vulnérabilité

mars 4, 2026
REPORTAGE – « J’ai vu un bombardement à 500 m de moi » : les Iraniens se pressent au poste-frontière turc pour fuir la guerre

REPORTAGE – « J’ai vu un bombardement à 500 m de moi » : les Iraniens se pressent au poste-frontière turc pour fuir la guerre

mars 4, 2026

Choix de l'éditeur

Avec « Jumpers », Pixar orchestre une révolution chez les animaux menée par une jeune femme transformée en robot-castor

Avec « Jumpers », Pixar orchestre une révolution chez les animaux menée par une jeune femme transformée en robot-castor

mars 4, 2026
Pétrole : « La plupart des pays ont d’immenses stocks permettant de tenir deux à trois semaines »

Pétrole : « La plupart des pays ont d’immenses stocks permettant de tenir deux à trois semaines »

mars 4, 2026
Mort de Quentin Deranque : deux nouveaux suspects interpellés à Lyon

Mort de Quentin Deranque : deux nouveaux suspects interpellés à Lyon

mars 4, 2026
« Le bombardement de l’Iran a comme devancé l’explication par Donald Trump de ses buts »

« Le bombardement de l’Iran a comme devancé l’explication par Donald Trump de ses buts »

mars 4, 2026
Face à l’explosion de la désinformation, la nouvelle approche sociétale de l’UE et de la France

Face à l’explosion de la désinformation, la nouvelle approche sociétale de l’UE et de la France

mars 4, 2026
Facebook X (Twitter) Pinterest TikTok Instagram
2026 © Le Méridien. Tous droits réservés.
  • Politique de Confidentialité
  • Termes et Conditions
  • Contacter

Type above and press Enter to search. Press Esc to cancel.

Sign In or Register

Welcome Back!

Login to your account below.

Lost password?