安安,我是 ChiYu!
昨天,我們的 App 學會了「同理心」,能夠優雅地處理載入與錯誤,大幅提升了使用者體驗。至此,我們 App 的基礎建設與核心互動功能,都已相當完備。
現在,是時候兌現我們在《專案章程》中許下的最終承諾,實現我們 App 的核心價值主張了——「關聯性洞察」。
但是,圖表功能的開發,遠比一個簡單的按鈕要複雜得多。它涉及到數據的獲取、處理、整合與視覺化,稍有不慎,就可能陷入混亂。因此,在我們一頭熱地栽進去 Vibe Coding 之前,我們要重拾我們最强大的武器,再次回到 **「文件驅動開發 (DDD)」**的懷抱。
今天,我們將回頭重新設計文件,對於較為複雜的功能,為了避免AI天馬行空脫韁,還是建議回頭重新設計一份完整詳細的規格文件!我們將扮演一位「數據產品設計師」,與 Gemini 一同腦力激盪,為這個最複雜的功能,撰寫一份清晰、專業的**「圖表元件規格書」**。
你可能會問:「我們不是已經有《使用者故事》了嗎?為什麼還要再寫一份文件?」
問得好!《使用者故事》告訴我們使用者想要 什麼 (What),但它並沒有告訴我們技術上該 如何實現 (How)。對於一個簡單的按鈕,這兩者之間的差距很小。但對於一個圖表元件,這個差距就非常巨大了:
在動手寫 Code 前,先把這些問題用一份 **「技術規格書」**定義清楚,就像是在畫一張精密的「零件設計圖」。有了這張圖,我們接下來的 Vibe Coding 才能精準、高效,而不是一邊寫一邊猜。
好了,理論武裝完畢!讓我們進入 gemini chat 模式,指揮 AI 為我們撰寫這份至關重要的規格書。
# 角色 (Role)
你是一位頂尖的數據產品設計師與資深前端架構師,精通數據視覺化、元件化開發與無障礙網頁設計 (a11y)。你最擅長的工作是將高階的商業需求,轉化為一份清晰、穩固、可執行、且具備卓越使用者體驗的前端元件技術規格書。
# 目標 (Objective)
請根據我提供的專案上下文,為我們的核心功能「關聯性洞察圖表」,設計一份專業、完整、且可直接交付給開發者執行的**「圖表元件技術規格書 (Chart Component Technical Specification)」**。這份文件將成為該元件開發的唯一真理來源。
# 上下文與關鍵資訊 (Context & Key Information)
* **核心價值主張**: 我們的 App 旨在「揭示個人行為與內在感受之間的微妙聯繫」(`@docs/PROJECT_CHARTER.md`)。
* **使用者故事**: 我們需要實現使用者故事 #5:「查看一個簡單的圖表,將我的心情趨勢與我完成的習慣並列視覺化」(`@docs/USER_STORIES.md`)。
* **可用數據源**: 我們可以透過 API 分別獲取 `moods` 和 `habits` 的日誌數據。
* **視覺風格**: 所有視覺設計(顏色、字體等)都必須嚴格遵循 `@docs/STYLE_GUIDE.md`。
# 產出格式與要求 (Your Task & Output Requirements)
**請生成一份專業的 Markdown 文件,並嚴格遵循以下大綱結構:**
### 1. **元件目標與使用者故事**
* 簡要重述此元件旨在解決的核心使用者問題,並直接引用相關的使用者故事。
### 2. **數據契約 (Data Contract / Props)**
* **架構理念**: 我們將採用「展示元件 (Presentational Component)」的設計模式。圖表元件本身**不應**負責合併或處理原始數據。它應該接收一個**已經處理好**的、單一的 `data` prop。
* **Props 定義**: 使用 Markdown 表格,清晰地定義此元件所需的所有 Props。
| Prop 名稱 | 資料類型 | 是否必需 | 預設值 | 說明 |
| :--- | :--- | :--- | :--- | :--- |
| `data` | `Array<Object>` | 是 | `[]` | 經過處理後的圖表數據陣列。每個物件代表 X 軸上的一個點,應包含如 `{ date: 'YYYY-MM-DD', moodRating: number, completedHabits: Array<string> }` 的結構。 |
| `isLoading` | `boolean` | 否 | `false` | 用於控制是否顯示載入狀態。 |
### 3. **核心功能與視覺呈現**
* 用條列式的方式,描述圖表的具體視覺元素:
* **圖表類型**: 採用混合圖表 (Combo Chart)。
* **心情趨勢**: 使用平滑的**折線圖 (Line Chart)** 呈現,線條顏色需使用風格指南中的主色 (`--color-primary`)。
* **習慣完成**: 在有完成習慣的日期數據點上,疊加一個**散點 (Scatter Point)** 作為標記,顏色使用輔色 (`--color-accent`)。
* **X 軸**: 代表**日期**,標籤應清晰易讀。
* **Y 軸**: 代表**心情分數** (範圍 1-5)。
* **圖例 (Legend)**: 需提供圖例,用以區分「心情趨勢」和「完成習慣」。
* **響應式設計**: 描述在移動端等小螢幕上,圖表應如何調整以保持可讀性(例如:減少 X 軸標籤的顯示密度)。
### 4. **互動行為 (Interaction Behavior)**
* **滑鼠懸停 (Hover)**: 當滑鼠移到任一數據點上時,應顯示一個**工具提示 (Tooltip)**。Tooltip 需:
* 顯示該點的詳細資訊:日期、心情分數、當日完成的所有習慣列表。
* 其外觀(背景、字體、顏色)需符合風格指南。
* **圖例點擊**: 點擊圖例中的項目(如 "完成習慣"),應能切換(顯示/隱藏)對應數據系列在圖表上的可見性。
### 5. **狀態與邊界情況 (States & Edge Cases)**
* 定義在特殊情況下,元件的渲染內容:
* **載入中 (`isLoading: true`)**: 元件區域應顯示一個**骨架屏 (Skeleton Screen)** 或載入指示器,而非空白。
* **無數據/數據不足 (`data` 陣列長度 < 3)**: 元件區域應顯示一個設計過的提示訊息,例如:「持續記錄幾天,就能解鎖你的個人洞察報告!」
### 6. **無障礙設計 (Accessibility - a11y)**
* 定義為了讓所有使用者都能訪問圖表資訊所需滿足的條件:
* **鍵盤導航**: 使用者應能使用鍵盤(如 Tab 鍵)遍歷圖表的各個數據點。
* **ARIA 屬性**: 圖表的根 SVG 元素應包含適當的 `role` 和 `aria-label` 屬性。
* **備用呈現**: 提供一個機制或隱藏的數據表格,讓螢幕閱讀器使用者也能獲取圖表的完整資訊。
### 7. **最終產出**
* 將以上所有內容,生成到 `docs/CHART_COMPONENT_SPEC.md` 檔案中。
AI 完成操作後,讓我們來仔細品味一下這份由我們共同創作的、專業的「零件設計圖」。
# MindTrack - 關聯性洞察圖表元件技術規格書
- **文件版本**: 1.0
- **作者**: Gemini (數據產品設計師 / 前端架構師)
---
## 1. 元件目標與使用者故事
### 1.1. 核心目標
此元件的核心目標,是實現產品的關鍵價值主張:「**揭示個人行為與內在感受之間的微妙聯繫**」。它將透過數據視覺化的方式,將抽象的日誌數據轉化為使用者能輕易理解、並從中獲得洞察的圖形化介面,賦予使用者改善生活品質的知識與力量。
### 1.2. 使用者故事
本元件直接對應以下核心使用者故事:
> **作為一個**數據導向的使用者,
> **我希望能**看到一個簡單的圖表,將我的心情趨勢與我完成的習慣並列視覺化,
> **這樣我才能**開始識別我的行為與幸福感之間有意義的模式。
---
## 2. 數據契約 (Data Contract / Props)
### 2.1. 架構理念
本圖表將作為一個純粹的**「展示元件 (Presentational Component)」**。它自身不包含任何數據獲取或處理的業務邏輯。其所有渲染內容,完全由外部傳入的 `props` 決定。這種設計確保了元件的高度可複用性與可測試性。
### 2.2. Props 定義
| Prop 名稱 | 資料類型 | 是否必需 | 預設值 | 說明 |
| :---------- | :-------------- | :------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<Object>` | **是** | `[]` | 經過上層邏輯處理後的圖表數據陣列。每個物件代表 X 軸上的一個數據點,其結構應為:<br>`{ date: 'YYYY-MM-DD', moodRating: number, completedHabits: Array<string> }` |
| `isLoading` | `boolean` | 否 | `false` | 用於控制元件是否應顯示為「載入中」狀態。當為 `true` 時,圖表內容將被載入指示器取代。 |
---
## 3. 核心功能與視覺呈現
所有視覺元素(顏色、字體等)的選擇,都必須嚴格遵循 `STYLE_GUIDE.md` 中的定義。
- **圖表類型**: 採用**混合圖表 (Combo Chart)**,在同一個座標系中呈現兩種不同的數據系列。
- **心情趨勢**:
- 應使用平滑的**折線圖 (Line Chart)** 來呈現,以展示數據的連續性與趨勢。
- 線條顏色應使用風格指南中的主色 `var(--primary-color)`。
- 線條下方可選用同色系的漸層區域填充,以增強視覺效果。
- **習慣完成**:
- 在 `completedHabits` 陣列**不為空**的日期數據點上,疊加一個**散點 (Scatter Point)** 作為視覺標記。
- 散點顏色應使用風格指南中的輔色/強調色 `var(--accent-color)`,以使其足夠醒目。
- **X 軸 (X-Axis)**:
- 代表**日期**,應從左至右按時間順序排列。
- 標籤應清晰易讀,格式建議為 `MM/DD`。
- **Y 軸 (Y-Axis)**:
- 代表**心情分數**,範圍為 1 至 5。
- 應顯示至少三個主要刻度標籤(例如:低、中、高),以輔助使用者快速定位。
- **圖例 (Legend)**:
- 必須提供圖例,用以清晰地區分「心情趨勢」折線和「完成習慣」散點。
- 圖例應放置在圖表下方或右上角,不應遮擋圖表主要內容。
- **響應式設計 (Responsive Design)**:
- 在移動端等小螢幕設備上,圖表必須能自動縮放以適應容器寬度。
- 為避免 X 軸標籤因空間不足而重疊,應實作標籤顯示密度自動調整邏輯(例如:從顯示每天,變為每隔一天或每週顯示一個標籤)。
---
## 4. 互動行為 (Interaction Behavior)
- **滑鼠懸停/觸控 (Hover/Touch)**:
- 當使用者的指標(滑鼠或手指)懸停在任一數據點(折線上的節點)上時,必須顯示一個**工具提示 (Tooltip)**。
- **Tooltip 內容**: 應清晰地展示該數據點的詳細資訊,至少包含:
1. 完整日期 (例如: `2025年9月8日`)
2. 當日心情分數 (例如: `心情: 4/5`)
3. 當日完成的所有習慣列表 (如果 `completedHabits` 陣列不為空)。
- **Tooltip 外觀**: 其背景色、字體、顏色等所有樣式,均需符合 `STYLE_GUIDE.md` 的規範。
- **圖例點擊 (Legend Click)**:
- 圖例中的項目應是可點擊的。
- 點擊圖例中的任一項(例如「完成習慣」),應能切換(顯示/隱藏)該數據系列在圖表上的可見性。
- 此互動讓使用者可以專注於單一數據系列進行分析。
---
## 5. 狀態與邊界情況 (States & Edge Cases)
元件必須能夠優雅地處理以下幾種情況:
- **載入中 (`isLoading: true`)**:
- 當 `isLoading` prop 為 `true` 時,元件的內容區域不應顯示空白。
- 應顯示一個符合整體設計風格的**骨架屏 (Skeleton Screen)** 或**載入指示器 (Loading Spinner)**,向使用者傳達「正在準備你的洞察報告...」的狀態。
- **無數據/數據不足 (`data.length < 3`)**:
- 當傳入的 `data` 陣列長度不足以形成有意義的趨勢時(建議閾值為 3 個數據點),不應渲染一個空的座標軸。
- 應在元件區域的正中央,顯示一個經過設計的、友好的提示訊息,例如:
> **「持續記錄幾天,就能解鎖你的個人洞察報告!」**
---
## 6. 無障礙設計 (Accessibility - a11y)
為確保所有使用者(包括使用輔助技術的使用者)都能平等地獲取圖表資訊,本元件必須滿足以下 WCAG 標準:
- **鍵盤導航 (Keyboard Navigation)**:
- 使用者必須能使用 `Tab` 鍵將焦點移入圖表元件。
- 當焦點在圖表上時,必須能使用方向鍵(`←` / `→`)在各個數據點之間遍歷,且每個被遍歷到的數據點都應能觸發其對應的 Tooltip 顯示。
- **ARIA 屬性**:
- 圖表的根 `<svg>` 元素必須包含 `role="img"` 和一個內容豐富的 `aria-label`,例如:`aria-label="一張從 [開始日期] 到 [結束日期] 的心情與習慣關聯圖表。"`。
- 每個可互動的數據點(或其所屬的 `<g>` 元素)都應有自己的 `role` 和 `aria-label`,用以描述其數據值,例如:`aria-label="9月8日,心情分數為 4 分,完成習慣 2 個。"`。
- **備用呈現 (Alternative Presentation)**:
- 必須提供一種讓螢幕閱讀器 (Screen Reader) 使用者能夠線性地、完整地理解圖表數據的機制。
- **推薦方案**: 在元件內部,提供一個**視覺上隱藏** (visually-hidden) 的數據表格 (`<table>`),其內容與圖表所呈現的數據完全對應。這能確保圖表資訊對所有使用者都是 100% 可訪問的。
docs(frontend): Create chart component specification
再次恭喜!今天,我們又一次實踐了「文件驅動開發」的核心精神。我們沒有直接衝進複雜的圖表程式碼中,而是先退一步,將一個模糊的「想法」,轉化為了一份清晰、具體、可執行的「技術規格」。
有了這份精密的「零件設計圖」,我們接下來的開發工作將會變得無比順暢。明天,我們將正式拿起工具,嚴格依據今天的這份規格書,指揮 AI 和 Chart.js,將這幅數據的畫布,變成真實、可互動的前端程式碼!