資料視覺敘事
時長對比條
時長對比 React 元件:兩到五條時長以同一比例尺、同一速度生長,例如 30 分鐘對六週;單位自動換算成「30 分鐘」「6 週」,讀數隨條寬同步計數,長完後浮出「快 2016 倍」或「省下 99.9%」徽章,差距極大時以斷軸保留最短條。
講「省下多少時間」最直接的畫法:把兩到五條時長排成水平條,用同一把比例尺、同一個速度一起生長——短的那條一下就長完,長的那條讓你多等一會兒,等待感本身就是重點。輸入可以是分鐘數,或帶單位(分鐘/小時/天/週/月)的值,顯示時自動換算成最合適的單位;右側讀數跟著條寬從 0 計數到真值,全部長完後浮出倍數徽章。差距極端時(30 分鐘對 6 週是 2016 倍),預設的斷軸比例尺會在長條中間切一段 zigzag,保證最短條仍看得見。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add duration-compare-barsPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
18
6
編輯中的呼叫預設屬性
<DurationCompareBars/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/duration-compare-bars.json或在 components.json 設定 registries 後,改用 @webberui/duration-compare-bars 安裝。
使用
import { DurationCompareBars } from "@/components/ui/duration-compare-bars";
<DurationCompareBars
items={[
{ id: "legacy", label: "傳統流程", value: 6, unit: "w" },
{ id: "ours", label: "用我們", value: 30 },
]}
/>
// 三條比較、對數比例尺、徽章顯示節省百分比
<DurationCompareBars
scale="log"
ratio="percent"
items={[
{ id: "manual", label: "人工對帳", value: 2, unit: "d" },
{ id: "semi", label: "半自動", value: 3, unit: "h" },
{ id: "auto", label: "全自動", value: 5 },
]}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
items | DurationCompareItem[] | — | 要比較的時長(建議 2–5 條),由上而下垂直排列 |
scale | "linear" | "log" | "broken" | "broken" | 比例尺;broken 在差距極大時於長條中間斷軸,保證最短條仍看得見 |
minWidth | number | 6 | 最短條的最小寬度(百分比),用於 broken 與 log 比例尺 |
msPerPercent | number | 18 | 每 1% 寬度的生長時間(毫秒);所有條同速生長,長條自然長得更久 |
maxGrow | number | 2400 | 單條生長時間上限(毫秒) |
ratio | "times" | "percent" | "none" | "times" | 全部長完後浮出的徽章格式:「快 2016 倍」、「省下 99.9%」或不顯示 |
locale | "zh-TW" | "en" | "zh-TW" | 單位字語系:「30 分鐘」或「30 minutes」 |
trigger | "inView" | "mount" | "inView" | 動畫觸發時機:進入視窗或掛載後立即開始 |
onComplete | () => void | — | 全部條長完(徽章浮出)時回呼 |
className | string | — | 透傳到最外層容器 |
DurationCompareItem
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 唯一識別,用於 React key |
label | string | — | 左側標籤,例如「傳統流程」 |
value | number | — | 時長數值,單位由 unit 決定 |
unit | "min" | "h" | "d" | "w" | "mo" | "min" | value 的單位;一個月以 30 天計 |
color | string | — | 自訂條色;未提供時最短那條用強調色、其餘用灰色 |
另外具名匯出 formatDuration(minutes, locale),可在其他地方沿用同一套單位換算。
CSS 變數
| 變數 | 預設值 | 說明 |
|---|---|---|
--wb-duration-compare-slow | #a3a3a3 | 較長那幾條的顏色 |
--wb-duration-compare-fast | #22c55e | 最短那條與倍數徽章的強調色 |
--wb-duration-compare-badge-duration | 260ms | 倍數徽章彈出的時長 |
細節
- 同速生長:每條的動畫時間 = 最終寬度 ×
msPerPercent,上限maxGrow;前 80% 等速、最後一段 ease-out 收尾。長條長得比較久,正是要傳達的「等待感」。 - 單位換算:由大到小挑第一個「≥ 1 且為 0.5 倍數」的單位,所以 6 週顯示「6 週」而不是「1.4 個月」、90 分鐘顯示「1.5 小時」。計數過程中單位會依序經過分鐘、小時、天,但不會超過終值的單位。
- 斷軸的誠實性:broken 只在線性寬度會讓最短條小於
minWidth時才啟用。斷軸前的條按比例畫,跨過斷軸的條只保證順序與最長 = 100%,寬度不再與數值成正比——因此每條右側的讀數與aria-label永遠是真值,斷軸處的 zigzag 與「…」明示這裡省略了一段。需要嚴格按比例時改用scale="linear"。 - 倍數與百分比:倍數 = 最長 ÷ 最短,10 倍以上取整數;節省百分比無條件捨去到一位小數,避免 99.95% 被四捨五入成 100%。
可及性
- 條列以
role="list"呈現,每條的aria-label為「標籤:時長」(例如「傳統流程:6 週」),計數中的動態數字對輔助科技隱藏 - 圖表下方有一句僅供螢幕閱讀器的摘要(例如「用我們只需 30 分鐘,比傳統流程快 2016 倍。」),並以
aria-describedby關聯 - 數值讀數與顏色並用,不只靠顏色區分快慢
- 使用者系統開啟「減少動態效果」時,條寬與數字直接到終值,倍數徽章直接顯示