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
« En Iran, un changement de régime ne peut et ne doit pas être imposé de l’extérieur », affirme un collectif de personnalités politiques de gauche

« En Iran, un changement de régime ne peut et ne doit pas être imposé de l’extérieur », affirme un collectif de personnalités politiques de gauche

janvier 15, 2026
Venezuela : « Nous n’avons pas peur d’affronter diplomatiquement » les Etats-Unis, affirme la présidente par intérim, Delcy Rodriguez

Venezuela : « Nous n’avons pas peur d’affronter diplomatiquement » les Etats-Unis, affirme la présidente par intérim, Delcy Rodriguez

janvier 15, 2026
Déjà candidat en 2020, le milliardaire Mohed Altrad retente sa chance à la mairie de Montpellier

Déjà candidat en 2020, le milliardaire Mohed Altrad retente sa chance à la mairie de Montpellier

janvier 15, 2026
Facebook X (Twitter) Instagram
Facebook X (Twitter) Instagram YouTube
Se Connecter
janvier 15, 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

Colère des agriculteurs : plus de 70 tracteurs dans le centre de Lyon à l’appel de la FNSEA

Colère des agriculteurs : plus de 70 tracteurs dans le centre de Lyon à l’appel de la FNSEA

Environnement janvier 15, 2026
Sur la côte chinoise, ces « raffineries théières » qui vivent du pétrole vénézuélien et iranien

Sur la côte chinoise, ces « raffineries théières » qui vivent du pétrole vénézuélien et iranien

Environnement janvier 15, 2026
En Antarctique, un sanctuaire inauguré pour conserver les archives glaciaires de la planète à – 52 °C

En Antarctique, un sanctuaire inauguré pour conserver les archives glaciaires de la planète à – 52 °C

Environnement janvier 14, 2026
A Rio de Janeiro, en pleine canicule, les travailleurs démunis face à la chaleur

A Rio de Janeiro, en pleine canicule, les travailleurs démunis face à la chaleur

Environnement janvier 14, 2026
« Le pétrole n’est pas une sorte de trésor souterrain que l’on peut “prendre” »

« Le pétrole n’est pas une sorte de trésor souterrain que l’on peut “prendre” »

Environnement janvier 14, 2026
Le « Nobel de l’environnement » attribué à une spécialiste des champignons mycorhiziens, invisibles mais fascinants et essentiels à la vie sur Terre

Le « Nobel de l’environnement » attribué à une spécialiste des champignons mycorhiziens, invisibles mais fascinants et essentiels à la vie sur Terre

Environnement janvier 14, 2026
Réchauffement climatique : 2025 dans le trio des années les plus chaudes jamais enregistrées

Réchauffement climatique : 2025 dans le trio des années les plus chaudes jamais enregistrées

Environnement janvier 14, 2026
le gouvernement annonce un « projet de loi d’urgence » agricole après une nouvelle manifestation des syndicats à Paris

le gouvernement annonce un « projet de loi d’urgence » agricole après une nouvelle manifestation des syndicats à Paris

Environnement janvier 13, 2026
Au Kenya, les terres consacrées aux crédits-carbone équivalent désormais à la superficie des terres arables

Au Kenya, les terres consacrées aux crédits-carbone équivalent désormais à la superficie des terres arables

Environnement janvier 13, 2026

Actualité à la Une

Venezuela : « Nous n’avons pas peur d’affronter diplomatiquement » les Etats-Unis, affirme la présidente par intérim, Delcy Rodriguez

Venezuela : « Nous n’avons pas peur d’affronter diplomatiquement » les Etats-Unis, affirme la présidente par intérim, Delcy Rodriguez

janvier 15, 2026
Déjà candidat en 2020, le milliardaire Mohed Altrad retente sa chance à la mairie de Montpellier

Déjà candidat en 2020, le milliardaire Mohed Altrad retente sa chance à la mairie de Montpellier

janvier 15, 2026
Pour Canal+, « Jean-Marc Morandini est à l’antenne de CNews, et il y restera »

Pour Canal+, « Jean-Marc Morandini est à l’antenne de CNews, et il y restera »

janvier 15, 2026

Choix de l'éditeur

Les règles de la prescription pénale vont-elles être bouleversées ? Les clés pour comprendre le débat avant une décision cruciale vendredi

Les règles de la prescription pénale vont-elles être bouleversées ? Les clés pour comprendre le débat avant une décision cruciale vendredi

janvier 15, 2026
Minneapolis : les images des manifestations contre l’ICE après qu’un agent a tiré sur un Vénézuélien

Minneapolis : les images des manifestations contre l’ICE après qu’un agent a tiré sur un Vénézuélien

janvier 15, 2026
le chef de la diplomatie danoise dément l’existence d’un groupe de travail « sur l’acquisition » de l’île

le chef de la diplomatie danoise dément l’existence d’un groupe de travail « sur l’acquisition » de l’île

janvier 15, 2026
Près de 100.000 dollars de cartes Pokémon volées au cours d’un braquage à New York

Près de 100.000 dollars de cartes Pokémon volées au cours d’un braquage à New York

janvier 15, 2026
Taïwan et les Etats-Unis signent un accord commercial pour abaisser les droits de douane de 20 % à 15 %

Taïwan et les Etats-Unis signent un accord commercial pour abaisser les droits de douane de 20 % à 15 %

janvier 15, 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?