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 = 'Facteur de risque' + partis.map(p => `${p.nom}`).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 = `${STANCE_LABEL[pos.stance]}`; 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 = 'Facteur de risqueNb causes touchéesCauses concernées'; 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 = `${row.facteur.nom}${row.causeIds.length}${names}`; 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();