Theme / v2.15.0

UI UX Pro Max

把模糊需求變成可實作、可驗收的介面

實戰範例

實戰範例 002:建立可探索的營運資料儀表板

從使用者問題、篩選器狀態和圖表選型開始,逐步做出能比較、定位與追查資料的互動儀表板。

建立可探索的營運資料儀表板

專案情境

產品經理想知道:「本週哪個方案的啟用率下降最多?」這個問題決定了頁面需要時間範圍、方案篩選、比較值和明細,而不是任意放上幾種圖表。

1. 先定義查詢狀態

type DashboardQuery = {
  range: '7d' | '30d' | '90d';
  plans: string[];
};

const defaultQuery: DashboardQuery = {
  range: '7d',
  plans: [],
};

把查詢狀態放在 URL,使用者才能複製連結分享目前視圖:

const params = new URLSearchParams({ range: query.range });
query.plans.forEach((plan) => params.append('plan', plan));
history.replaceState(null, '', `?${params}`);

實際專案要同時處理瀏覽器返回、無效參數和沒有任何方案的狀態。

2. 依問題選擇圖表

使用者問題 主視覺 輔助內容
哪個方案下降最多? 排序橫條圖 變化率表格
下降從何時開始? 折線圖 日期範圍
哪些客戶受影響? 表格 分頁與匯出

圖表提供趨勢,表格提供精確值。不要讓 tooltip 成為取得數字的唯一方式。

3. 處理更新中的畫面

function Results({ state }) {
  if (state.status === 'loading' && !state.data) return <DashboardSkeleton />;
  if (state.status === 'error') {
    return <RetryPanel onRetry={state.retry}>資料載入失敗</RetryPanel>;
  }
  if (state.data?.length === 0) {
    return <EmptyState action="清除篩選">沒有符合條件的資料</EmptyState>;
  }
  return <ChartAndTable data={state.data} />;
}

已有資料時重新查詢,不要整頁換成空白 skeleton;保留舊結果並在篩選器旁顯示「更新中」,能降低跳動和不確定感。

4. 寫出文字摘要

本週「專業版」啟用率下降 8.4%,是所有方案中降幅最大者。
點擊方案名稱可查看受影響客戶。

這段摘要同時服務無法看圖表的使用者,也幫助所有人快速理解頁面結論。

驗收

  • 篩選條件顯示在畫面上且可由 URL 恢復。
  • 查詢期間保留上下文,不會把焦點移回頁面頂端。
  • 圖表和表格的數字、單位與時間範圍一致。
  • 鍵盤可以操作篩選器和結果連結。

延伸練習

新增「與上一期間比較」功能,處理沒有上一期間資料、資料延遲和負值百分比三種情況。