react-calendar-heatmapでコントリビューションチャートを実現する
Next.js
フロントエンド
React Calendar Heatmap
知識
APIから以下の様なデータが返る様に実装しておく
ts
export type Activity = {
date: string;
count: number;
};Activityの配列を、react-calendar-heatmapのCalendarHeatmapに渡してあげるだけでOK
tsx
const monthLabels = [
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
];
const shiftDate = (date: Date, numDays: number): Date => {
const newDate = new Date(date);
newDate.setDate(newDate.getDate() + numDays);
return newDate;
};
type ContributionChartProps = {
data: Activity[];
};
export const ContributionChart = ({
data,
}: ContributionChartProps): JSX.Element => {
const [isShowModal, setIsShowModal] = React.useState(false);
const [selectedDate, setSelectedDate] = React.useState<string>('');
const handleOnClick = (
value: ReactCalendarHeatmapValue<string> | undefined
): void => {
if (isNil(value)) return;
setSelectedDate(value.date);
setIsShowModal(true);
};
return (
<>
<DashboardCard title='最近のアクティビティ'>
<CalendarHeatmap
monthLabels={monthLabels}
startDate={shiftDate(new Date(), -360)}
endDate={new Date()}
values={data ?? []}
onClick={handleOnClick}
classForValue={(value) => {
if (isNil(value) || value?.count === 0) {
return 'color-empty';
}
if (value?.count <= 1) {
return 'color-scale-1';
} else if (value?.count <= 2) {
return 'color-scale-2';
} else if (value?.count <= 3) {
return 'color-scale-3';
} else {
return 'color-scale-4';
}
}}
/>
</DashboardCard>
<ContributionChartModal
isShowModal={isShowModal}
setIsShowModal={setIsShowModal}
selectedDate={selectedDate}
/>
</>
);
};
heatmapの色は、count数によって変更される。 閾値は自分でカスタマイズ可能。