雷達技能圖
多維度雷達圖:進場繪製動畫、hover 頂點數值、雙資料疊比。
以純 SVG 繪製的多維度雷達圖:進場時資料多邊形自中心展開、外框沿邊描繪生長,滑鼠移到頂點會浮出該維度的數值 tooltip,並支援第二組資料半透明疊加對比,適合技能評估、產品比較等敘事場景。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add radar-skill-chartRadar Skill Chart 是用 React、SVG 與 Motion(motion/react)做的雷達圖(radar chart/蜘蛛網圖)元件,不依賴任何圖表函式庫。進場時資料多邊形從中心展開、外框沿邊描繪,可疊加第二組數值做對比,hover 或鍵盤聚焦頂點時顯示 tooltip。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<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 | 型別 | 預設值 | 說明 |
|---|---|---|---|
axes | RadarAxisDatum[] | — | 各軸資料 { label, value },至少 3 軸,主系列數值內嵌其中;較長的標籤會在空白處換行,標籤超出圖框時整張圖等比縮小,讓標籤留在 size 範圍內 |
series2 | number[] | — | 第二組數值(半透明疊加對比),順序需與 axes 對齊 |
seriesLabel | string | "系列 A" | 主系列名稱,雙系列時用於圖例與 tooltip |
series2Label | string | "系列 B" | 第二系列名稱 |
max | number | 100 | 數值上限,對應最外圈 |
size | number | 320 | 渲染尺寸(px,寬 = 高) |
rings | number | 4 | 同心網格圈數 |
color | string | "#6366f1" | 主系列顏色(任何合法 CSS 色值) |
color2 | string | "#f59e0b" | 第二系列顏色 |
className | string | — | 透傳到最外層容器 |
可及性
- 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 聚焦並朗讀該軸數值。系統開啟「減少動態效果」時會跳過展開動畫。