document.querySelector(« #dec_deuxieme_para »).innerHTML = asterisque + textes_dec.texte_asterique;
function extraireTitre(civilite) {
const titre = civilite.split( » « )[0];
if (titre === « M. ») {
return textes_dec.maire_elu;
} else if (titre === « Mme ») {
return textes_dec.maire_elue;
} else {
return textes_dec.maire_elu;
}
}
function initTooltipBrt(selector) {
let currentTooltip = null;
function removeCurrentTooltip() {
if (currentTooltip) {
currentTooltip.remove();
currentTooltip = null;
}
}
function showTooltip(elmt) {
removeHoverTooltip();
removeCurrentTooltip();
let tt_fixe = document.createElement(« div »);
tt_fixe.classList.add(« tooltipbrt »);
tt_fixe.innerHTML = `
×
${elmt.getAttribute(« data-tt »)}
`;
document.body.appendChild(tt_fixe);
// Positionnement du tooltip
if (window.innerWidth > 500) {
const rect = elmt.getBoundingClientRect();
tt_fixe.style.top = rect.top – 14 + window.scrollY – tt_fixe.offsetHeight + « px »;
tt_fixe.style.left = rect.left + rect.width / 2 – tt_fixe.offsetWidth / 2 + 2 + « px »;
}
// Gestionnaire pour fermer le tooltip
tt_fixe.querySelector(« .fermer-tooltip »).addEventListener(« click », function () {
removeCurrentTooltip();
reset_func();
d3.selectAll(« #dec_mun circle.bubulle »).classed(« opacified », false);
d3.selectAll(« .dec_nuance »).classed(« choisi », false);
d3.selectAll(« .dec_nuance.latotale »).classed(« choisi », true);
});
currentTooltip = tt_fixe;
return tt_fixe;
}
// Sélectionne les éléments
let tt_fixe_elmts = getA(selector);
// Ajoute les événements de clic
forEach(tt_fixe_elmts, function (elmt) {
elmt.addEventListener(« click », function (e) {
e.stopPropagation();
showTooltip(this);
});
});
// Fonction pour afficher le tooltip manuellement
function showTooltipManually(elmt) {
forEach(tt_fixe_elmts, function (e) {
e.classList.remove(« selected-commune »);
});
elmt.classList.add(« selected-commune »);
// on poireaute un peu
setTimeout(() => showTooltip(elmt), 25);
}
// Retourne les fonctions utiles
return {
showTooltipManually,
showTooltip,
};
}
function showHoverTooltip(elmt) {
removeHoverTooltip();
const tt = document.createElement(« div »);
tt.classList.add(« minitt », « tooltipbrt »);
tt.innerHTML = elmt.getAttribute(« data-tt ») + »;
document.body.appendChild(tt);
const rect = elmt.getBoundingClientRect();
tt.style.top = rect.top – 14 + window.scrollY – tt.offsetHeight + « px »;
tt.style.left = rect.left + 2 + rect.width / 2 – tt.offsetWidth / 2 + « px »;
}
function removeHoverTooltip() {
const existing = document.querySelector(« .minitt »);
if (existing) existing.remove();
}
function dessinerBubulles(langue) {
// on modifie quelques textes en dur
if (langue != « fr ») {
d3.select(« #search_mun input »).attr(« placeholder », « Search for a town or a city »);
}
// Variables globales
const largeur = document.getElementById(« dec_mun »).offsetWidth;
const mobileDec = document.getElementById(« contenant_carte »).offsetWidth < 600;
const ratioMun = mobileDec ? 1.4 : 1.3;
const hauteur = largeur * ratioMun;
const is_dark = document.querySelector(« html »).getAttribute(« data-color-mode ») === « dark »;
// Initialisation du SVG
const svg = d3
.select(« #dec_mun »)
.append(« svg »)
.attr(« width », « 100% »)
.attr(« viewBox », `${largeur * -0.025} ${largeur * ratioMun * -0.05} ${largeur} ${largeur * ratioMun}`),
dec_dept = svg.append(« g »),
dec_ligne = svg.append(« g »),
dec_communes = svg.append(« g »),
dec_textes = svg.append(« g »);
// Chargement des données
// URL finale : https://assets-decodeurs.lemonde.fr/decodeurs/municipales_2026_snippets/municipales/exports/2026/T2/listes_en_tete.json
// test : https://assets-decodeurs.lemonde.fr/decodeurs/municipales_2026_snippets/municipales/exports/2026test2/T2/listes_en_tete.json
Promise.all([d3.json(« //assets-decodeurs.lemonde.fr/decodeurs/assets/municipales2026/brt_3500.json »), d3.csv(« //assets-decodeurs.lemonde.fr/decodeurs/assets/municipales2026/commplus3500.csv »), d3.json(« //assets-decodeurs.lemonde.fr/decodeurs/municipales_2026_snippets/municipales/exports/2026/T2/listes_en_tete.json »), d3.csv(« //assets-decodeurs.lemonde.fr/sheets/wAn2GJcj3n7zw3Ivl7sP8tBTw6KHCg_3917.csv »), d3.csv(« //assets-decodeurs.lemonde.fr/sheets/wAn2GJcj3n7zw3Ivl7sP8tBTw6KHCg_3918.csv »), d3.csv(« //assets-decodeurs.lemonde.fr/sheets/wAn2GJcj3n7zw3Ivl7sP8tBTw6KHCg_3985.csv »)]).then(
function ([geoData, popData, resultData, nuancesMin, nuancesLM, blocsData]) {
const dicoPop = {},
listeComm = [],
listeBlocs = [],
listeNuancesLM = [];
let decompteBlocs = {},
decompteNuances = {},
decompteTours = {},
dataGraphe = {},
dataGraphePop = {},
totalBubulles = 0,
resultBubulles = 0,
totalPop = 0,
resultPop = 0;
// si on a des résultats
if (resultData.length > 0) {
document.querySelector(« #titre_tetesliste »).innerHTML = textes_dec.leg_tetesliste + asterisque;
document.querySelector(« #titre_nuanceliste »).innerHTML = textes_dec.leg_blocs;
} else {
document.querySelector(« #titre_tetesliste »).innerHTML = textes_dec.pasresultat;
d3.selectAll(« #titre_nuanceliste, #dec_deuxieme_para »).style(« display », « none »);
}
// mes dicos
const resultDict = resultData.reduce((acc, current) => {
acc[current.code_circo] = current;
return acc;
}, {}),
dicoMin = nuancesMin.reduce((acc, e) => {
e.n = +e.n;
acc[e.code] = e;
return acc;
}, {}),
dicoLM = nuancesLM.reduce((acc, e) => {
e.n = +e.n;
acc[e.code] = e;
return acc;
}, {}),
dicoBloc = blocsData.reduce((acc, e) => {
e.n = +e.n;
acc[e.bloc] = e;
return acc;
}, {});
function listerLesListes(circonscription, maxListes) {
if (!maxListes) {
maxListes = 10;
}
var html= »
« ;
return html;
}
// Remplir le dictionnaire de population
popData.forEach((row) => (dicoPop[row.code_insee] = +row[« PMUN »]));
// Paramètres pour les cercles
const minPop = 3000,
maxPop = d3.max(popData, (d) => +d[« PMUN »]),
valeursCercles = mobileDec ? [1, largeur / 38] : [1.5, largeur / 36],
unite = valeursCercles[1],
echelleRayon = d3.scaleSqrt().domain([minPop, maxPop]).range([valeursCercles[0], valeursCercles[1]]).clamp(true);
// Extraction des points et départements
const points = topojson.feature(geoData, geoData.objects.p_com),
departements = topojson.feature(geoData, geoData.objects.a_dept);
// Projection et path
const projection = d3
.geoIdentity()
.reflectY(true)
.fitSize([largeur * 0.95, largeur * ratioMun * 0.9], points),
path = d3.geoPath().projection(projection);
// Dessiner les départements/la Fronce
// dec_dept.selectAll(« .departement »).data(departements.features)tnter().append(« path »).attr(« class », « departement »).attr(« d », path);
dec_dept
.append(« path »)
.attr(« class », « departement »)
.attr(« d », path(topojson.merge(geoData, geoData.objects.a_dept.geometries)));
// la légende
const legende = svg
.append(« g »)
.attr(« class », « legende passelect »)
.attr(« transform », « translate( » + largeur * 0.075 + « , » + hauteur * 0.075 + « ) »);
const valeursLeg = mobileDec ? [200000, 2000000] : [100000, 700000, 2000000],
xLabel = largeur * 0.08;
legende
.selectAll(« circle.leg_stroke »)
.data(valeursLeg)
.join(« circle »)
.attr(« class », « leg_stroke »)
.attr(« cx », 0)
.attr(« cy », (d) => -echelleRayon(d))
.attr(« r », (d) => echelleRayon(d))
.style(« fill », « none »);
legende
.selectAll(« line.leg_stroke »)
.data(valeursLeg)
.join(« line »)
.attr(« class », « leg_stroke »)
.attr(« x1 », 0)
.attr(« x2 », xLabel)
.attr(« y1 », (d) => -echelleRayon(d) * 2)
.attr(« y2 », (d, i) => -echelleRayon(d) * 2)
.style(« stroke-dasharray », « 2,2 »);
legende
.selectAll(« text.texte_leg »)
.data(valeursLeg)
.join(« text »)
.attr(« class », « texte_leg »)
.attr(« x », xLabel * 1.1)
.attr(« y », (d) => 3 + -echelleRayon(d) * 2)
.text(function (d) {
if (langue == « fr ») {
return milliers(d) + (d >= 1000000 ? » d’hab. » : « »);
} else {
return thousands(d) + (d >= 1000000 ? » inhab. » : « »);
}
});
// Préparation des données pour les cercles
// + la liste pour le menu déroulant
const circlesData = points.features
.filter((d, i) => dicoPop[d.properties.c] !== undefined /*&& i < 600*/)
.map((d) => {
listeComm.push({
label: { name: d.properties.l + » ( » + d.properties.d + « ) » },
data: { name: d.properties.l, dept: d.properties.d, c: d.properties.c },
});
const pop = dicoPop[d.properties.c] || 0;
var radiusTemp = 1;
// variables
if (pop) {
radiusTemp = echelleRayon(pop);
}
cXtemp = projection(d.geometry.coordinates)[0];
cYtemp = projection(d.geometry.coordinates)[1];
if (dicoPosition[d.properties.c]) {
tempProj = projection([dicoPosition[d.properties.c][0], dicoPosition[d.properties.c][1]]);
cXtemp = tempProj[0];
cYtemp = tempProj[1];
}
return {
cx: cXtemp,
cy: cYtemp,
r: radiusTemp,
l: d.properties.l,
d: d.properties.d,
id: d.properties.c,
p: dicoPop[d.properties.c],
};
});
const simulation = d3
.forceSimulation(circlesData)
.force(« x », d3.forceX((d) => d.cx).strength(0.5))
.force(« y », d3.forceY((d) => d.cy).strength(0.5))
.force(« collide », d3.forceCollide((d) => d.r + 0.2).strength(0.5))
.on(« tick », ticked)
.on(« end », () => {
simulation.stop();
});
// Dessin des cercles
const circles = dec_communes
.selectAll(« circle »)
.data(circlesData)
.enter()
.append(« circle »)
.attr(« class », function (d, i) {
if (resultDict[d.id]) {
resultBubulles++;
resultPop += d.p;
}
totalBubulles++;
totalPop += d.p;
return resultDict[d.id] ? « bubulle resultat » : « bubulle sansresultat »;
})
.attr(« data-insee », (d) => d.id)
.attr(« r », (d) => d.r)
.attr(« data-tt », function (d) {
if (resultDict[d.id]) {
e = resultDict[d.id];
let html= »
» + d.l + » ( » + d.d + « )
« ;
if (e) {
html += listerLesListes(e, 5);
} else {
html += ‘
‘ + textes_dec.pasresultat + «
« ;
}
html += »;
html += ‘ »;
return html;
} else {
let html= »
» + d.l + » ( » + d.d + « )
« ;
html += «
» + textes_dec.noresult + «
« ;
html += »;
html += ‘ »;
return html;
}
})
.attr(« data-status », function (d) {
if (resultDict[d.id]) {
// je fais le compte
if (!decompteTours[resultDict[d.id].status]) {
decompteTours[resultDict[d.id].status] = 0;
}
decompteTours[resultDict[d.id].status]++;
// je remplis
return resultDict[d.id] ? resultDict[d.id].status : « »;
}
})
.attr(« data-bloc », function (d) {
if (resultDict[d.id]) {
if (dicoLM[resultDict[d.id].liste_1_nuance]) {
if (dicoLM[resultDict[d.id].liste_1_nuance].bloc) {
// on crée la dataGraphe
if (!dataGraphe[dicoLM[resultDict[d.id].liste_1_nuance].bloc]) {
dataGraphe[dicoLM[resultDict[d.id].liste_1_nuance].bloc] = { T1: 0, T2: 0 };
dataGraphePop[dicoLM[resultDict[d.id].liste_1_nuance].bloc] = { T1: 0, T2: 0 };
}
// on ajoute la population
// T2
if (resultDict[d.id].status == « Elue ») {
dataGraphe[dicoLM[resultDict[d.id].liste_1_nuance].bloc][« T2 »]++;
dataGraphePop[dicoLM[resultDict[d.id].liste_1_nuance].bloc][« T2 »] += d.p;
}
// T1
if (resultDict[d.id].status == « Elue en T1 ») {
dataGraphe[dicoLM[resultDict[d.id].liste_1_nuance].bloc][« T1 »]++;
dataGraphePop[dicoLM[resultDict[d.id].liste_1_nuance].bloc][« T1 »] += d.p;
}
// on remplit le décompte
if (!decompteBlocs[dicoLM[resultDict[d.id].liste_1_nuance].bloc]) {
decompteBlocs[dicoLM[resultDict[d.id].liste_1_nuance].bloc] = 0;
}
decompteBlocs[dicoLM[resultDict[d.id].liste_1_nuance].bloc]++;
return dicoLM[resultDict[d.id].liste_1_nuance].bloc;
}
} else if (dicoMin[resultDict[d.id].liste_1_nuance]) {
if (dicoMin[resultDict[d.id].liste_1_nuance].bloc) {
// on crée la dataGraphe
if (!dataGraphe[dicoMin[resultDict[d.id].liste_1_nuance].bloc]) {
dataGraphe[dicoMin[resultDict[d.id].liste_1_nuance].bloc] = { T1: 0, T2: 0 };
dataGraphePop[dicoMin[resultDict[d.id].liste_1_nuance].bloc] = { T1: 0, T2: 0 };
}
// on ajoute la population
// T2
if (resultDict[d.id].status == « Elue ») {
dataGraphe[dicoMin[resultDict[d.id].liste_1_nuance].bloc][« T2 »]++;
dataGraphePop[dicoMin[resultDict[d.id].liste_1_nuance].bloc][« T2 »] += d.p;
}
// T1
if (resultDict[d.id].status == « Elue en T1 ») {
dataGraphe[dicoMin[resultDict[d.id].liste_1_nuance].bloc][« T1 »]++;
dataGraphePop[dicoMin[resultDict[d.id].liste_1_nuance].bloc][« T1 »] += d.p;
}
// on remplit le décompte ministère
if (!decompteBlocs[dicoMin[resultDict[d.id].liste_1_nuance].bloc]) {
decompteBlocs[dicoMin[resultDict[d.id].liste_1_nuance].bloc] = 0;
}
decompteBlocs[dicoMin[resultDict[d.id].liste_1_nuance].bloc]++;
return dicoMin[resultDict[d.id].liste_1_nuance].bloc;
}
}
}
})
.attr(« data-nuance-lm », function (d) {
if (resultDict[d.id] && resultDict[d.id].liste_1_nuance_lemonde) {
// on remplit le décompte LM
if (!decompteNuances[resultDict[d.id].liste_1_nuance_lemonde]) {
decompteNuances[resultDict[d.id].liste_1_nuance_lemonde] = 0;
}
decompteNuances[resultDict[d.id].liste_1_nuance_lemonde]++;
return resultDict[d.id].liste_1_nuance_lemonde;
} else if (resultDict[d.id] && resultDict[d.id].liste_1_nuance) {
if (!decompteNuances[resultDict[d.id].liste_1_nuance]) {
decompteNuances[resultDict[d.id].liste_1_nuance] = 0;
}
decompteNuances[resultDict[d.id].liste_1_nuance]++;
return resultDict[d.id].liste_1_nuance;
}
})
.attr(« style », function (d) {
if (resultDict[d.id]) {
// je stocke les blocs depuis les nuances LM
if (dicoLM[resultDict[d.id].liste_1_nuance]) {
if (listeBlocs.indexOf(dicoLM[resultDict[d.id].liste_1_nuance].bloc) == -1) {
listeBlocs.push(dicoLM[resultDict[d.id].liste_1_nuance].bloc);
}
} else if (dicoMin[resultDict[d.id].liste_1_nuance]) {
// les blocs depuis les nuances ministère
if (listeBlocs.indexOf(dicoMin[resultDict[d.id].liste_1_nuance].bloc) == -1) {
listeBlocs.push(dicoMin[resultDict[d.id].liste_1_nuance].bloc);
}
} else {
console.warn(« ouille, pas de nuance « intérieur » », d.id, resultDict[d.id].liste_1_nuance);
}
if (resultDict[d.id].liste_1_nuance_lemonde) {
if (listeNuancesLM.indexOf(resultDict[d.id].liste_1_nuance_lemonde) == -1) {
listeNuancesLM.push(resultDict[d.id].liste_1_nuance_lemonde);
}
}
if (dicoLM[resultDict[d.id].liste_1_nuance_lemonde]) {
styleCercle = « –color: » + dicoLM[resultDict[d.id].liste_1_nuance_lemonde].couleur + « ; –dark-color: » + dicoLM[resultDict[d.id].liste_1_nuance_lemonde].couleur_dark + « ;–stroke-color: » + d3.rgb(dicoLM[resultDict[d.id].liste_1_nuance_lemonde].couleur).darker(1) + « ;–stroke-dark-color: » + d3.rgb(dicoLM[resultDict[d.id].liste_1_nuance_lemonde].couleur_dark).darker(1) + « ; »;
} else if (dicoMin[resultDict[d.id].liste_1_nuance]) {
styleCercle = « –color: » + dicoMin[resultDict[d.id].liste_1_nuance].couleur + « ; –dark-color: » + dicoMin[resultDict[d.id].liste_1_nuance].couleur_dark + « ;–stroke-color: » + d3.rgb(dicoMin[resultDict[d.id].liste_1_nuance].couleur).darker(1) + « ;–stroke-dark-color: » + d3.rgb(dicoMin[resultDict[d.id].liste_1_nuance].couleur_dark).darker(1) + « ; »;
}
return styleCercle;
} else {
return « –color: #323232; –dark-color: #A4A4A4;–stroke-color:#636363;–stroke-dark-color:#cdcdcd; »;
}
})
.style(« stroke-width », (d) => (resultDict[d.id] ? 0 : 0.25))
.on(« mouseover », function () {
d3.select(this).style(« stroke-width », 1.5);
if (!mobileDec) {
showHoverTooltip(this);
}
})
.on(« mouseout », function () {
d3.select(this).style(« stroke-width », (d) => (resultDict[d.id] ? 0 : 0.25));
removeHoverTooltip();
});
// on lance la création du graphe
dessinerGraphe(« #graphe_t1t2 », dataGraphe, dataGraphePop, dicoBloc);
// j’ajoute le texte pour les DROM
if (langue == « fr ») {
var listeDrom = [
// ligne du bas
{ nom: « S.-Pierre-et-M. », nom_court: « SPM », hauteur: 0.93, largeur: 0.2 },
{ nom: « Nouvelle-Calédonie », nom_court: « N.-Calédonie », hauteur: 0.93, largeur: 0.39 },
{ nom: « Polynésie fr. », nom_court: « Poly. fr. », hauteur: 0.93, largeur: 0.57 },
{ nom: « Mayotte », nom_court: « Mayotte », hauteur: 0.93, largeur: 0.74 },
// ligne du haut ligne
{ nom: « Guadeloupe », nom_court: « Guadeloupe », hauteur: 0.73, largeur: 0.2 },
{ nom: « Martinique », nom_court: « Martinique », hauteur: 0.73, largeur: 0.37 },
{ nom: « Guyane », nom_court: « Guyane », hauteur: 0.73, largeur: 0.55 },
{ nom: « La Réunion », nom_court: « Réunion », hauteur: 0.73, largeur: 0.74 },
];
} else {
var listeDrom = [
// ligne du bas
{ nom: « St. Pierre and M. », nom_court: « SPM », hauteur: 0.93, largeur: 0.2 },
{ nom: « New Caledonia », nom_court: « N-Caledonia », hauteur: 0.93, largeur: 0.39 },
{ nom: « French Polynesia », nom_court: « Fr Polynesia », hauteur: 0.93, largeur: 0.57 },
{ nom: « Mayotte », nom_court: « Mayotte », hauteur: 0.93, largeur: 0.74 },
// ligne du haut ligne
{ nom: « Guadeloupe », nom_court: « Guadeloupe », hauteur: 0.73, largeur: 0.2 },
{ nom: « Martinique », nom_court: « Martinique », hauteur: 0.73, largeur: 0.37 },
{ nom: « French Guiana », nom_court: « Fr Guiana », hauteur: 0.73, largeur: 0.55 },
{ nom: « La Réunion », nom_court: « Réunion », hauteur: 0.73, largeur: 0.74 },
];
}
dec_textes
.selectAll(« text.ile »)
.data(listeDrom)
.enter()
.append(« text »)
.attr(« class », « ile passelect »)
.attr(« x », (d) => largeur * d.largeur)
.attr(« y », (d) => hauteur * (mobileDec ? d.hauteur – 0.02 : d.hauteur))
.text((d) => (mobileDec ? d.nom_court : d.nom));
// après la création des bubulles, on peut remplir
// le premier para avec quelques infos au long
if (langue == « fr » && resultData.length > 0) {
texte_html = « Cette carte de France affiche les résultats du premier tour des municipales dans » + milliers(resultBubulles) + » commune » + (resultData.length >= 2 ? « s » : « ») + » française » + (resultData.length >= 2 ? « s » : « ») + » représentant » + milliers(resultPop) + (resultPop < 1000000 ? » » : » d’ ») + « habitants ; soit » + milliers((resultBubulles / totalBubulles) * 100) + » % de communes dépouillées sur » + milliers(totalBubulles) + » (choisies parce qu’elles ont plus de 3 500 habitants ou qu’elles ont été jugées importantes par Le Monde). »;
if (resultBubulles < decompteTours[« Elue en T1″]) {
texte_html += » Parmi elles, » + milliers(decompteTours[« Elue en T1″]) + » ont déjà une élu une liste avec plus de 50 % des voix au premier tour. »;
}
document.querySelector(« #dec_premier_para »).innerHTML = texte_html;
} else {
document.getElementById(« dec_premier_para »).remove();
}
/*██ /██ /██
| ██ /██__/ | ██
| ██ /██████ /██████ /██████ /███████ /███████ /██████
| ██ /██__ ██ /██__ ██ /██__ ██| ██__ ██ /██__ ██ /██__ ██
| ██| ████████| ██ ██| ████████| ██ ██| ██ | ██| ████████
| ██| ██_____/| ██ | ██| ██_____/| ██ | ██| ██ | ██| ██_____/
| ██| ███████| ███████| ███████| ██ | ██| ███████| ███████
|__/ _______/ ____ ██ _______/|__/ |__/ _______/ _______/
/██ ██
| ██████/ *INTERACTIVE
_____*/
if (resultData.length > 0) {
var legendeBlocs= »
» + textes_dec.toutafficher + «
« ;
listeBlocs.sort((a, b) => {
const valA = dicoBloc[a] ? dicoBloc[a].n : Infinity;
const valB = dicoBloc[b] ? dicoBloc[b].n : Infinity;
return valA – valB;
});
for (const [i, d] of listeBlocs.entries()) {
if (dicoBloc[d]) {
e = dicoBloc[d];
if (decompteBlocs[e.bloc] >= minLegende) {
legendeBlocs += ‘
‘ + (langue == « fr » ? e.bloc : e.bloc_en) + ‘ ‘ + decompteBlocs[e.bloc] + «
« ;
}
}
}
legendeCouleurs = d3.select(« #dec_leg_min »).html(legendeBlocs);
// on va faire aussi une légende avec les nuances LM
var legendeNuancesLM = ‘
‘ + textes_dec.toutafficher + «
« ;
listeNuancesLM.sort((a, b) => {
const valA = dicoLM[a] ? dicoLM[a].n : Infinity;
const valB = dicoLM[b] ? dicoLM[b].n : Infinity;
return valA – valB;
});
for (const [i, d] of listeNuancesLM.entries()) {
if (dicoLM[d]) {
e = dicoLM[d];
if (decompteNuances[e.code] >= minLegende) {
legendeNuancesLM += ‘
‘ + (langue == « fr » ? e.nom_court : e.nom_court_en) + ‘ ‘ + decompteNuances[e.code] + «
« ;
}
}
}
legendeCouleursLM = d3.select(« #dec_leg_lm »).html(legendeNuancesLM);
var leg_tours= »
» + textes_dec.toutafficher + «
« ;
leg_tours += ‘
‘ + textes_dec.deuxiemetour + » » + (langue == « fr » ? milliers(decompteTours[« Elue »]) : thousands(decompteTours[« Elue »])) + «
« ;
leg_tours += ‘
‘ + textes_dec.liste_elue + » » + (langue == « fr » ? milliers(decompteTours[« Elue en T1 »]) : thousands(decompteTours[« Elue en T1 »])) + «
« ;
var legendeStatus = d3.select(« #dec_leg_elu »).html(leg_tours);
// Variables pour stocker les sélections
var selectedStatus = « tout »;
var selectedBloc = « tout »;
var selectedNuanceLM = « tout »;
// Fonction de filtrage combiné
function filtrerLesCercles() {
svg.selectAll(« circle.bubulle »).classed(« opacified », function () {
var currentStatus = d3.select(this).attr(« data-status »);
var currentNuance = d3.select(this).attr(« data-bloc »);
var currentNuanceLM = d3.select(this).attr(« data-nuance-lm »);
// Condition pour vérifier si le cercle doit être affiché
var isVisible = (currentStatus === selectedStatus || selectedStatus === « tout ») && (currentNuance === selectedBloc || selectedBloc === « tout ») && (currentNuanceLM === selectedNuanceLM || selectedNuanceLM === « tout »);
return !isVisible;
});
}
// Interaction pour le status
legendeStatus.selectAll(« .dec_status »).on(« click », function () {
d3.selectAll(« .tooltipbrt »).remove();
d3.selectAll(« #dec_leg_elu .dec_status »).classed(« choisi », false);
d3.select(this).classed(« choisi », true);
selectedStatus = d3.select(this).attr(« data-status »);
filtrerLesCercles();
});
// Interaction pour les nuances
legendeCouleurs.selectAll(« .dec_nuance_min »).on(« click », function () {
d3.selectAll(« .tooltipbrt »).remove();
d3.selectAll(« .dec_nuance_min »).classed(« choisi », false);
d3.select(this).classed(« choisi », true);
selectedBloc = d3.select(this).attr(« data-bloc »);
selectedNuanceLM = « tout »;
d3.selectAll(« .dec_nuance_lm »).classed(« choisi », false);
d3.selectAll(« .dec_nuance_lm.latotale »).classed(« choisi », true);
d3.select(this).classed(« choisi », true);
filtrerLesCercles();
});
// Interaction pour nuance LM
legendeCouleursLM.selectAll(« .dec_nuance_lm »).on(« click », function () {
d3.selectAll(« .tooltipbrt »).remove();
d3.selectAll(« #dec_leg_lm .dec_nuance_lm »).classed(« choisi », false);
d3.select(this).classed(« choisi », true);
selectedNuanceLM = d3.select(this).attr(« data-nuance-lm »);
selectedBloc = « tout »;
d3.selectAll(« .dec_nuance_min »).classed(« choisi », false);
d3.selectAll(« .dec_nuance_min.latotale »).classed(« choisi », true);
filtrerLesCercles();
});
}
// fin de la gestion de la légende interactive
// Mise à jour des positions des cercles
function ticked() {
circles.attr(« cx », (d) => d.x).attr(« cy », (d) => d.y);
}
// Initialisation du tooltip
const { showTooltipManually, showTooltip } = initTooltipBrt(« #dec_mun .bubulle »);
// la fonction qui traite les résultats
const func_to_treat_result_donnees = (result) => {
setTimeout(() => d3.selectAll(« #dec_mun circle.bubulle »).classed(« opacified », (d) => d.id !== result.data.c), 25);
const selectedCircle = document.querySelector(`#dec_mun circle.bubulle[data-insee= »${result.data.c} »]`);
if (selectedCircle) {
showTooltipManually(selectedCircle);
selectedCircle.scrollIntoView({ behavior: « smooth », block: « center » });
}
};
// Initialisation de l’autocomplete
if (langue == « fr ») {
autocomplete_decodeurs(« search_mun », listeComm, func_to_treat_result_donnees, reset_func, (x) => `${x.label.name}`, 6, 3, slugify, « Aucune commune avec ce nom »);
} else {
autocomplete_decodeurs(« search_mun », listeComm, func_to_treat_result_donnees, reset_func, (x) => `${x.label.name}`, 6, 3, slugify, « No town or city with that name »);
}
// quand on tape échap
document.addEventListener(« keydown », function (event) {
if (event.key === « Escape ») {
reset_func();
const circles = getA(« #dec_mun circle.bubulle »);
var selectedStatus = « tout »;
var selectedBloc = « tout »;
var selectedNuanceLM = « tout »;
forEach(circles, function (circle) {
circle.classList.remove(« selected-commune »);
});
d3.selectAll(« .tooltipbrt »).remove();
}
});
// Gestionnaire pour fermer le tooltip en cliquant ailleurs
document.addEventListener(« click », function (e) {
if (!e.target.closest(« #dec_mun circle ») && !e.target.closest(« #search_mun »)) {
const circles = getA(« #dec_mun circle.bubulle »);
forEach(circles, function (circle) {
circle.classList.remove(« selected-commune »);
});
}
});
}
);
}
// Fonction pour réinitialiser la carte
const reset_func = () => {
document.querySelector(« #search_mun input »).value = « »;
d3.selectAll(« #dec_mun circle.bubulle »).classed(« opacified », false);
d3.select(« #search_mun .lmui-search__button »).style(« visibility », « visible »);
d3.select(« #search_mun .lmui-search__reset-button »).style(« visibility », « hidden »);
// on remet à zéro les filtres
d3.selectAll(« .dec_nuance »).classed(« choisi », false);
d3.selectAll(« .dec_nuance.latotale »).classed(« choisi », true);
var selectedBloc = « tout »;
var selectedNuanceLM = « tout »;
};
dessinerBubulles(langue);
Les résultats des principaux partis et blocs politiques
Il vous reste 0% de cet article à lire. La suite est réservée aux abonnés.









