216 lines
6.0 KiB
TypeScript
Raw Normal View History

2020-07-22 20:50:43 +03:00
import React, { ReactChild } from 'react';
import { ViewMode } from '../../types/public-types';
import { TopPartOfCalendar } from './top-part-of-calendar';
import {
getLocaleMonth,
getWeekNumberISO8601,
} from '../../helpers/date-helper';
import '../../style.css';
export type CalendarProps = {
dates: Date[];
locale: string;
viewMode: ViewMode;
headerHeight: number;
columnWidth: number;
fontFamily: string;
fontSize: string;
};
export const Calendar: React.FC<CalendarProps> = ({
dates,
locale,
viewMode,
headerHeight,
columnWidth,
fontFamily,
fontSize,
}) => {
const getCalendarValuesForMonth = () => {
let topValues: ReactChild[] = [];
let bottomValues: ReactChild[] = [];
const topDefaultWidth = columnWidth * 6;
const topDefaultHeight = headerHeight * 0.5;
for (let i = 0; i < dates.length; i++) {
const date = dates[i];
let bottomValue = getLocaleMonth(date, locale);
bottomValues.push(
<text
key={bottomValue + date.getFullYear()}
y={headerHeight * 0.8}
x={columnWidth * i + columnWidth * 0.5}
className="GanttCalendar-bottomText"
>
{bottomValue}
</text>
);
if (i === 0 || date.getFullYear() !== dates[i - 1].getFullYear()) {
let topValue = date.getFullYear().toString();
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * i}
y1Line={0}
y2Line={topDefaultHeight}
xText={
topDefaultWidth + columnWidth * i - date.getMonth() * columnWidth
}
yText={topDefaultHeight * 0.9}
/>
);
}
}
return [topValues, bottomValues];
};
const getCalendarValuesForWeek = () => {
let topValues: ReactChild[] = [];
let bottomValues: ReactChild[] = [];
let weeksCount: number = 0;
const topDefaultHeight = headerHeight * 0.5;
for (let i = dates.length - 1; i >= 0; i--) {
const date = dates[i];
let topValue = '';
if (i === 0 || date.getMonth() !== dates[i - 1].getMonth()) {
//top
topValue = `${getLocaleMonth(date, locale)}, ${date.getFullYear()}`;
}
//bottom
const bottomValue = `W${getWeekNumberISO8601(date)}`;
bottomValues.push(
<text
key={date.getTime()}
y={headerHeight * 0.8}
x={columnWidth * i}
className="GanttCalendar-bottomText"
>
{bottomValue}
</text>
);
if (topValue) {
//if last day is new month
if (i !== dates.length - 1) {
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * i + weeksCount * columnWidth}
y1Line={0}
y2Line={topDefaultHeight}
xText={columnWidth * i + columnWidth * weeksCount * 0.5}
yText={topDefaultHeight * 0.9}
/>
);
}
weeksCount = 0;
}
weeksCount++;
}
return [topValues, bottomValues];
};
const getCalendarValuesForDay = () => {
let topValues: ReactChild[] = [];
let bottomValues: ReactChild[] = [];
const topDefaultHeight = headerHeight * 0.5;
for (let i = 0; i < dates.length; i++) {
const date = dates[i];
const bottomValue = date.getDate().toString();
bottomValues.push(
<text
key={date.getTime()}
y={headerHeight * 0.8}
x={columnWidth * i + columnWidth * 0.5}
className="GanttCalendar-bottomText"
>
{bottomValue}
</text>
);
if (
i + 1 !== dates.length &&
date.getMonth() !== dates[i + 1].getMonth()
) {
let topValue = getLocaleMonth(date, locale);
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * (i + 1)}
y1Line={0}
y2Line={topDefaultHeight}
xText={columnWidth * (i + 1) - date.getDate() * columnWidth * 0.5}
yText={topDefaultHeight * 0.9}
/>
);
}
}
return [topValues, bottomValues];
};
const getCalendarValuesForOther = () => {
let topValues: ReactChild[] = [];
let bottomValues: ReactChild[] = [];
let ticks = viewMode === ViewMode.HalfDay ? 2 : 4;
const topDefaultHeight = headerHeight * 0.5;
for (let i = 0; i < dates.length; i++) {
const date = dates[i];
const bottomValue = Intl.DateTimeFormat(locale, {
hour: 'numeric',
}).format(date);
bottomValues.push(
<text
key={date.getTime()}
y={headerHeight * 0.8}
x={columnWidth * i}
className="GanttCalendar-bottomText"
fontFamily={fontFamily}
>
{bottomValue}
</text>
);
if (i === 0 || date.getDate() !== dates[i - 1].getDate()) {
const topValue = `${date.getDate()} ${getLocaleMonth(date, locale)}`;
topValues.push(
<TopPartOfCalendar
key={topValue}
value={topValue}
x1Line={columnWidth * i + ticks * columnWidth}
y1Line={0}
y2Line={topDefaultHeight}
xText={columnWidth * i + ticks * columnWidth * 0.5}
yText={topDefaultHeight * 0.9}
/>
);
}
}
return [topValues, bottomValues];
};
let topValues: ReactChild[] = [];
let bottomValues: ReactChild[] = [];
switch (viewMode) {
case ViewMode.Month:
[topValues, bottomValues] = getCalendarValuesForMonth();
break;
case ViewMode.Week:
[topValues, bottomValues] = getCalendarValuesForWeek();
break;
case ViewMode.Day:
[topValues, bottomValues] = getCalendarValuesForDay();
break;
default:
[topValues, bottomValues] = getCalendarValuesForOther();
break;
}
return (
<g className="calendar" fontSize={fontSize} fontFamily={fontFamily}>
{bottomValues} {topValues}
</g>
);
};