(ctx, w, h)
| 22 | } |
| 23 | |
| 24 | function paint(ctx, w, h) { |
| 25 | // Cream paper background + vignette. |
| 26 | ctx.fillStyle = theme.widget_base; |
| 27 | ctx.fillRect(0, 0, w, h); |
| 28 | |
| 29 | // Header strip. |
| 30 | ctx.fillStyle = theme.widget_text; |
| 31 | ctx.font = "bold 11px sans-serif"; |
| 32 | ctx.textAlign = "start"; |
| 33 | ctx.fillText("STRIP CHART", 14, 18); |
| 34 | ctx.fillStyle = theme.placeholder_text; |
| 35 | ctx.font = "10px sans-serif"; |
| 36 | ctx.textAlign = "end"; |
| 37 | ctx.fillText(datasets.length + " channels", w - 14, 18); |
| 38 | ctx.fillStyle = theme.widget_border; |
| 39 | ctx.fillRect(14, 22, w - 28, 1); |
| 40 | |
| 41 | // Plot card. |
| 42 | const padL = 50; |
| 43 | const padR = 14; |
| 44 | const padT = 32; |
| 45 | const padB = 38; |
| 46 | const plotX = padL; |
| 47 | const plotY = padT; |
| 48 | const plotW = w - padL - padR; |
| 49 | const plotH = h - padT - padB; |
| 50 | |
| 51 | ctx.fillStyle = theme.widget_border; |
| 52 | ctx.fillRect(plotX + 1, plotY + 2, plotW, plotH); |
| 53 | ctx.fillStyle = theme.alternate_base; |
| 54 | ctx.fillRect(plotX, plotY, plotW, plotH); |
| 55 | ctx.strokeStyle = theme.widget_border; |
| 56 | ctx.lineWidth = 1; |
| 57 | ctx.strokeRect(plotX + 0.5, plotY + 0.5, plotW - 1, plotH - 1); |
| 58 | |
| 59 | if (datasets.length === 0) return; |
| 60 | |
| 61 | // Unified Y range across every dataset. |
| 62 | let lo = Number.POSITIVE_INFINITY; |
| 63 | let hi = Number.NEGATIVE_INFINITY; |
| 64 | for (let i = 0; i < datasets.length; ++i) { |
| 65 | lo = Math.min(lo, datasets[i].min); |
| 66 | hi = Math.max(hi, datasets[i].max); |
| 67 | } |
| 68 | if (!Number.isFinite(lo) || !Number.isFinite(hi) || hi <= lo) { |
| 69 | lo = 0; |
| 70 | hi = 100; |
| 71 | } |
| 72 | const span = hi - lo; |
| 73 | |
| 74 | // Horizontal grid lines + Y labels. |
| 75 | ctx.strokeStyle = theme.widget_border; |
| 76 | ctx.fillStyle = theme.placeholder_text; |
| 77 | ctx.font = "9px sans-serif"; |
| 78 | ctx.textBaseline = "middle"; |
| 79 | ctx.textAlign = "right"; |
| 80 | for (let i = 0; i <= 4; ++i) { |
| 81 | const y = plotY + (plotH / 4) * i; |
nothing calls this directly
no test coverage detected