-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
128 lines (120 loc) · 5.4 KB
/
Copy pathscript.js
File metadata and controls
128 lines (120 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* script.js: fetch data and render charts using Chart.js */
const repoRoot = '';
async function loadJSON(path){
try{
const res = await fetch(path);
if(!res.ok) throw new Error('Network error');
return await res.json();
}catch(e){
console.warn('Could not load', path, e);
return null;
}
}
function setYear(){
const y = new Date().getFullYear();
const el = document.getElementById('year'); if(el) el.textContent = y;
}
function safeNumber(v,dec=0){return typeof v==='number'? v.toFixed(dec):'—'}
async function renderIndex(){
const indicators = await loadJSON('global-indicators.json');
const regional = await loadJSON(repoRoot+'data/regional-comparison.json');
if(indicators){
const trauma = document.getElementById('global-trauma');
const divi = document.getElementById('global-diversity');
const acc = document.getElementById('global-acceptance');
if(trauma) trauma.textContent = safeNumber(indicators.global_trauma_rate);
if(divi) divi.textContent = indicators.global_diversity_index ? indicators.global_diversity_index.toFixed(2) : '—';
if(acc) acc.textContent = indicators.average_acceptance_score ? indicators.average_acceptance_score.toFixed(0) : '—';
}
if(regional){
const labels = regional.regions.map(r=>r.name);
const data = regional.regions.map(r=>r.trauma_rate);
const ctx = document.getElementById('regionBarChart');
if(ctx){
new Chart(ctx.getContext('2d'),{
type:'bar',
data:{labels, datasets:[{label:'Trauma rate (per 100k)',data,backgroundColor:'#0b3d91'}]},
options:{responsive:true,plugins:{legend:{display:false}}}
});
}
}
}
async function renderTrauma(){
const trauma = await loadJSON('trauma-rates.json');
if(trauma && trauma.regions){
const labels = trauma.regions.map(r=>r.name);
const data = trauma.regions.map(r=>r.trauma_rate);
const bar = document.getElementById('traumaBar');
if(bar){
new Chart(bar.getContext('2d'),{type:'bar',data:{labels,datasets:[{label:'Trauma rate',data,backgroundColor:'#0b3d91'}]}});
}
}
// severity pie
if(trauma && trauma.severity_distribution){
const pie = document.getElementById('severityPie');
const keys = Object.keys(trauma.severity_distribution);
const vals = keys.map(k=>trauma.severity_distribution[k]);
if(pie){
new Chart(pie.getContext('2d'),{type:'pie',data:{labels:keys,datasets:[{data:vals,backgroundColor:['#0b3d91','#2a6fbf','#7aa7e9']}]}});
}
}
}
async function renderDiversity(){
const div = await loadJSON('diversity-index.json');
if(div && div.regions){
const labels = div.regions.map(r=>r.name);
const data = div.regions.map(r=>r.acceptance_score);
const ctx = document.getElementById('diversityBar');
if(ctx){
new Chart(ctx.getContext('2d'),{type:'bar',data:{labels,datasets:[{label:'Acceptance score',data,backgroundColor:'#0b3d91'}]},options:{scales:{y:{beginAtZero:true}}}});
}
}
}
async function renderAnalytics(){
const regional = await loadJSON(repoRoot+'data/regional-comparison.json');
if(regional){
const labels = regional.regions.map(r=>r.name);
const traumaData = regional.regions.map(r=>r.trauma_rate);
const divData = regional.regions.map(r=>r.diversity_index);
const grouped = document.getElementById('groupedChart');
if(grouped){
new Chart(grouped.getContext('2d'),{type:'bar',data:{labels,datasets:[{label:'Trauma rate',data:traumaData,yAxisID:'A',backgroundColor:'#0b3d91'},{label:'Diversity index',data:divData,yAxisID:'B',backgroundColor:'#7aa7e9'}]},options:{responsive:true,scales:{A:{type:'linear',position:'left'},B:{type:'linear',position:'right',ticks:{beginAtZero:true}}}}});
}
// acceptance trend line uses first region's trend as example
const acceptanceLine = document.getElementById('acceptanceLine');
if(acceptanceLine){
const years = regional.years || ['2018','2019','2020','2021','2022','2023','2024','2025'];
// aggregate mean acceptance per year
const series = years.map((y,idx)=>{
const vals = regional.regions.map(r=>(r.acceptance_trend? r.acceptance_trend[idx]: null)).filter(v=>v!=null);
if(vals.length===0) return null;
return vals.reduce((a,b)=>a+b,0)/vals.length;
});
new Chart(acceptanceLine.getContext('2d'),{type:'line',data:{labels:years,datasets:[{label:'Average acceptance',data:series,fill:false,borderColor:'#0b3d91'}]}});
}
}
}
async function renderGlobalMiniCharts(){
const regional = await loadJSON(repoRoot+'data/regional-comparison.json');
if(!regional) return;
const canvases = document.querySelectorAll('.mini-chart');
canvases.forEach(c=>{
const regionName = c.dataset.region;
const r = regional.regions.find(rr=>rr.name.toLowerCase()===regionName.toLowerCase());
const ctx = c.getContext('2d');
if(r){
new Chart(ctx,{type:'bar',data:{labels:['Trauma rate','Acceptance'],datasets:[{label:regionName,data:[r.trauma_rate,r.acceptance_score],backgroundColor:['#0b3d91','#7aa7e9']}]},options:{responsive:true,plugins:{legend:{display:false}}}});
} else {
new Chart(ctx,{type:'bar',data:{labels:['Trauma rate'],datasets:[{label:regionName,data:[0],backgroundColor:'#d3dce6'}]},options:{plugins:{legend:{display:false}}}});
}
});
}
// boot
document.addEventListener('DOMContentLoaded',()=>{
setYear();
renderIndex();
renderTrauma();
renderDiversity();
renderAnalytics();
renderGlobalMiniCharts();
});