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:
Tom
2020-02-03 23:07:04 -06:00
committed by GitHub
parent c6eb40ceef
commit 964328dbae
3 changed files with 2369 additions and 16 deletions

View File

@ -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>

View 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