| 5 | // rotor diagnostics. Each pair becomes one ray with a coloured tip. |
| 6 | |
| 7 | function paint(ctx, w, h) { |
| 8 | // Cream paper background + vignette. |
| 9 | ctx.fillStyle = theme.widget_base; |
| 10 | ctx.fillRect(0, 0, w, h); |
| 11 | |
| 12 | const pairs = Math.floor(datasets.length / 2); |
| 13 | |
| 14 | // Header. |
| 15 | ctx.fillStyle = theme.widget_text; |
| 16 | ctx.font = "bold 11px sans-serif"; |
| 17 | ctx.textAlign = "start"; |
| 18 | ctx.fillText("POLAR PLOT", 14, 18); |
| 19 | ctx.fillStyle = theme.placeholder_text; |
| 20 | ctx.font = "10px sans-serif"; |
| 21 | ctx.textAlign = "end"; |
| 22 | ctx.fillText(pairs + (pairs === 1 ? " ray" : " rays"), w - 14, 18); |
| 23 | ctx.fillStyle = theme.widget_border; |
| 24 | ctx.fillRect(14, 22, w - 28, 1); |
| 25 | |
| 26 | // Card containing the dial. |
| 27 | const padX = 14; |
| 28 | const padTop = 30; |
| 29 | const padBot = 14; |
| 30 | const cardX = padX; |
| 31 | const cardY = padTop; |
| 32 | const cardW = w - padX * 2; |
| 33 | const cardH = h - padTop - padBot; |
| 34 | |
| 35 | ctx.fillStyle = theme.widget_border; |
| 36 | ctx.fillRect(cardX + 1, cardY + 2, cardW, cardH); |
| 37 | ctx.fillStyle = theme.alternate_base; |
| 38 | ctx.fillRect(cardX, cardY, cardW, cardH); |
| 39 | ctx.strokeStyle = theme.widget_border; |
| 40 | ctx.lineWidth = 1; |
| 41 | ctx.strokeRect(cardX + 0.5, cardY + 0.5, cardW - 1, cardH - 1); |
| 42 | |
| 43 | const cx = cardX + cardW * 0.5; |
| 44 | const cy = cardY + cardH * 0.5; |
| 45 | const r = Math.max(20, Math.min(cardW, cardH) * 0.42); |
| 46 | |
| 47 | // Concentric range rings. |
| 48 | ctx.strokeStyle = theme.widget_border; |
| 49 | ctx.lineWidth = 1; |
| 50 | for (let i = 1; i <= 4; ++i) { |
| 51 | const rr = (r / 4) * i; |
| 52 | ctx.beginPath(); |
| 53 | ctx.moveTo(cx + rr, cy); |
| 54 | ctx.arc(cx, cy, rr, 0, Math.PI * 2); |
| 55 | ctx.stroke(); |
| 56 | } |
| 57 | |
| 58 | // Cardinal cross. |
| 59 | ctx.strokeStyle = theme.widget_border; |
| 60 | ctx.beginPath(); |
| 61 | ctx.moveTo(cx - r, cy); |
| 62 | ctx.lineTo(cx + r, cy); |
| 63 | ctx.moveTo(cx, cy - r); |
| 64 | ctx.lineTo(cx, cy + r); |