日期标记 (F-CL-06): 旧实现是只按状态上色的 4px 圆点, 看不出完成度 —— 3/5 与 5/5 是同一个绿点。改为环形进度, 弧长 = 当天完成比例: expected = 0 -> 不画环 (当天没有应打卡项) expected > 0, 0 次 -> 空心环 (未开始) 部分完成 -> 弧长按比例 (半填充) 达标 / 超额 -> 整圈 (实心; 超额换色区分) 未来日期不画环 (计划 != 未完成); 选中日改用白环, 弧长仍表完成度; 「本月完成率」右侧补图例。 - 新增 components/checkin/DayRing.jsx (共享环形标记, 颜色交由 CSS 按视图上色) - MergedView 日历格子接入该环 - 删除无引用死代码: pages/checkin/CalendarView.jsx (173 行) 与 HabitView.jsx (338 行) —— V0.2.1 合并「打卡/日历」tab 后遗留, 全库扫描确认 无任何 import/动态 import 引用; 连带清理仅服务于它们的 CSS (保留仍被 ListView 使用的 .habit-link) 验证: 桩 fetch 渲染真实 MergedView, 15 项断言通过 —— 空心环 / 弧长 25%·50% 精确匹配 / 整圈 / 三态配色 / 未来不画环 / 选中日白弧 60% / 图例 / 旧圆点已移除。
51 lines
1.6 KiB
React
51 lines
1.6 KiB
React
// 打卡日历的日期标记: 环形进度 (F-CL-06)
|
|
//
|
|
// 为什么是环而不是圆点:
|
|
// 旧实现是 4px 小圆点, 只按状态上色 —— 3/5 和 5/5 都是同一个绿点,
|
|
// 看不出"当天做到几成"。改成环形后 **弧长 = 当天完成比例**, 颜色仍表状态:
|
|
// 0 < actual < expected -> 弧长按比例 (部分完成 / 半填充)
|
|
// actual >= expected -> 整圈 (全部完成 / 实心)
|
|
// actual = 0 且 expected > 0 -> 只有底环 (未开始 / 空心)
|
|
// expected = 0 由父组件判断, 不渲染本组件 (当天没有应打卡项)
|
|
//
|
|
// 颜色不写在这里: 由 CSS 按 `.mv-day` 作用域上色 (各视图调色板可能不同)。
|
|
const DEFAULT_SIZE = 30
|
|
const DEFAULT_STROKE = 2.5
|
|
|
|
export default function DayRing({
|
|
status = 'partial',
|
|
ratio = 0,
|
|
size = DEFAULT_SIZE,
|
|
stroke = DEFAULT_STROKE,
|
|
}) {
|
|
const p = Math.max(0, Math.min(1, Number(ratio) || 0))
|
|
const r = (size - stroke) / 2
|
|
const c = 2 * Math.PI * r
|
|
const half = size / 2
|
|
return (
|
|
<svg
|
|
className="day-ring"
|
|
width={size}
|
|
height={size}
|
|
viewBox={`0 0 ${size} ${size}`}
|
|
aria-hidden="true"
|
|
>
|
|
<circle
|
|
className="day-ring-bg"
|
|
cx={half} cy={half} r={r}
|
|
fill="none" strokeWidth={stroke}
|
|
/>
|
|
{p > 0 && (
|
|
<circle
|
|
className={'day-ring-bar ' + status}
|
|
cx={half} cy={half} r={r}
|
|
fill="none" strokeWidth={stroke}
|
|
strokeDasharray={c}
|
|
strokeDashoffset={c * (1 - p)}
|
|
transform={`rotate(-90 ${half} ${half})`}
|
|
/>
|
|
)}
|
|
</svg>
|
|
)
|
|
}
|