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
Avec « Nino dans la nuit », le cinéaste Laurent Micheli dresse le portrait d’une jeunesse en rade, noyant ses galères dans la drogue et les fêtes

Avec « Nino dans la nuit », le cinéaste Laurent Micheli dresse le portrait d’une jeunesse en rade, noyant ses galères dans la drogue et les fêtes

mars 4, 2026
« Nous avons sous-estimé la violence du choc en train de s’abattre sur nous » : le Bade-Wurtemberg, le Land modèle confronté à l’effondrement de son économie

« Nous avons sous-estimé la violence du choc en train de s’abattre sur nous » : le Bade-Wurtemberg, le Land modèle confronté à l’effondrement de son économie

mars 4, 2026
A Paris, les mobilités bouleversées par deux mandats d’Anne Hidalgo, pour un résultat encore discutable et parfois brouillon

A Paris, les mobilités bouleversées par deux mandats d’Anne Hidalgo, pour un résultat encore discutable et parfois brouillon

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

La France a connu un hiver « exceptionnel », avec un défilé de tempêtes, des crues majeures et des précipitations record

La France a connu un hiver « exceptionnel », avec un défilé de tempêtes, des crues majeures et des précipitations record

Environnement mars 4, 2026
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

Actualité à la Une

« Nous avons sous-estimé la violence du choc en train de s’abattre sur nous » : le Bade-Wurtemberg, le Land modèle confronté à l’effondrement de son économie

« Nous avons sous-estimé la violence du choc en train de s’abattre sur nous » : le Bade-Wurtemberg, le Land modèle confronté à l’effondrement de son économie

mars 4, 2026
A Paris, les mobilités bouleversées par deux mandats d’Anne Hidalgo, pour un résultat encore discutable et parfois brouillon

A Paris, les mobilités bouleversées par deux mandats d’Anne Hidalgo, pour un résultat encore discutable et parfois brouillon

mars 4, 2026
Aux Etats-Unis, le Buy American Act pour préserver l’emploi

Aux Etats-Unis, le Buy American Act pour préserver l’emploi

mars 4, 2026

Choix de l'éditeur

Le groupe d’ultradroite Bloc montpelliérain dissous en conseil des ministres

Le groupe d’ultradroite Bloc montpelliérain dissous en conseil des ministres

mars 4, 2026
Élections municipales 2026 : les propriétaires d’animaux dragués comme jamais par les candidats

Élections municipales 2026 : les propriétaires d’animaux dragués comme jamais par les candidats

mars 4, 2026
un atlas microbien du territoire danois

un atlas microbien du territoire danois

mars 4, 2026
La France a connu un hiver « exceptionnel », avec un défilé de tempêtes, des crues majeures et des précipitations record

La France a connu un hiver « exceptionnel », avec un défilé de tempêtes, des crues majeures et des précipitations record

mars 4, 2026
Avec « Adèle Berry », l’auteur, chanteur et compositeur Yanowski ranime la comédie musicale

Avec « Adèle Berry », l’auteur, chanteur et compositeur Yanowski ranime la comédie musicale

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?