bugfixes and some redesign
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Chart data transformation utilities for baby sleep tracker
|
||||
*/
|
||||
/**
|
||||
* Build timetable slots for visualization
|
||||
* @param slots - raw timetable slots from API
|
||||
* @returns grouped slots by date
|
||||
*/
|
||||
export function buildTimetableSlots(slots) {
|
||||
return slots.reduce((acc, slot) => {
|
||||
if (!acc[slot.date]) {
|
||||
acc[slot.date] = [];
|
||||
}
|
||||
acc[slot.date].push(slot);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
* Transform wakeup minutes for Recharts LineChart
|
||||
* @param days - wakeup/bedtime data from API
|
||||
* @returns array formatted for LineChart
|
||||
*/
|
||||
export function computeWakeupMinutes(days, wakeupRef = "04:00") {
|
||||
return days.map((day) => ({
|
||||
date: day.date,
|
||||
minutes: day.wakeup_minutes ?? 0,
|
||||
time: day.wakeup_minutes !== null
|
||||
? formatMinutesAfter(day.wakeup_minutes, wakeupRef)
|
||||
: "N/A",
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Transform bedtime minutes for Recharts LineChart
|
||||
* @param days - wakeup/bedtime data from API
|
||||
* @returns array formatted for LineChart
|
||||
*/
|
||||
export function computeBedtimeMinutes(days, bedtimeRef = "19:00") {
|
||||
return days.map((day) => ({
|
||||
date: day.date,
|
||||
minutes: day.bedtime_minutes ?? 0,
|
||||
time: day.bedtime_minutes !== null
|
||||
? formatMinutesAfter(day.bedtime_minutes, bedtimeRef)
|
||||
: "N/A",
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Transform daily summary for Recharts BarChart (vertical layout)
|
||||
* @param days - daily summary data from API
|
||||
* @returns array formatted for BarChart
|
||||
*/
|
||||
export function computeDailySummaryData(days) {
|
||||
return days.map((day) => ({
|
||||
date: day.date,
|
||||
daySleep: day.day_minutes,
|
||||
nightSleep: day.night_minutes,
|
||||
total: day.total_minutes,
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Calculate average summary stats from daily data
|
||||
* @param days - daily summary data from API
|
||||
* @returns averages for total, day, and night sleep
|
||||
*/
|
||||
export function computeAverageStats(days) {
|
||||
if (!days.length) {
|
||||
return { avgTotal: 0, avgDay: 0, avgNight: 0, count: 0 };
|
||||
}
|
||||
const totals = days.reduce((acc, day) => ({
|
||||
total: acc.total + day.total_minutes,
|
||||
day: acc.day + day.day_minutes,
|
||||
night: acc.night + day.night_minutes,
|
||||
}), { total: 0, day: 0, night: 0 });
|
||||
const count = days.length;
|
||||
return {
|
||||
avgTotal: Math.round(totals.total / count),
|
||||
avgDay: Math.round(totals.day / count),
|
||||
avgNight: Math.round(totals.night / count),
|
||||
count,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert minutes after reference to clock time string
|
||||
* Internal helper - kept for chartHelpers module
|
||||
*/
|
||||
function formatMinutesAfter(minutes, reference) {
|
||||
const [refHours, refMinutes] = reference.split(":").map(Number);
|
||||
const totalRefMinutes = refHours * 60 + refMinutes;
|
||||
const targetMinutes = totalRefMinutes + minutes;
|
||||
const normalizedMinutes = ((targetMinutes % 1440) + 1440) % 1440;
|
||||
const hours = Math.floor(normalizedMinutes / 60);
|
||||
const mins = normalizedMinutes % 60;
|
||||
return `${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
||||
}
|
||||
/**
|
||||
* Reverse date order (newest first for charts)
|
||||
* @param days - array of day data
|
||||
* @returns reversed array
|
||||
*/
|
||||
export function reverseDateOrder(days) {
|
||||
return [...days].reverse();
|
||||
}
|
||||
/**
|
||||
* Filter days to only include those with data
|
||||
* @param days - array of day data
|
||||
* @returns filtered array
|
||||
*/
|
||||
export function filterDaysWithData(days) {
|
||||
return days.filter((day) => (day.total_minutes ?? 0) > 0);
|
||||
}
|
||||
Reference in New Issue
Block a user