儀表盤
指針儀表盤:spring 擺動指針、分段色弧、數值滾動。
SVG 半圓儀表盤,指針以低阻尼 spring 轉到目標值、帶過衝回穩的擺動感;分段色弧(綠黃紅可自訂 stops)搭配刻度線,中央數值與指針共用同一條 spring 同步滾動,指針尚未到達的色段會降低透明度。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add gauge-meterGauge Meter 是用 React、SVG 與 Motion 的 useSpring 做的指針儀表盤(gauge chart、速度錶、半圓儀表)元件:半圓分段色弧加上刻度,指針以帶過衝的彈簧擺到目標值,中央數字同步滾動,下方顯示目前所在色段的狀態文字。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<GaugeMeter/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
適用情境
- 系統監控儀表板的 CPU、記憶體、磁碟使用率
- 網站效能或 SEO 健康度分數
- IoT 裝置的溫度、濕度、壓力讀數
- 業績達成率、客戶滿意度這類有「良好/注意/警戒」區間的指標
- 不適合:只需要單純百分比進度、不需要刻度與指針時,Circular Progress 更簡潔
安裝
npx webberui@latest add https://webberui.com/r/gauge-meter.json或在 components.json 設定 registries 後,改用 @webberui/gauge-meter 安裝。
使用
import { GaugeMeter } from "@/components/ui/gauge-meter";
<GaugeMeter
value={72}
unit="%"
label="CPU 使用率"
stops={[
{ to: 60, color: "#10b981", label: "順暢" },
{ to: 85, color: "#f59e0b", label: "偏高" },
{ to: 100, color: "#ef4444", label: "過載" },
]}
/>範例
輪詢 API 即時更新
value 每次改變,指針都會從目前位置彈到新值,適合接上定時輪詢的監控資料。
"use client";
import * as React from "react";
import { GaugeMeter } from "@/components/ui/gauge-meter";
export function MemoryGauge() {
const [usage, setUsage] = React.useState(0);
React.useEffect(() => {
const load = () =>
fetch("/api/metrics/memory")
.then((r) => r.json())
.then((d: { percent: number }) => setUsage(d.percent));
load();
const id = setInterval(load, 5000);
return () => clearInterval(id);
}, []);
return <GaugeMeter value={usage} unit="%" label="記憶體使用率" decimals={1} />;
}自訂範圍與色段
min、max 不必是 0 到 100。stops 依 to 排序,每段的 label 會在指針落入該段時顯示。從元件匯出的 GaugeStop 型別可以用來宣告設定。
import { GaugeMeter, type GaugeStop } from "@/components/ui/gauge-meter";
const tempStops: GaugeStop[] = [
{ to: 18, color: "#3b82f6", label: "偏冷" },
{ to: 26, color: "#10b981", label: "舒適" },
{ to: 40, color: "#ef4444", label: "過熱" },
];
<GaugeMeter value={23.5} min={0} max={40} stops={tempStops} unit="°C" label="機房溫度" decimals={1} />多個儀表並排
size 控制寬度,高度依 200:148 比例縮放,適合在格狀版面裡排成一列。
<div className="grid grid-cols-3 gap-6">
<GaugeMeter size={180} value={42} unit="%" label="CPU" />
<GaugeMeter size={180} value={68} unit="%" label="記憶體" />
<GaugeMeter size={180} value={91} unit="%" label="磁碟" />
</div>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
value | number | — | 目標值,變更時指針以 spring 擺動過去(帶過衝回穩) |
min | number | 0 | 量表最小值 |
max | number | 100 | 量表最大值 |
stops | GaugeStop[] | 綠黃紅預設 | 分段色弧設定,每段為 { to, color, label? },未提供時使用 60% / 85% / 100% 的綠黃紅 |
unit | string | — | 數值後方的單位文字,例如 "%"、"km/h" |
label | string | — | 儀表標題,顯示於儀表下方 |
size | number | 240 | 儀表寬度(px),高度依 200:148 比例自動縮放 |
decimals | number | 0 | 中央數值顯示的小數位數 |
className | string | — | 透傳到外層容器 |
GaugeStop:to 為此色段的結束值(各段需遞增,最後一段建議等於 max)、color 為任何合法 CSS 顏色、label 為當前值落在此段時顯示的狀態文字。
可及性
- 容器使用
role="meter"搭配aria-valuemin/aria-valuemax/aria-valuenow與aria-valuetext,輔助科技朗讀的是目標值而非動畫中間值 - SVG 本體標記
aria-hidden,避免與 meter 語意重複朗讀 - 使用者系統開啟「減少動態效果」時,指針與數字直接跳至目標值,不播放 spring 擺動
- 數值使用
tabular-nums等寬數字,滾動時版面不抖動
常見問題
可以在 Next.js App Router 使用嗎?
可以。原始碼已經有 "use client",在 Server Component 頁面直接 import 即可。伺服器端與首次渲染時指針停在 min,掛載後才彈到目標值。
超出 min/max 的值會怎樣?
value 會被夾在 min 到 max 之間。指針在彈簧過衝時可以稍微超出兩端(約 4%),中央數字則始終鎖在範圍內。
沒有傳 stops 時,色段怎麼分?
預設是綠、黃、紅三段,分界在範圍的 60% 與 85%,狀態文字分別是「良好」、「注意」、「警戒」。
可以讓寬度跟著容器變化嗎?
size 是以 px 寫在外層的 inline width,SVG 本身是 w-full。需要流動寬度時,可以在原始碼裡把 style={{ width: size }} 改成你要的寬度設定。
螢幕閱讀器讀到的是什麼?
外層是 role="meter",帶有 aria-valuemin、aria-valuemax、aria-valuenow 與 aria-valuetext,讀的是目標值而非動畫中的數字;沒有 label 時 aria-label 預設為「儀表」。依賴是 motion、clsx、tailwind-merge。