react-calendar-heatmapでコントリビューションチャートを実現する
Next.js
react-calendar-heatmap
APIから以下の様なデータが返る様に実装しておく
export type Activity = { date: string; count: number; };
Activityの配列を、react-calendar-heatmapのCalendarHeatmapに渡してあげるだけでOK
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数によって変更される。 閾値は自分でカスタマイズ可能。