diff --git a/src/app/calendarOverviewCard.tsx b/src/app/calendarOverviewCard.tsx
index ab68d7e..a778221 100644
--- a/src/app/calendarOverviewCard.tsx
+++ b/src/app/calendarOverviewCard.tsx
@@ -5,11 +5,12 @@ import useSWR from "swr";
import {fetcher} from "@/app/utils";
import * as R from 'ramda';
import * as dFns from 'date-fns';
-// import CalendarHeatmap from 'react-calendar-heatmap';
-import CalendarHeatmap from '../heatmap';
+import CalendarHeatmap from 'react-calendar-heatmap';
+// import CalendarHeatmap from '../heatmap';
import 'react-calendar-heatmap/dist/styles.css';
import './calendar-styles.css'
import { Tooltip } from 'react-tooltip';
+import {MyHeatMap} from "@/heatmap/b";
const initialDate = dFns.parseISO('2023-12-15T00:00:00.000Z')
const endDate = dFns.parseISO('2024-01-25T00:00:00.000Z')
diff --git a/src/heatmap/b.tsx b/src/heatmap/b.tsx
deleted file mode 100644
index 7218ec6..0000000
--- a/src/heatmap/b.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as dFns from 'date-fns';
-import {CSS_PSEDUO_NAMESPACE} from "@/heatmap/index";
-
-export function MonthLabels({
- startDate,
- endDate,
- getMonthLabelCoordinates
- }: {
- startDate: Date;
- endDate: Date;
- getMonthLabelCoordinates: (month: Date) => {
- x: number;
- y: number
- };
-}) {
- // We render a label for each month in the interval if its first week is in the interval
- const firstWeeks = dFns.eachWeekOfInterval({
- start: startDate,
- end: endDate,
- }).filter(date => date.getDate() <= 7);
-
- return (
- <>
- {firstWeeks.map((month, i) => {
- const {x, y} = getMonthLabelCoordinates(month);
-
- return (
- {dFns.format(month, 'MMM')}
- );
- })}
- >
- );
-}
diff --git a/src/heatmap/constants.ts b/src/heatmap/constants.ts
deleted file mode 100644
index a70d6ca..0000000
--- a/src/heatmap/constants.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export const MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000;
-
-export const DAYS_IN_WEEK = 7;
-
-export const MONTH_LABELS = [
- 'Jan',
- 'Feb',
- 'Mar',
- 'Apr',
- 'May',
- 'Jun',
- 'Jul',
- 'Aug',
- 'Sep',
- 'Oct',
- 'Nov',
- 'Dec',
-];
-
-export const DAY_LABELS = ['', 'Mon', '', 'Wed', '', 'Fri', ''];
diff --git a/src/heatmap/helpers.test.ts b/src/heatmap/helpers.test.ts
deleted file mode 100644
index 911b363..0000000
--- a/src/heatmap/helpers.test.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-import {
- convertToDate,
- dateNDaysAgo,
- getBeginningTimeForDate,
- getRange,
- shiftDate,
-} from './helpers';
-
-import {describe, it, expect} from "@jest/globals";
-
-describe('shiftDate', () => {
- it('adds a day to the first day of a month', () => {
- const startingDate = new Date(2017, 0, 1);
- const expectedDate = new Date(2017, 0, 2);
-
- expect(shiftDate(startingDate, 1).getTime()).toBe(expectedDate.getTime());
- });
-
- it('adds multiple days to the first day of a month', () => {
- const startingDate = new Date(2017, 0, 1);
- const expectedDate = new Date(2017, 0, 3);
-
- expect(shiftDate(startingDate, 2).getTime()).toBe(expectedDate.getTime());
- });
-
- it('subtracts a day from the first day of a month', () => {
- const startingDate = new Date(2017, 0, 1);
- const expectedDate = new Date(2016, 11, 31);
-
- expect(shiftDate(startingDate, -1).getTime()).toBe(expectedDate.getTime());
- });
-
- it('subtracts multiple days from the first day of a month', () => {
- const startingDate = new Date(2017, 0, 1);
- const expectedDate = new Date(2016, 11, 30);
-
- expect(shiftDate(startingDate, -2).getTime()).toBe(expectedDate.getTime());
- });
-
- it('adds a day to a non-first day of a month', () => {
- const startingDate = new Date(2017, 0, 2);
- const expectedDate = new Date(2017, 0, 3);
-
- expect(shiftDate(startingDate, 1).getTime()).toBe(expectedDate.getTime());
- });
-
- it('adds multiple days to a non-first day of a month', () => {
- const startingDate = new Date(2017, 0, 2);
- const expectedDate = new Date(2017, 0, 4);
-
- expect(shiftDate(startingDate, 2).getTime()).toBe(expectedDate.getTime());
- });
-
- it('subtracts a day from a non-first day of a month', () => {
- const startingDate = new Date(2017, 0, 2);
- const expectedDate = new Date(2017, 0, 1);
-
- expect(shiftDate(startingDate, -1).getTime()).toBe(expectedDate.getTime());
- });
-
- it('subtracts multiple days from a non-first day of a month', () => {
- const startingDate = new Date(2017, 0, 2);
- const expectedDate = new Date(2016, 11, 31);
-
- expect(shiftDate(startingDate, -2).getTime()).toBe(expectedDate.getTime());
- });
-});
-
-describe('getBeginningTimeForDate', () => {
- it('gets midnight (in the local timezone) on the date passed in', () => {
- const inputDate = new Date(2017, 11, 25, 21, 30, 59, 750);
- const expectedDate = new Date(2017, 11, 25, 0, 0, 0, 0);
-
- expect(getBeginningTimeForDate(inputDate).getTime()).toBe(expectedDate.getTime());
- });
-});
-
-describe('convertToDate', () => {
- it('interprets an "ISO-8601 date-only" string as UTC and converts it into a Date object representing the first millisecond on that date', () => {
- const iso8601DateOnlyString = '2017-07-14';
- const expectedDate = new Date(Date.UTC(2017, 6, 14, 0, 0, 0, 0));
-
- expect(convertToDate(iso8601DateOnlyString).getTime()).toBe(expectedDate.getTime());
- });
-
- it('interprets a millisecond timestamp integer as UTC and converts it into a Date object representing that same millisecond', () => {
- const msTimestamp = 1500000001234; // Friday, July 14, 2017 2:40:01.234 AM, according to https://epochconverter.com
- const expectedDate = new Date(Date.UTC(2017, 6, 14, 2, 40, 1, 234));
-
- expect(convertToDate(msTimestamp).getTime()).toBe(expectedDate.getTime());
- });
-
- it('returns the same Date object it receives', () => {
- const inputDate = new Date(2017, 11, 25, 21, 30, 59, 750);
- const originalTimestamp = inputDate.getTime();
-
- expect(convertToDate(inputDate)).toBe(inputDate);
- expect(convertToDate(inputDate).getTime()).toBe(originalTimestamp);
- });
-});
-
-describe('dateNDaysAgo', () => {
- it('crosses month boundaries in the negative direction', () => {
- const numDays = 32;
- const startingDate = new Date();
- const expectedDate = new Date(startingDate.getTime());
- expectedDate.setDate(startingDate.getDate() - numDays);
-
- const expectedYear = expectedDate.getFullYear();
- const expectedMonth = expectedDate.getMonth();
- const expectedDay = expectedDate.getDate();
-
- expect(dateNDaysAgo(numDays).getFullYear()).toBe(expectedYear);
- expect(dateNDaysAgo(numDays).getMonth()).toBe(expectedMonth);
- expect(dateNDaysAgo(numDays).getDate()).toBe(expectedDay);
- });
-
- it('crosses month boundaries in the positive direction', () => {
- const numDays = -32;
- const startingDate = new Date();
- const expectedDate = new Date(startingDate.getTime());
- expectedDate.setDate(startingDate.getDate() - numDays);
-
- const expectedYear = expectedDate.getFullYear();
- const expectedMonth = expectedDate.getMonth();
- const expectedDay = expectedDate.getDate();
-
- expect(dateNDaysAgo(numDays).getFullYear()).toBe(expectedYear);
- expect(dateNDaysAgo(numDays).getMonth()).toBe(expectedMonth);
- expect(dateNDaysAgo(numDays).getDate()).toBe(expectedDay);
- });
-
- it('crosses year boundaries in the negative direction', () => {
- const numDays = 366;
- const startingDate = new Date();
- const expectedDate = new Date(startingDate.getTime());
- expectedDate.setDate(startingDate.getDate() - numDays);
-
- const expectedYear = expectedDate.getFullYear();
- const expectedMonth = expectedDate.getMonth();
- const expectedDay = expectedDate.getDate();
-
- expect(dateNDaysAgo(numDays).getFullYear()).toBe(expectedYear);
- expect(dateNDaysAgo(numDays).getMonth()).toBe(expectedMonth);
- expect(dateNDaysAgo(numDays).getDate()).toBe(expectedDay);
- });
-
- it('crosses year boundaries in the positive direction', () => {
- const numDays = -366;
- const startingDate = new Date();
- const expectedDate = new Date(startingDate.getTime());
- expectedDate.setDate(startingDate.getDate() - numDays);
-
- const expectedYear = expectedDate.getFullYear();
- const expectedMonth = expectedDate.getMonth();
- const expectedDay = expectedDate.getDate();
-
- expect(dateNDaysAgo(numDays).getFullYear()).toBe(expectedYear);
- expect(dateNDaysAgo(numDays).getMonth()).toBe(expectedMonth);
- expect(dateNDaysAgo(numDays).getDate()).toBe(expectedDay);
- });
-});
-
-describe('getRange', () => {
- it('generates an empty array', () => {
- expect(getRange(0)).toEqual([]);
- });
-
- it('generates an array containing one integer', () => {
- expect(getRange(1)).toEqual([0]);
- });
-
- it('generates an array containing multiple integers', () => {
- expect(getRange(5)).toEqual([0, 1, 2, 3, 4]);
- });
-});
diff --git a/src/heatmap/helpers.ts b/src/heatmap/helpers.ts
deleted file mode 100644
index 5c21bc9..0000000
--- a/src/heatmap/helpers.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as dFns from 'date-fns';
-
-// returns a new date shifted a certain number of days (can be negative)
-export function shiftDate(date: Date, numDays: number): Date {
- return dFns.addDays(date, numDays);
-}
-
-export function getBeginningTimeForDate(date: Date): Date {
- return dFns.startOfDay(date);
-}
-
-// obj can be a parseable string, a millisecond timestamp, or a Date object
-export function convertToDate(obj: Date | string | number): Date {
- return obj instanceof Date ? obj : new Date(obj);
-}
-
-export function dateNDaysAgo(numDaysAgo: number): Date {
- return shiftDate(new Date(), -numDaysAgo);
-}
-
-export function getRange(count: number): number[] {
- const arr = [];
- for (let idx = 0; idx < count; idx += 1) {
- arr.push(idx);
- }
- return arr;
-}
diff --git a/src/heatmap/index.test.js b/src/heatmap/index.test.js
deleted file mode 100644
index 0f8c346..0000000
--- a/src/heatmap/index.test.js
+++ /dev/null
@@ -1,286 +0,0 @@
-import React from 'react';
-import Enzyme, { shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-
-import CalendarHeatmap from './index';
-import { dateNDaysAgo, shiftDate } from './helpers';
-
-Enzyme.configure({ adapter: new Adapter() });
-
-const getWrapper = (overrideProps, renderMethod = 'shallow') => {
- const defaultProps = {
- values: [],
- };
- return Enzyme[renderMethod]();
-};
-
-describe('CalendarHeatmap', () => {
- const values = [
- { date: new Date('2017-06-01') },
- { date: new Date('2017-06-02') },
- { date: new Date('2018-06-01') },
- { date: new Date('2018-06-02') },
- { date: new Date('2018-06-03') },
- ];
-
- it('should render as an svg', () => {
- const wrapper = shallow();
-
- expect(wrapper.find('svg')).toHaveLength(1);
- });
-
- it('should not throw exceptions in base case', () => {
- expect(() => ).not.toThrow();
- });
-
- it('shows values within its original date range', () => {
- const wrapper = shallow(
- ,
- );
-
- expect(wrapper.find('.color-filled').length).toBe(2);
- });
-
- it('should handle string formatted date range', () => {
- const wrapper = shallow(
- ,
- );
-
- expect(wrapper.find('.color-filled').length).toBe(2);
- });
-
- it('shows values within an updated date range', () => {
- const wrapper = shallow(
- ,
- );
-
- wrapper.setProps({
- endDate: new Date('2018-12-31'),
- startDate: new Date('2018-01-01'),
- });
-
- expect(wrapper.find('.color-filled').length).toBe(3);
- });
-});
-
-describe('CalendarHeatmap props', () => {
- it('values', () => {
- const values = [
- { date: '2016-01-01' },
- { date: new Date('2016-01-02').getTime() },
- { date: new Date('2016-01-03') },
- ];
- const wrapper = shallow(
- ,
- );
-
- // 'values should handle Date/string/number formats'
- expect(wrapper.find('.color-filled')).toHaveLength(values.length);
- });
-
- it('horizontal', () => {
- const horizontal = shallow(
- ,
- );
- const [, , horWidth, horHeight] = horizontal.prop('viewBox').split(' ');
- // 'horizontal orientation width should be greater than height'
- expect(Number(horWidth)).toBeGreaterThan(Number(horHeight));
-
- const vertical = shallow(
- ,
- );
- const [, , vertWidth, vertHeight] = vertical.prop('viewBox').split(' ');
- // 'vertical orientation width should be less than height'
- expect(Number(vertWidth)).toBeLessThan(Number(vertHeight));
- });
-
- it('startDate', () => {
- const today = new Date();
- const wrapper = shallow();
-
- expect(
- today.getDate() ===
- wrapper
- .instance()
- .getEndDate()
- .getDate() &&
- today.getMonth() ===
- wrapper
- .instance()
- .getEndDate()
- .getMonth(),
- ).toBe(true);
- });
-
- it('endDate', () => {
- const today = new Date();
- const wrapper = shallow(
- ,
- );
-
- expect(
- today.getDate() ===
- wrapper
- .instance()
- .getEndDate()
- .getDate() &&
- today.getMonth() ===
- wrapper
- .instance()
- .getEndDate()
- .getMonth(),
- ).toBe(true);
- });
-
- it('classForValue', () => {
- const today = new Date();
- const numDays = 10;
- const expectedStartDate = shiftDate(today, -numDays + 1);
- const wrapper = shallow(
- (value ? value.count : null)}
- classForValue={(value) => {
- if (!value) {
- return null;
- }
- return value.count > 0 ? 'red' : 'white';
- }}
- />,
- );
-
- expect(wrapper.find('.white')).toHaveLength(1);
- expect(wrapper.find('.red')).toHaveLength(1);
-
- // TODO these attr selectors might be broken with react 15
- // assert(wrapper.first('rect[title=0]').hasClass('white'));
- // assert(wrapper.first('rect[title=1]').hasClass('red'));
- });
-
- it('showMonthLabels', () => {
- const visible = shallow(
- ,
- );
-
- expect(visible.find('text').length).toBeGreaterThan(0);
-
- const hidden = shallow();
-
- expect(hidden.find('text')).toHaveLength(0);
- });
-
- it('showWeekdayLabels', () => {
- const visible = shallow(
- ,
- );
-
- expect(visible.find('text').length).toBeGreaterThan(2);
-
- const hidden = shallow(
- ,
- );
-
- expect(hidden.find('text')).toHaveLength(0);
-
- // should display text with .small-text class
- // in case if horizontal prop value is false
- const vertical = shallow();
-
- expect(vertical.find('text.react-calendar-heatmap-small-text')).toHaveLength(3);
- });
-
- it('transformDayElement', () => {
- const transform = (rect) => React.cloneElement(rect, { 'data-test': 'ok' });
- const today = new Date();
- const expectedStartDate = shiftDate(today, -1);
- const wrapper = shallow(
- ,
- );
-
- expect(wrapper.find('[data-test="ok"]')).toHaveLength(1);
- });
-
- describe('tooltipDataAttrs', () => {
- it('allows a function to be passed', () => {
- const today = new Date();
- const numDays = 10;
- const expectedStartDate = shiftDate(today, -numDays + 1);
- const wrapper = shallow(
- ({
- 'data-tooltip': `Count: ${count}`,
- })}
- />,
- );
-
- expect(wrapper.find('[data-tooltip="Count: 1"]')).toHaveLength(1);
- });
- });
-
- describe('event handlers', () => {
- const count = 999;
- const startDate = '2018-06-01';
- const endDate = '2018-06-03';
- const values = [{ date: '2018-06-02', count }];
- const props = {
- values,
- startDate,
- endDate,
- };
- const expectedValue = values[0];
-
- it('calls props.onClick with the correct value', () => {
- const onClick = jest.fn();
- const wrapper = getWrapper({ ...props, onClick });
-
- const rect = wrapper.find('rect').at(0);
- rect.simulate('click');
-
- expect(onClick).toHaveBeenCalledWith(expectedValue);
- });
-
- it('calls props.onMouseOver with the correct value', () => {
- const onMouseOver = jest.fn();
- const wrapper = getWrapper({ ...props, onMouseOver });
- const fakeEvent = { preventDefault: jest.fn() };
-
- const rect = wrapper.find('rect').at(0);
- rect.simulate('mouseOver', fakeEvent);
-
- expect(onMouseOver).toHaveBeenCalledWith(fakeEvent, expectedValue);
- });
-
- it('calls props.onMouseLeave with the correct value', () => {
- const onMouseLeave = jest.fn();
- const wrapper = getWrapper({ ...props, onMouseLeave });
- const fakeEvent = { preventDefault: jest.fn() };
-
- const rect = wrapper.find('rect').at(0);
- rect.simulate('mouseLeave', fakeEvent);
-
- expect(onMouseLeave).toHaveBeenCalledWith(fakeEvent, expectedValue);
- });
- });
-});
diff --git a/src/heatmap/index.tsx b/src/heatmap/index.tsx
deleted file mode 100644
index 62185f2..0000000
--- a/src/heatmap/index.tsx
+++ /dev/null
@@ -1,386 +0,0 @@
-// @ts-nocheck
-
-import React, {Fragment} from 'react';
-import PropTypes from 'prop-types';
-import memoizeOne from 'memoize-one';
-import {DAYS_IN_WEEK, MILLISECONDS_IN_ONE_DAY, DAY_LABELS, MONTH_LABELS} from './constants';
-import {
- dateNDaysAgo,
- shiftDate,
- getBeginningTimeForDate,
- convertToDate,
- getRange,
-} from './helpers';
-import * as dFns from 'date-fns';
-import {MonthLabels} from "@/heatmap/b";
-
-const SQUARE_SIZE = 10;
-const MONTH_LABEL_GUTTER_SIZE = 4;
-export const CSS_PSEDUO_NAMESPACE = 'react-calendar-heatmap-';
-
-class CalendarHeatmap extends React.Component {
- getDateDifferenceInDays() {
- const {
- startDate,
- endDate
- } = this.props;
- return dFns.differenceInCalendarDays(endDate, startDate);
- }
-
- getSquareSizeWithGutter() {
- return SQUARE_SIZE + this.props.gutterSize;
- }
-
- getMonthLabelSize() {
- if (!this.props.showMonthLabels) {
- return 0;
- }
- if (this.props.horizontal) {
- return SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE;
- }
- return 2 * (SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE);
- }
-
- getWeekdayLabelSize() {
- if (!this.props.showWeekdayLabels) {
- return 0;
- }
- if (this.props.horizontal) {
- return 30;
- }
- return SQUARE_SIZE * 1.5;
- }
-
- getStartDate() {
- return shiftDate(this.getEndDate(), -this.getDateDifferenceInDays() + 1); // +1 because endDate is inclusive
- }
-
- getEndDate() {
- return getBeginningTimeForDate(convertToDate(this.props.endDate));
- }
-
- getStartDateWithEmptyDays() {
- return shiftDate(this.getStartDate(), -this.getNumEmptyDaysAtStart());
- }
-
- getNumEmptyDaysAtStart() {
- return this.getStartDate().getDay();
- }
-
- getNumEmptyDaysAtEnd() {
- return DAYS_IN_WEEK - 1 - this.getEndDate().getDay();
- }
-
- getWeekCount() {
- const numDaysRoundedToWeek =
- this.getDateDifferenceInDays() + this.getNumEmptyDaysAtStart() + this.getNumEmptyDaysAtEnd();
- return Math.ceil(numDaysRoundedToWeek / DAYS_IN_WEEK);
- }
-
- getWeekWidth() {
- return DAYS_IN_WEEK * this.getSquareSizeWithGutter();
- }
-
- getWidth() {
- return (
- this.getWeekCount() * this.getSquareSizeWithGutter() -
- (this.props.gutterSize - this.getWeekdayLabelSize())
- );
- }
-
- getHeight() {
- return (
- this.getWeekWidth() +
- (this.getMonthLabelSize() - this.props.gutterSize) +
- this.getWeekdayLabelSize()
- );
- }
-
- getValueCache = memoizeOne((props) =>
- props.values.reduce((memo, value) => {
- const date = convertToDate(value.date);
- const index = Math.floor((date - this.getStartDateWithEmptyDays()) / MILLISECONDS_IN_ONE_DAY);
- // eslint-disable-next-line no-param-reassign
- memo[index] = {
- value,
- className: this.props.classForValue(value),
- title: this.props.titleForValue ? this.props.titleForValue(value) : null,
- tooltipDataAttrs: this.getTooltipDataAttrsForValue(value),
- };
- return memo;
- }, {}),
- );
-
- getValueForIndex(index) {
- if (this.valueCache[index]) {
- return this.valueCache[index].value;
- }
- return null;
- }
-
- getClassNameForIndex(index) {
- if (this.valueCache[index]) {
- return this.valueCache[index].className;
- }
- return this.props.classForValue(null);
- }
-
- getTitleForIndex(index) {
- if (this.valueCache[index]) {
- return this.valueCache[index].title;
- }
- return this.props.titleForValue ? this.props.titleForValue(null) : null;
- }
-
- getTooltipDataAttrsForIndex(index) {
- if (this.valueCache[index]) {
- return this.valueCache[index].tooltipDataAttrs;
- }
- return this.getTooltipDataAttrsForValue({
- date: null,
- count: null
- });
- }
-
- getTooltipDataAttrsForValue(value) {
- const {tooltipDataAttrs} = this.props;
-
- if (typeof tooltipDataAttrs === 'function') {
- return tooltipDataAttrs(value);
- }
- return tooltipDataAttrs;
- }
-
- getTransformForWeek(weekIndex) {
- if (this.props.horizontal) {
- return `translate(${weekIndex * this.getSquareSizeWithGutter()}, 0)`;
- }
- return `translate(0, ${weekIndex * this.getSquareSizeWithGutter()})`;
- }
-
- getTransformForWeekdayLabels() {
- if (this.props.horizontal) {
- return `translate(${SQUARE_SIZE}, ${this.getMonthLabelSize()})`;
- }
- return null;
- }
-
- getTransformForMonthLabels() {
- if (this.props.horizontal) {
- return `translate(${this.getWeekdayLabelSize()}, 0)`;
- }
- return `translate(${this.getWeekWidth() +
- MONTH_LABEL_GUTTER_SIZE}, ${this.getWeekdayLabelSize()})`;
- }
-
- getTransformForAllWeeks() {
- if (this.props.horizontal) {
- return `translate(${this.getWeekdayLabelSize()}, ${this.getMonthLabelSize()})`;
- }
- return `translate(0, ${this.getWeekdayLabelSize()})`;
- }
-
- getViewBox() {
- if (this.props.horizontal) {
- return `0 0 ${this.getWidth()} ${this.getHeight()}`;
- }
- return `0 0 ${this.getHeight()} ${this.getWidth()}`;
- }
-
- getSquareCoordinates(dayIndex) {
- if (this.props.horizontal) {
- return [0, dayIndex * this.getSquareSizeWithGutter()];
- }
- return [dayIndex * this.getSquareSizeWithGutter(), 0];
- }
-
- getWeekdayLabelCoordinates(dayIndex) {
- if (this.props.horizontal) {
- return [0, (dayIndex + 1) * SQUARE_SIZE + dayIndex * this.props.gutterSize];
- }
- return [dayIndex * SQUARE_SIZE + dayIndex * this.props.gutterSize, SQUARE_SIZE];
- }
-
- getMonthLabelCoordinates(weekIndex) {
- if (this.props.horizontal) {
- return [
- weekIndex * this.getSquareSizeWithGutter(),
- this.getMonthLabelSize() - MONTH_LABEL_GUTTER_SIZE,
- ];
- }
- const verticalOffset = -2;
- return [0, (weekIndex + 1) * this.getSquareSizeWithGutter() + verticalOffset];
- }
-
- handleClick(value) {
- if (this.props.onClick) {
- this.props.onClick(value);
- }
- }
-
- handleMouseOver(e, value) {
- if (this.props.onMouseOver) {
- this.props.onMouseOver(e, value);
- }
- }
-
- handleMouseLeave(e, value) {
- if (this.props.onMouseLeave) {
- this.props.onMouseLeave(e, value);
- }
- }
-
- renderSquare(dayIndex, index) {
- const indexOutOfRange =
- index < this.getNumEmptyDaysAtStart() ||
- index >= this.getNumEmptyDaysAtStart() + this.getDateDifferenceInDays();
- if (indexOutOfRange && !this.props.showOutOfRangeDays) {
- return null;
- }
- const [x, y] = this.getSquareCoordinates(dayIndex);
- const value = this.getValueForIndex(index);
- const rect = (
- // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
- this.handleClick(value)}
- onMouseOver={(e) => this.handleMouseOver(e, value)}
- onMouseLeave={(e) => this.handleMouseLeave(e, value)}
- {...this.getTooltipDataAttrsForIndex(index)}
- >
- {this.getTitleForIndex(index)}
-
- );
- const {transformDayElement} = this.props;
- return transformDayElement ? transformDayElement(rect, value, index) : rect;
- }
-
- renderWeek(weekIndex) {
- return (
-
- {getRange(DAYS_IN_WEEK).map((dayIndex) =>
- this.renderSquare(dayIndex, weekIndex * DAYS_IN_WEEK + dayIndex),
- )}
-
- );
- }
-
- renderWeekdayLabels() {
- if (!this.props.showWeekdayLabels) {
- return null;
- }
- return this.props.weekdayLabels.map((weekdayLabel, dayIndex) => {
- const [x, y] = this.getWeekdayLabelCoordinates(dayIndex);
- const cssClasses = `${
- this.props.horizontal ? '' : `${CSS_PSEDUO_NAMESPACE}small-text`
- } ${CSS_PSEDUO_NAMESPACE}weekday-label`;
- // eslint-disable-next-line no-bitwise
- return dayIndex & 1 ? (
-
- {weekdayLabel}
-
- ) : null;
- });
- }
-
- render() {
- this.valueCache = this.getValueCache(this.props);
-
- const monthPositionAdapter = (date) => {
- const [x, y] = this.getMonthLabelCoordinates(dFns.differenceInWeeks(date, this.props.startDate));
- return {
- x,
- y
- }
- };
-
- const weeks = dFns.eachWeekOfInterval({
- start: this.props.startDate,
- end: this.props.endDate,
- });
-
- return (
-
- );
- }
-}
-
-CalendarHeatmap.propTypes = {
- values: PropTypes.arrayOf(
- PropTypes.shape({
- date: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)])
- .isRequired,
- }).isRequired,
- ).isRequired, // array of objects with date and arbitrary metadata
- numDays: PropTypes.number, // number of days back from endDate to show
- startDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)]), // start of date range
- endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)]), // end of date range
- gutterSize: PropTypes.number, // size of space between squares
- horizontal: PropTypes.bool, // whether to orient horizontally or vertically
- showMonthLabels: PropTypes.bool, // whether to show month labels
- showWeekdayLabels: PropTypes.bool, // whether to show weekday labels
- showOutOfRangeDays: PropTypes.bool, // whether to render squares for extra days in week after endDate, and before start date
- tooltipDataAttrs: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), // data attributes to add to square for setting 3rd party tooltips, e.g. { 'data-toggle': 'tooltip' } for bootstrap tooltips
- titleForValue: PropTypes.func, // function which returns title text for value
- classForValue: PropTypes.func, // function which returns html class for value
- monthLabels: PropTypes.arrayOf(PropTypes.string), // An array with 12 strings representing the text from janurary to december
- weekdayLabels: PropTypes.arrayOf(PropTypes.string), // An array with 7 strings representing the text from Sun to Sat
- onClick: PropTypes.func, // callback function when a square is clicked
- onMouseOver: PropTypes.func, // callback function when mouse pointer is over a square
- onMouseLeave: PropTypes.func, // callback function when mouse pointer is left a square
- transformDayElement: PropTypes.func, // function to further transform the svg element for a single day
-};
-
-CalendarHeatmap.defaultProps = {
- numDays: null,
- startDate: dateNDaysAgo(200),
- endDate: new Date(),
- gutterSize: 1,
- horizontal: true,
- showMonthLabels: true,
- showWeekdayLabels: false,
- showOutOfRangeDays: false,
- tooltipDataAttrs: null,
- titleForValue: null,
- classForValue: (value) => (value ? 'color-filled' : 'color-empty'),
- monthLabels: MONTH_LABELS,
- weekdayLabels: DAY_LABELS,
- onClick: null,
- onMouseOver: null,
- onMouseLeave: null,
- transformDayElement: null,
-};
-
-export default CalendarHeatmap;
diff --git a/src/heatmap/styles.css b/src/heatmap/styles.css
deleted file mode 100644
index 2961147..0000000
--- a/src/heatmap/styles.css
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * react-calendar-heatmap styles
- *
- * All of the styles in this file are optional and configurable!
- * The github and gitlab color scales are provided for reference.
- */
-
-.react-calendar-heatmap text {
- font-size: 10px;
- fill: #aaa;
-}
-
-.react-calendar-heatmap .react-calendar-heatmap-small-text {
- font-size: 5px;
-}
-
-.react-calendar-heatmap rect:hover {
- stroke: #555;
- stroke-width: 1px;
-}
-
-/*
- * Default color scale
- */
-
-.react-calendar-heatmap .color-empty {
- fill: #eeeeee;
-}
-
-.react-calendar-heatmap .color-filled {
- fill: #8cc665;
-}
-
-/*
- * Github color scale
- */
-
-.react-calendar-heatmap .color-github-0 {
- fill: #eeeeee;
-}
-.react-calendar-heatmap .color-github-1 {
- fill: #d6e685;
-}
-.react-calendar-heatmap .color-github-2 {
- fill: #8cc665;
-}
-.react-calendar-heatmap .color-github-3 {
- fill: #44a340;
-}
-.react-calendar-heatmap .color-github-4 {
- fill: #1e6823;
-}
-
-/*
- * Gitlab color scale
- */
-
-.react-calendar-heatmap .color-gitlab-0 {
- fill: #ededed;
-}
-.react-calendar-heatmap .color-gitlab-1 {
- fill: #acd5f2;
-}
-.react-calendar-heatmap .color-gitlab-2 {
- fill: #7fa8d1;
-}
-.react-calendar-heatmap .color-gitlab-3 {
- fill: #49729b;
-}
-.react-calendar-heatmap .color-gitlab-4 {
- fill: #254e77;
-}