Site perso comparant causes de décès réelles (CépiDc/CIM-10) et positions des partis sur leurs facteurs de risque, en vue des présidentielles 2027. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BfMPw3qHuYEtf1msg2DhfE
116 lines
4.1 KiB
JavaScript
116 lines
4.1 KiB
JavaScript
async function loadJSON(name) {
|
|
const res = await fetch(`data/${name}`);
|
|
return res.json();
|
|
}
|
|
|
|
const STANCE_LABEL = { pour: 'Pour', contre: 'Contre', divise: 'Divisé' };
|
|
|
|
function buildCauseNode(cause, causes, partis, facteurById, causeFacteurs, positions) {
|
|
const children = causes.filter(c => c.parent_id === cause.id);
|
|
const details = document.createElement('details');
|
|
const summary = document.createElement('summary');
|
|
summary.textContent = `${cause.nom} (${cause.code_cim10})`;
|
|
details.appendChild(summary);
|
|
|
|
if (children.length) {
|
|
for (const child of children) {
|
|
details.appendChild(buildCauseNode(child, causes, partis, facteurById, causeFacteurs, positions));
|
|
}
|
|
} else {
|
|
details.appendChild(buildFacteurTable(cause.id, partis, facteurById, causeFacteurs, positions));
|
|
}
|
|
return details;
|
|
}
|
|
|
|
function buildFacteurTable(causeId, partis, facteurById, causeFacteurs, positions) {
|
|
const table = document.createElement('table');
|
|
const facteurIds = causeFacteurs[causeId] || [];
|
|
|
|
const thead = document.createElement('tr');
|
|
thead.innerHTML = '<th>Facteur de risque</th>' +
|
|
partis.map(p => `<th style="background:${p.couleur}44">${p.nom}</th>`).join('');
|
|
table.appendChild(thead);
|
|
|
|
for (const facteurId of facteurIds) {
|
|
const tr = document.createElement('tr');
|
|
const facteurCell = document.createElement('td');
|
|
facteurCell.textContent = facteurById[facteurId].nom;
|
|
tr.appendChild(facteurCell);
|
|
|
|
for (const parti of partis) {
|
|
const td = document.createElement('td');
|
|
td.style.background = `${parti.couleur}22`;
|
|
const pos = positions.find(p => p.cause_id === causeId && p.facteur_id === facteurId && p.parti_id === parti.id);
|
|
if (pos) {
|
|
td.classList.add('pos-cell');
|
|
td.innerHTML = `<span class="pill pill-${pos.stance}">${STANCE_LABEL[pos.stance]}</span>`;
|
|
td.addEventListener('click', () => showDetail(parti.nom, pos));
|
|
} else {
|
|
td.textContent = '—';
|
|
}
|
|
tr.appendChild(td);
|
|
}
|
|
table.appendChild(tr);
|
|
}
|
|
return table;
|
|
}
|
|
|
|
function buildFacteursTable(facteurs, causeFacteurs, causes) {
|
|
const byId = Object.fromEntries(causes.map(c => [c.id, c]));
|
|
const causesByFacteur = {};
|
|
for (const [causeId, facteurIds] of Object.entries(causeFacteurs)) {
|
|
for (const facteurId of facteurIds) {
|
|
(causesByFacteur[facteurId] ??= []).push(causeId);
|
|
}
|
|
}
|
|
|
|
const rows = facteurs
|
|
.map(f => ({ facteur: f, causeIds: causesByFacteur[f.id] || [] }))
|
|
.filter(r => r.causeIds.length > 1)
|
|
.sort((a, b) => b.causeIds.length - a.causeIds.length);
|
|
|
|
const table = document.getElementById('facteurs-table');
|
|
const thead = document.createElement('tr');
|
|
thead.innerHTML = '<th>Facteur de risque</th><th>Nb causes touchées</th><th>Causes concernées</th>';
|
|
table.appendChild(thead);
|
|
|
|
for (const row of rows) {
|
|
const tr = document.createElement('tr');
|
|
const names = row.causeIds.map(id => byId[id].nom).join(', ');
|
|
tr.innerHTML = `<td>${row.facteur.nom}</td><td>${row.causeIds.length}</td><td>${names}</td>`;
|
|
table.appendChild(tr);
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const [causes, partis, facteurs, causeFacteurs, positions] = await Promise.all([
|
|
loadJSON('causes.json'),
|
|
loadJSON('partis.json'),
|
|
loadJSON('facteurs.json'),
|
|
loadJSON('cause_facteurs.json'),
|
|
loadJSON('positions.json'),
|
|
]);
|
|
|
|
const facteurById = Object.fromEntries(facteurs.map(f => [f.id, f]));
|
|
const chapitres = causes
|
|
.filter(c => c.parent_id === null)
|
|
.sort((a, b) => (a.rang ?? 999) - (b.rang ?? 999));
|
|
|
|
const tree = document.getElementById('causes-tree');
|
|
for (const chapitre of chapitres) {
|
|
tree.appendChild(buildCauseNode(chapitre, causes, partis, facteurById, causeFacteurs, positions));
|
|
}
|
|
|
|
buildFacteursTable(facteurs, causeFacteurs, causes);
|
|
}
|
|
|
|
function showDetail(partiNom, pos) {
|
|
document.getElementById('detail-title').textContent = partiNom;
|
|
document.getElementById('detail-text').textContent = pos.position;
|
|
const source = document.getElementById('detail-source');
|
|
source.href = pos.source_url;
|
|
source.textContent = pos.source_url;
|
|
document.getElementById('detail').showModal();
|
|
}
|
|
|
|
main();
|