histogram.ts (1063B)
1 import type { HistBin } from '../data'; 2 3 export function renderHistogram(bins: HistBin[], width = 600, height = 200): string { 4 const maxCount = Math.max(...bins.map(b => b.count), 1); 5 const barW = (width - 60) / bins.length; 6 const chartH = height - 40; 7 8 let bars = ''; 9 for (let i = 0; i < bins.length; i++) { 10 const b = bins[i]; 11 const barH = (b.count / maxCount) * chartH; 12 const x = 50 + i * barW; 13 const y = chartH - barH + 10; 14 const color = b.lo < 30 ? '#f06565' : b.lo < 50 ? '#f0c050' : b.lo < 70 ? '#6c8cff' : '#3dd68c'; 15 bars += `<rect class="bar" x="${x}" y="${y}" width="${barW - 1}" height="${barH}" fill="${color}" rx="2"> 16 <title>${b.lo}-${b.hi}%: ${b.count} papers</title></rect>`; 17 } 18 19 // X-axis labels 20 let labels = ''; 21 for (let i = 0; i < bins.length; i += 4) { 22 labels += `<text x="${50 + i * barW + barW / 2}" y="${chartH + 28}" text-anchor="middle">${bins[i].lo}%</text>`; 23 } 24 25 return `<svg viewBox="0 0 ${width} ${height}" style="width:100%;max-width:${width}px"> 26 ${bars}${labels} 27 </svg>`; 28 }