|
255 | 255 | refs.gpuModel = metricRow(g, "model", "gpu-model", ""); |
256 | 256 | refs.gpuUsage = metricRow(g, "usage", "gpu-usage", "%"); |
257 | 257 | refs.gpuTemp = metricRow(g, "temp", "gpu-temp", "°C"); |
| 258 | + refs.gpuFreq = metricRow(g, "freq", "gpu-freq", "MHz"); |
258 | 259 | // GPU 使用率历史图 |
259 | 260 | const gchart = el("div"); gchart.id = "gpu-chart"; gchart.style.cssText = "height:160px;margin-top:12px"; |
260 | 261 | g.appendChild(gchart); |
|
266 | 267 | refs.gpuPowerLimit = metricRow(gm, "powerLimit", "gpu-powerlimit", "W"); |
267 | 268 | grid.appendChild(gm); |
268 | 269 | sec.appendChild(grid); |
| 270 | + // 左下角说明:很多信息无法获取的原因 |
| 271 | + refs.gpuHint = el("div", "mt-4 text-[13px] leading-relaxed text-[var(--color-faint)] rounded-xl " |
| 272 | + + "bg-[var(--color-hover)] px-4 py-3"); |
| 273 | + refs.gpuHint.innerHTML = `💡 ${t("gpuHint", "为什么很多信息无法获取?部分硬件数据依赖底层命令或驱动:")}<br>` |
| 274 | + + `<span class="text-[var(--color-subtle)]">• ${t("gpuHintIntel", "Intel 核显使用率/频率/功耗:需 root 权限并安装 intel-gpu-tools(intel_gpu_top),请用 sudo 运行本程序")}</span><br>` |
| 275 | + + `<span class="text-[var(--color-subtle)]">• ${t("gpuHintNvidia", "NVIDIA 显存/温度/功耗:需安装 nvidia-ml-py(NVML)")}</span><br>` |
| 276 | + + `<span class="text-[var(--color-subtle)]">• ${t("gpuHintReadme", "更多权限与依赖说明请对照 README「Linux 权限说明」章节")}</span>`; |
| 277 | + sec.appendChild(refs.gpuHint); |
269 | 278 | refs.gpuEmpty = el("div", "text-[var(--color-faint)] text-[14px]"); |
270 | 279 | refs.gpuEmpty.textContent = t("noGpu", "未检测到可用的独立显卡(或驱动未安装)"); |
271 | 280 | } |
|
642 | 651 | refs.gpuUsage.textContent = last.length ? Number(last[last.length - 1][1]).toFixed(1) : "—"; |
643 | 652 | } |
644 | 653 | refs.gpuTemp.textContent = det.temperature != null ? det.temperature : "—"; |
| 654 | + // 频率:优先硬件详情静态值,否则回退到实时 Intel 详情 |
| 655 | + const intelDet = (snap.real_time_data || {}).gpu_intel_details; |
| 656 | + if (det.frequency != null) { |
| 657 | + refs.gpuFreq.textContent = det.frequency; |
| 658 | + } else if (intelDet && intelDet.frequency != null) { |
| 659 | + refs.gpuFreq.textContent = intelDet.frequency; |
| 660 | + } else { |
| 661 | + refs.gpuFreq.textContent = "—"; |
| 662 | + } |
645 | 663 | refs.gpuMemTotal.textContent = det.memory_total != null ? det.memory_total : "—"; |
646 | 664 | refs.gpuMemUsed.textContent = det.memory_used != null ? det.memory_used : "—"; |
647 | 665 | refs.gpuPower.textContent = det.power_draw != null ? det.power_draw : "—"; |
|
661 | 679 | refs.gpuModel = metricRow(g, "model", "gpu-model", ""); |
662 | 680 | refs.gpuUsage = metricRow(g, "usage", "gpu-usage", "%"); |
663 | 681 | refs.gpuTemp = metricRow(g, "temp", "gpu-temp", "°C"); |
| 682 | + refs.gpuFreq = metricRow(g, "freq", "gpu-freq", "MHz"); |
664 | 683 | const gchart = el("div"); gchart.id = "gpu-chart"; gchart.style.cssText = "height:160px;margin-top:12px"; |
665 | 684 | g.appendChild(gchart); |
666 | 685 | grid.appendChild(g); |
|
671 | 690 | refs.gpuPowerLimit = metricRow(gm, "powerLimit", "gpu-powerlimit", "W"); |
672 | 691 | grid.appendChild(gm); |
673 | 692 | sec.appendChild(grid); |
| 693 | + if (refs.gpuHint) sec.appendChild(refs.gpuHint); |
674 | 694 | } |
675 | 695 |
|
676 | 696 | function updateNetwork(snap) { |
|
0 commit comments