資料視覺敘事

雷達技能圖

多維度雷達圖:進場繪製動畫、hover 頂點數值、雙資料疊比。

以純 SVG 繪製的多維度雷達圖:進場時資料多邊形自中心展開、外框沿邊描繪生長,滑鼠移到頂點會浮出該維度的數值 tooltip,並支援第二組資料半透明疊加對比,適合技能評估、產品比較等敘事場景。

把這個效果裝進你的專案

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

npx webberui@latest add radar-skill-chart

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

Radar Skill Chart 是用 React、SVG 與 Motion(motion/react)做的雷達圖(radar chart/蜘蛛網圖)元件,不依賴任何圖表函式庫。進場時資料多邊形從中心展開、外框沿邊描繪,可疊加第二組數值做對比,hover 或鍵盤聚焦頂點時顯示 tooltip。

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

300
100
4
編輯中的呼叫預設屬性
<RadarSkillChart/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

適用情境

  • 個人作品集或履歷頁的技能分布
  • 招募後台比較候選人能力與職缺需求
  • 產品比較頁呈現兩個方案在多個面向上的差異
  • 課程或測驗結果頁顯示各科分數
  • 不適合:維度只有一兩個,或需要看時間趨勢時,雷達圖反而難讀,改用 Animated Charts 的長條圖或折線圖

安裝

npx webberui@latest add https://webberui.com/r/radar-skill-chart.json

或在 components.json 設定 registries 後,改用 @webberui/radar-skill-chart 安裝。

使用

import { RadarSkillChart } from "@/components/ui/radar-skill-chart";

<RadarSkillChart
  axes={[
    { label: "React", value: 92 },
    { label: "TypeScript", value: 85 },
    { label: "測試", value: 62 },
    { label: "溝通協作", value: 88 },
  ]}
  series2={[60, 48, 30, 72]}
  seriesLabel="今年"
  series2Label="去年"
/>

範例

1 到 5 分的評分

把 max 設成 5,rings 也設成 5,讓每一圈剛好對應一分。

import { RadarSkillChart } from "@/components/ui/radar-skill-chart";

<RadarSkillChart
  max={5}
  rings={5}
  axes={[
    { label: "易用性", value: 4 },
    { label: "效能", value: 3 },
    { label: "文件", value: 5 },
    { label: "客服", value: 4 },
    { label: "價格", value: 2 },
  ]}
/>;

候選人與職缺需求對比

主系列放候選人分數,series2 放職缺要求的門檻,順序要和 axes 一致;用 color、color2 換成品牌色。

<RadarSkillChart
  axes={[
    { label: "前端", value: 88 },
    { label: "後端", value: 54 },
    { label: "系統設計", value: 70 },
    { label: "溝通", value: 82 },
    { label: "領導", value: 45 },
    { label: "產品思維", value: 76 },
  ]}
  series2={[80, 60, 65, 70, 50, 60]}
  seriesLabel="候選人"
  series2Label="職缺需求"
  color="#0ea5e9"
  color2="#a3a3a3"
  size={360}
/>

從 API 載入資料

元件是用戶端元件,可以在 Server Component 取得資料後直接當 props 傳入。

// app/team/[id]/page.tsx
import { RadarSkillChart } from "@/components/ui/radar-skill-chart";

export default async function MemberPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const res = await fetch(`https://api.example.com/members/${id}/skills`);
  const skills: { name: string; score: number }[] = await res.json();

  return (
    <RadarSkillChart
      axes={skills.map((s) => ({ label: s.name, value: s.score }))}
    />
  );
}

Props

Prop型別預設值說明
axesRadarAxisDatum[]—各軸資料 { label, value },至少 3 軸,主系列數值內嵌其中;較長的標籤會在空白處換行,標籤超出圖框時整張圖等比縮小,讓標籤留在 size 範圍內
series2number[]—第二組數值(半透明疊加對比),順序需與 axes 對齊
seriesLabelstring"系列 A"主系列名稱,雙系列時用於圖例與 tooltip
series2Labelstring"系列 B"第二系列名稱
maxnumber100數值上限,對應最外圈
sizenumber320渲染尺寸(px,寬 = 高)
ringsnumber4同心網格圈數
colorstring"#6366f1"主系列顏色(任何合法 CSS 色值)
color2string"#f59e0b"第二系列顏色
classNamestring—透傳到最外層容器

可及性

  • SVG 具描述性 aria-label,完整朗讀每個維度的標籤與各系列數值
  • 每個頂點熱區可鍵盤聚焦(Tab 依序移動),聚焦時同樣顯示 tooltip,並各自帶有朗讀數值的 aria-label
  • 使用者系統開啟「減少動態效果」時,跳過展開與描邊動畫,直接呈現完成圖形
  • hover 對應的軸線與標籤會同步加深,提供額外的視覺對位線索

常見問題

可以在 Next.js App Router 使用嗎?

可以。檔案開頭已有 "use client",可以從 Server Component 頁面 import,並把資料當 props 傳進去。

為什麼圖表沒有顯示?

雷達圖至少需要 3 軸才有面積,axes 少於 3 筆時元件會回傳 null。超過 max 或小於 0 的數值會被夾在 0 到 max 之間。

資料更新時會重播動畫嗎?

不會。進場展開只在掛載時執行一次,之後 axes 或 series2 改變時,多邊形座標會直接重算到新數值。

怎麼換顏色與大小?

color、color2 接受任何 CSS 色值,分別控制兩組系列;size 是渲染寬高(px),內部用 viewBox 等比縮放(軸標籤較長時 viewBox 會外擴,圖形跟著縮小);rings 控制同心網格圈數。

螢幕閱讀器讀得到數值嗎?

讀得到。SVG 的 aria-label 會列出每個維度的數值,每個頂點熱區也能用 Tab 聚焦並朗讀該軸數值。系統開啟「減少動態效果」時會跳過展開動畫。