()
| 2399 | let lo = Math.min(...edges), hi = Math.max(...edges); |
| 2400 | if (b === '2.4') { lo = Math.min(lo, 1); hi = Math.max(hi, 13); } |
| 2401 | const padCh = b === '2.4' ? 0.5 : 2; |
| 2402 | lo -= padCh; hi += padCh; if (hi - lo < 4) { hi += 2; lo -= 2; } |
| 2403 | const x0 = padL + i * (segW + gap); |
| 2404 | ranges[b] = { lo, hi, x0, x1: x0 + segW }; |
| 2405 | }); |
| 2406 | const xFor = (band, ch) => { const r = ranges[band]; return r.x0 + (ch - r.lo) / (r.hi - r.lo) * (r.x1 - r.x0); }; |
| 2407 | const chFor = (band, x) => { const r = ranges[band]; return r.lo + (x - r.x0) / (r.x1 - r.x0) * (r.hi - r.lo); }; |
| 2408 | // Band labels + channel ticks + DFS shading |
| 2409 | ctx.textAlign = 'center'; |
| 2410 | bands.forEach(b => { |
| 2411 | const r = ranges[b]; |
| 2412 | ctx.fillStyle = _WIFI_BAND_COLOR[b]; ctx.font = `bold ${11 * K}px sans-serif`; |
| 2413 | ctx.fillText(b + ' GHz', (r.x0 + r.x1) / 2, padT - 4); |
| 2414 | // DFS channel shading |
| 2415 | (d.radar_channels[b] || []).forEach(ch => { |
| 2416 | if (ch < r.lo || ch > r.hi) return; |
| 2417 | const cx = xFor(b, ch); |
| 2418 | ctx.fillStyle = 'rgba(167,139,250,0.08)'; |
| 2419 | ctx.fillRect(cx - 3 * K, padT, 6 * K, plotH); |
no test coverage detected