ActivityChart 组件
概述
ActivityChart 是一个用户活动热力图组件,以 GitHub 风格的贡献图形式展示用户在一年内的活动情况。
文件路径
src/components/user/activity-chart.tsx
功能特性
- 热力图展示: 7xN 的网格展示每日活动
- 强度分级: 5 级颜色深度表示活动强度
- 响应式设计: 移动端显示 6 个月,桌面端显示 12 个月
- 月份标签: 自动计算并显示月份标签
- 交互提示: Tooltip 显示具体日期和活动数
- 日期选择: 支持点击日期进行筛选
- 今日标记: 当前日期有特殊边框标记
接口定义
interface ActivityData {
date: string; // ISO 日期格式 (YYYY-MM-DD)
count: number; // 活动数量
}
interface ActivityChartProps {
data: ActivityData[]; // 活动数据
locale?: string; // 语言区域
selectedDate?: string; // 选中的日期
onDateClick?: (date: string | null) => void; // 日期点击回调
}
使用示例
import { ActivityChart } from "@/components/user/activity-chart";
export default function UserProfile({ activityData }: { activityData: ActivityData[] }) {
const [selectedDate, setSelectedDate] = useState<string | null>(null);
return (
<ActivityChart
data={activityData}
locale="zh-CN"
selectedDate={selectedDate}
onDateClick={setSelectedDate}
/>
);
}
数据格式
const activityData = [
{ date: "2024-01-01", count: 5 },
{ date: "2024-01-02", count: 0 },
{ date: "2024-01-03", count: 12 },
// ...
];
强度计算
const getIntensity = (count: number): number => {
if (count === 0) return 0;
if (count === 1) return 1;
const ratio = count / maxCount;
if (ratio <= 0.25) return 1;
if (ratio <= 0.5) return 2;
if (ratio <= 0.75) return 3;
return 4;
};
颜色级别
| 级别 | 颜色 | 含义 |
|---|---|---|
| 0 | bg-muted | 无活动 |
| 1 | bg-primary/20 | 少量活动 |
| 2 | bg-primary/40 | 中等活动 |
| 3 | bg-primary/70 | 较多活动 |
| 4 | bg-primary | 大量活动 |
响应式行为
- 移动端 (
< 768px): 显示最近 26 周(约 6 个月) - 桌面端 (
>= 768px): 显示最近 52 周(约 12 个月)
周标签
显示周一至周五的缩写:
["", "M", "", "W", "", "F", ""]
月份标签处理
为避免标签重叠,算法会:
- 计算所有月份的起始位置
- 如果两个月太近(< 4 列),跳过当前月,显示下一个月
交互功能
日期选择
const handleClick = () => {
if (onDateClick) {
// 切换选择状态
onDateClick(isSelected ? null : dateStr);
}
};
Tooltip 内容
- 活动数量
- 完整日期(本地化格式)
依赖
next-intl- 国际化@/components/ui/tooltip- Tooltip 组件
性能优化
- 使用
useMemo缓存周数据和最大计数计算 - 使用
useEffect监听窗口大小变化
注意事项
- 数据日期格式必须是
YYYY-MM-DD - 组件从当前日期向前计算
- 起始日期对齐到周日
- 未来日期不显示
- 选中日期有额外的边框和放大效果
- 今日有 primary 色环标记