資料視覺敘事

時長對比條

時長對比 React 元件:兩到五條時長以同一比例尺、同一速度生長,例如 30 分鐘對六週;單位自動換算成「30 分鐘」「6 週」,讀數隨條寬同步計數,長完後浮出「快 2016 倍」或「省下 99.9%」徽章,差距極大時以斷軸保留最短條。

講「省下多少時間」最直接的畫法:把兩到五條時長排成水平條,用同一把比例尺、同一個速度一起生長——短的那條一下就長完,長的那條讓你多等一會兒,等待感本身就是重點。輸入可以是分鐘數,或帶單位(分鐘/小時/天/週/月)的值,顯示時自動換算成最合適的單位;右側讀數跟著條寬從 0 計數到真值,全部長完後浮出倍數徽章。差距極端時(30 分鐘對 6 週是 2016 倍),預設的斷軸比例尺會在長條中間切一段 zigzag,保證最短條仍看得見。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add duration-compare-bars

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 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型別預設值說明
itemsDurationCompareItem[]—要比較的時長(建議 2–5 條),由上而下垂直排列
scale"linear" | "log" | "broken""broken"比例尺;broken 在差距極大時於長條中間斷軸,保證最短條仍看得見
minWidthnumber6最短條的最小寬度(百分比),用於 broken 與 log 比例尺
msPerPercentnumber18每 1% 寬度的生長時間(毫秒);所有條同速生長,長條自然長得更久
maxGrownumber2400單條生長時間上限(毫秒)
ratio"times" | "percent" | "none""times"全部長完後浮出的徽章格式:「快 2016 倍」、「省下 99.9%」或不顯示
locale"zh-TW" | "en""zh-TW"單位字語系:「30 分鐘」或「30 minutes」
trigger"inView" | "mount""inView"動畫觸發時機:進入視窗或掛載後立即開始
onComplete() => void—全部條長完(徽章浮出)時回呼
classNamestring—透傳到最外層容器

DurationCompareItem

欄位型別預設值說明
idstring—唯一識別,用於 React key
labelstring—左側標籤,例如「傳統流程」
valuenumber—時長數值,單位由 unit 決定
unit"min" | "h" | "d" | "w" | "mo""min"value 的單位;一個月以 30 天計
colorstring—自訂條色;未提供時最短那條用強調色、其餘用灰色

另外具名匯出 formatDuration(minutes, locale),可在其他地方沿用同一套單位換算。

CSS 變數

變數預設值說明
--wb-duration-compare-slow#a3a3a3較長那幾條的顏色
--wb-duration-compare-fast#22c55e最短那條與倍數徽章的強調色
--wb-duration-compare-badge-duration260ms倍數徽章彈出的時長

細節

  • 同速生長:每條的動畫時間 = 最終寬度 × 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 關聯
  • 數值讀數與顏色並用,不只靠顏色區分快慢
  • 使用者系統開啟「減少動態效果」時,條寬與數字直接到終值,倍數徽章直接顯示