(type, value)
| 267 | return `<span class="caps-traffic duo ${heavy ? 'heavy' : 'normal'}${small ? ' sm' : ''}" title="本月下行 | 上行"><span class="half in">${humanMinMBFromB(m.monthIn)}</span><span class="half out">${humanMinMBFromB(m.monthOut)}</span></span>`; |
| 268 | } |
| 269 | function gaugeHTML(type, value){ |
| 270 | const pct = clamp(num(value), 0, 100); |
| 271 | const thresholds = { |
| 272 | cpu: { warn: 75, bad: 90 }, |
| 273 | mem: { warn: 80, bad: 90 }, |
| 274 | hdd: { warn: 85, bad: 90 } |
| 275 | }[type] || { warn: 75, bad: 90 }; |
| 276 | const warnAttr = pct >= thresholds.bad ? 'data-bad' : (pct >= thresholds.warn ? 'data-warn' : ''); |
| 277 | const label = type === 'cpu' ? 'CPU' : type === 'mem' ? '内存' : '硬盘'; |
| 278 | return `<div class="gauge-half" data-type="${type}" ${warnAttr} style="--p:${(pct / 100).toFixed(3)}" title="${label} ${pct.toFixed(0)}%"> |
| 279 | <svg viewBox="0 0 100 50" preserveAspectRatio="xMidYMid meet" aria-hidden="true"><path class="track" d="M10 50 A40 40 0 0 1 90 50" /><path class="arc" d="M10 50 A40 40 0 0 1 90 50" /></svg> |
| 280 | <span>${pct.toFixed(0)}%</span> |
| 281 | </div>`; |
| 282 | } |
| 283 | function resourceMeter(label, value, pct, kind){ |
| 284 | const safePct = clamp(num(pct), 0, 100); |
| 285 | const thresholds = { |
no test coverage detected