fix(client): accuracy issue with heatmap (#38137)
* fix/accuracy-issue-with-heatmap * fix: typo * feat: add test and simplify logic * test: mock Date.now and update snapshot Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@ -22,34 +22,54 @@ const propTypes = {
|
||||
};
|
||||
|
||||
function HeatMap({ calendar, streak }) {
|
||||
const startOfToday = startOfDay(Date.now());
|
||||
// an issue with react-calendar-heatmap makes the days off by one
|
||||
// see this https://github.com/kevinsqi/react-calendar-heatmap/issues/112
|
||||
// I have added one day in the marked places to account for the offset
|
||||
|
||||
// this logic adds a day to all the timestamps (remove if issue gets fixed)
|
||||
let tempCalendar = {};
|
||||
const secondsInADay = 60 * 60 * 24;
|
||||
for (let timestamp of Object.keys(calendar)) {
|
||||
tempCalendar[parseInt(timestamp, 10) + secondsInADay] = 1;
|
||||
}
|
||||
|
||||
calendar = tempCalendar;
|
||||
|
||||
// the addDays of 1 to startOfToday (remove if issue gets fixed)
|
||||
const startOfToday = addDays(startOfDay(Date.now()), 1);
|
||||
const sixMonthsAgo = addMonths(startOfToday, -6);
|
||||
const startOfCalendar = format(addDays(sixMonthsAgo, -1), 'YYYY-MM-DD');
|
||||
const endOfCalendar = format(startOfToday, 'YYYY-MM-DD');
|
||||
|
||||
let calendarData = {};
|
||||
let calendarData = [];
|
||||
let dayCounter = sixMonthsAgo;
|
||||
|
||||
// create a data point for each day of the calendar period (six months)
|
||||
while (dayCounter <= startOfToday) {
|
||||
calendarData[format(dayCounter, 'YYYY-MM-DD')] = 0;
|
||||
// this is the format needed for react-calendar-heatmap
|
||||
const newDay = {
|
||||
date: format(dayCounter, 'YYYY-MM-DD'),
|
||||
count: 0
|
||||
};
|
||||
|
||||
calendarData.push(newDay);
|
||||
dayCounter = addDays(dayCounter, 1);
|
||||
}
|
||||
|
||||
for (let timestamp in calendar) {
|
||||
if (calendar.hasOwnProperty(timestamp)) {
|
||||
// this adds one to the count of the day for each timestamp
|
||||
for (let timestamp of Object.keys(calendar)) {
|
||||
timestamp = Number(timestamp * 1000) || null;
|
||||
if (timestamp) {
|
||||
const startOfTimestampDay = format(startOfDay(timestamp), 'YYYY-MM-DD');
|
||||
calendarData[startOfTimestampDay] =
|
||||
calendarData[startOfTimestampDay] + 1 || 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
const index = calendarData.findIndex(
|
||||
day => day.date === startOfTimestampDay
|
||||
);
|
||||
|
||||
const calendarValues = Object.keys(calendarData).map(key => ({
|
||||
date: key,
|
||||
count: calendarData[key]
|
||||
}));
|
||||
if (index >= 0) {
|
||||
calendarData[index].count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FullWidthRow>
|
||||
@ -83,7 +103,7 @@ function HeatMap({ calendar, streak }) {
|
||||
})}`
|
||||
};
|
||||
}}
|
||||
values={calendarValues}
|
||||
values={calendarData}
|
||||
/>
|
||||
<ReactTooltip className='react-tooltip' effect='solid' html={true} />
|
||||
</FullWidthRow>
|
||||
|
37
client/src/components/profile/components/HeatMap.test.js
Normal file
37
client/src/components/profile/components/HeatMap.test.js
Normal file
@ -0,0 +1,37 @@
|
||||
/* global expect jest */
|
||||
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import HeatMap from './HeatMap';
|
||||
|
||||
const props = {
|
||||
calendar: {
|
||||
1580393017: 1,
|
||||
1580397504: 1
|
||||
},
|
||||
streak: {
|
||||
current: 2,
|
||||
longest: 2
|
||||
}
|
||||
};
|
||||
|
||||
let dateNowMockFn;
|
||||
|
||||
beforeEach(() => {
|
||||
dateNowMockFn = jest
|
||||
.spyOn(Date, 'now')
|
||||
.mockImplementation(() => 1580729769714);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
dateNowMockFn.mockRestore();
|
||||
});
|
||||
|
||||
describe('<HeatMap/>', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(<HeatMap {...props} />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user