From 3b9407474221c45281a731fd0d6864a2fbe39d24 Mon Sep 17 00:00:00 2001 From: Viet Nguyen <3805254+vnugent@users.noreply.github.com> Date: Mon, 21 Aug 2023 21:39:38 +0200 Subject: [PATCH] fix(logbook): wrap year selection when > 13 (#968) fix(logbook): show correct date on tooltip --- src/components/logbook/ActivityHeat.tsx | 80 ++++++++++++++++--------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/components/logbook/ActivityHeat.tsx b/src/components/logbook/ActivityHeat.tsx index 99924f484..7b15041a5 100644 --- a/src/components/logbook/ActivityHeat.tsx +++ b/src/components/logbook/ActivityHeat.tsx @@ -1,7 +1,7 @@ import { useState, useMemo, ReactElement } from 'react' -import { ResponsiveContainer, XAxis, YAxis, ZAxis, Tooltip, ScatterChart, Scatter } from 'recharts' +import { XAxis, YAxis, ZAxis, Tooltip, ScatterChart, Scatter } from 'recharts' import { groupBy } from 'underscore' -import { getWeek, format, eachYearOfInterval, eachWeekOfInterval } from 'date-fns' +import { getWeek, format, eachYearOfInterval, eachWeekOfInterval, addDays } from 'date-fns' import classNames from 'classnames' import { ChartsSectionProps } from './ChartsSection' @@ -9,9 +9,22 @@ import { TickType } from '../../js/types' import { ScatterPointItem } from 'recharts/types/cartesian/Scatter' interface DataProps { + /** + * First Monday of the month + */ x: number + /** + * Day of the week + */ y: string + /** + * Number of climbs/sends + */ z: number + /** + * Actual timestamp (x + y) + */ + ts: number } /** @@ -30,7 +43,7 @@ type ScatterPointProps = Pick & ScatterPointItem & { } /** - * Show a year of activities in a grid + * Show a year of activities in a calendar-like grid. */ const ActivityHeat: React.FC = ({ tickList }) => { if (tickList == null) return null @@ -64,12 +77,13 @@ const ActivityHeat: React.FC = ({ tickList }) => { const weekNum = getWeek(curr, { weekStartsOn: 1 }) const thisWeekTicks = currentTicksAggByWeek[weekNum] const thisWeekAgg = groupBy(thisWeekTicks, getDayOfWeekFromTick) - const week: DataProps[] = daysOfWeek.map(d => { + const week: DataProps[] = daysOfWeek.map((d, index) => { const count = thisWeekAgg[d]?.length ?? 0 return ({ x: curr.getTime(), y: DAYS_OF_WEEK.get(d) ?? '', - z: count + z: count, + ts: addDays(curr, index).getTime() }) }) return acc.concat(week) @@ -94,11 +108,12 @@ const ActivityHeat: React.FC = ({ tickList }) => { const renderToolTip: React.FC = ({ active, payload }) => { if (active === true && payload != null && payload.length > 0) { - const dateStr = format(payload[0].value, 'PPPP') + const dateStr = format(payload[0].payload.ts, 'PPPP') const count = payload?.[2]?.value ?? 0 + const unit = count === 1 ? 'climb' : 'climbs' return (
- {count > 0 ? count : 'No'} climbs on {dateStr} + {count > 0 ? count : 'No '} {unit} on {dateStr}
) } @@ -106,26 +121,32 @@ const ActivityHeat: React.FC = ({ tickList }) => { } return ( -
-
-

- Activity -

-
- {years.reverse().map(date => { - const year = date.getFullYear() - return ( - - ) - })} -
- - +
+

+ Activity +

+
+ {years.reverse().map(date => { + const year = date.getFullYear() + const count = aggByYear[year]?.length ?? 0 + return ( + + ) + })} +
+
+
+ = ({ tickList }) => { - +
) @@ -183,7 +204,8 @@ export const tickFormatScoreToYdsVscale = (value: string): string => { const dayOfMonth = d.getDate() const dayOfWeek = d.getDay() - // only show the first week of the month + // Only show tick (date) on the first week of the month. + // This check determines whether date is the first week. if (dayOfMonth <= 7 && dayOfWeek === 1) return format(d, 'MMM') return '' }