70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { timeMonday, timeSunday, timeDay, timeMonth } from 'd3-time';
|
|
import { timeFormat } from 'd3-time-format';
|
|
import type { DayEntry } from '../types';
|
|
|
|
export const DAY_LABELS_MONDAY = ['Mon', '', 'Wed', '', 'Fri', '', ''];
|
|
export const DAY_LABELS_SUNDAY = ['Sun', '', 'Tue', '', 'Thu', '', 'Sat'];
|
|
|
|
export function getDayLabels(weekStart: string): string[] {
|
|
return weekStart === 'sunday' ? DAY_LABELS_SUNDAY : DAY_LABELS_MONDAY;
|
|
}
|
|
|
|
export const MONTH_FORMAT = timeFormat('%b');
|
|
export const DATE_FORMAT = timeFormat('%Y-%m-%d');
|
|
export const DISPLAY_FORMAT = timeFormat('%a, %b %-d, %Y');
|
|
|
|
export interface DayCell {
|
|
date: Date;
|
|
dateStr: string;
|
|
entry: DayEntry | null;
|
|
week: number;
|
|
day: number;
|
|
isWeekend: boolean;
|
|
}
|
|
|
|
export function buildDateMap(days: DayEntry[]): Map<string, DayEntry> {
|
|
const map = new Map<string, DayEntry>();
|
|
for (const d of days) {
|
|
map.set(d.date, d);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
export function getWeekInterval(weekStart: string) {
|
|
return weekStart === 'sunday' ? timeSunday : timeMonday;
|
|
}
|
|
|
|
export function generateCells(
|
|
begin: Date,
|
|
end: Date,
|
|
dateMap: Map<string, DayEntry>,
|
|
weekStart: string = 'monday',
|
|
): DayCell[] {
|
|
const weekInterval = getWeekInterval(weekStart);
|
|
const firstWeekDay = weekInterval.floor(begin);
|
|
const cells: DayCell[] = [];
|
|
let current = new Date(begin);
|
|
|
|
while (current <= end) {
|
|
const dateStr = DATE_FORMAT(current);
|
|
const weeksSinceStart = weekInterval.count(firstWeekDay, current);
|
|
const jsDay = current.getDay(); // 0=Sunday, 6=Saturday
|
|
const dayOfWeek = weekStart === 'sunday'
|
|
? jsDay // Sunday=0 already first
|
|
: (jsDay + 6) % 7; // Monday=0, Sunday=6
|
|
const isWeekend = jsDay === 0 || jsDay === 6;
|
|
|
|
cells.push({
|
|
date: new Date(current),
|
|
dateStr,
|
|
entry: dateMap.get(dateStr) || null,
|
|
week: weeksSinceStart,
|
|
day: dayOfWeek,
|
|
isWeekend,
|
|
});
|
|
|
|
current = timeDay.offset(current, 1);
|
|
}
|
|
|
|
return cells;
|
|
}
|