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
« The Cruise » : dans le New York de la fin du siècle, portrait d’un guide touristique en roue libre

« The Cruise » : dans le New York de la fin du siècle, portrait d’un guide touristique en roue libre

mars 4, 2026
Après les mandats d’Anne Hidalgo, un Paris plus endetté que jamais pour une politique d’investissement toujours plus volontariste

Après les mandats d’Anne Hidalgo, un Paris plus endetté que jamais pour une politique d’investissement toujours plus volontariste

mars 4, 2026
Grèce : les dirigeants d’Aube dorée, ancien parti néonazi,  reconnus coupables en appel de « direction d’une organisation criminelle »

Grèce : les dirigeants d’Aube dorée, ancien parti néonazi, reconnus coupables en appel de « direction d’une organisation criminelle »

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

Après les mandats d’Anne Hidalgo, un Paris plus endetté que jamais pour une politique d’investissement toujours plus volontariste

Après les mandats d’Anne Hidalgo, un Paris plus endetté que jamais pour une politique d’investissement toujours plus volontariste

mars 4, 2026
Grèce : les dirigeants d’Aube dorée, ancien parti néonazi,  reconnus coupables en appel de « direction d’une organisation criminelle »

Grèce : les dirigeants d’Aube dorée, ancien parti néonazi, reconnus coupables en appel de « direction d’une organisation criminelle »

mars 4, 2026
Pedro Sanchez répond à Donald Trump et défend son refus d’aider à frapper l’Iran

Pedro Sanchez répond à Donald Trump et défend son refus d’aider à frapper l’Iran

mars 4, 2026

Choix de l'éditeur

En Israël, la satisfaction sur le bilan des premiers jours de la guerre

En Israël, la satisfaction sur le bilan des premiers jours de la guerre

mars 4, 2026
Prix des carburants : une « hausse de quelques centimes » attendue, des contrôles prévus

Prix des carburants : une « hausse de quelques centimes » attendue, des contrôles prévus

mars 4, 2026
« La Maison des femmes » : un collectif au service de celles qui subissent des violences

« La Maison des femmes » : un collectif au service de celles qui subissent des violences

mars 4, 2026
Guerre au Moyen Orient : le gouvernement prévoit une hausse « de quelques centimes » des prix des carburants mais va intensifier les contrôles dans les stations-service

Guerre au Moyen Orient : le gouvernement prévoit une hausse « de quelques centimes » des prix des carburants mais va intensifier les contrôles dans les stations-service

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