Spaces:
Sleeping
Sleeping
fix
Browse files- src/components/charts.ts +1 -1
- src/main.ts +4 -9
- src/utils/metricAcwr.ts +3 -22
src/components/charts.ts
CHANGED
|
@@ -393,7 +393,7 @@ function createDualAxisChart(
|
|
| 393 |
type: 'scatter' as const,
|
| 394 |
label: `Predicted Daily ${metricLabel}`,
|
| 395 |
data: Array(historicalCount).fill(null).concat(
|
| 396 |
-
data.futureValues.map(v => v > 0 ? v : null)
|
| 397 |
),
|
| 398 |
backgroundColor: 'rgba(148, 163, 184, 0.6)',
|
| 399 |
borderColor: 'rgba(100, 116, 139, 0.8)',
|
|
|
|
| 393 |
type: 'scatter' as const,
|
| 394 |
label: `Predicted Daily ${metricLabel}`,
|
| 395 |
data: Array(historicalCount).fill(null).concat(
|
| 396 |
+
data.futureValues.map(v => (v !== null && v > 0) ? v : null)
|
| 397 |
),
|
| 398 |
backgroundColor: 'rgba(148, 163, 184, 0.6)',
|
| 399 |
borderColor: 'rgba(100, 116, 139, 0.8)',
|
src/main.ts
CHANGED
|
@@ -208,7 +208,6 @@ function renderCharts(activities: Activity[], targetAcwr: number, predictToday:
|
|
| 208 |
// Determine end date based on whether we'll include today in predictions
|
| 209 |
const today = new Date();
|
| 210 |
today.setHours(0, 0, 0, 0);
|
| 211 |
-
const todayStr = today.toISOString().split('T')[0];
|
| 212 |
|
| 213 |
// Check if today has activities
|
| 214 |
const todayHasActivities = activities.some(activity => {
|
|
@@ -242,29 +241,25 @@ function renderCharts(activities: Activity[], targetAcwr: number, predictToday:
|
|
| 242 |
activities,
|
| 243 |
(activity) => activity.distance,
|
| 244 |
dateRange,
|
| 245 |
-
targetAcwr
|
| 246 |
-
predictToday
|
| 247 |
);
|
| 248 |
const durationData = calculateMetricACWR(
|
| 249 |
activities,
|
| 250 |
(activity) => activity.duration,
|
| 251 |
dateRange,
|
| 252 |
-
targetAcwr
|
| 253 |
-
predictToday
|
| 254 |
);
|
| 255 |
const tssData = calculateMetricACWR(
|
| 256 |
activities,
|
| 257 |
(activity) => activity.trainingStressScore,
|
| 258 |
dateRange,
|
| 259 |
-
targetAcwr
|
| 260 |
-
predictToday
|
| 261 |
);
|
| 262 |
const caloriesData = calculateMetricACWR(
|
| 263 |
activities,
|
| 264 |
(activity) => activity.calories,
|
| 265 |
dateRange,
|
| 266 |
-
targetAcwr
|
| 267 |
-
predictToday
|
| 268 |
);
|
| 269 |
|
| 270 |
// Destroy existing charts
|
|
|
|
| 208 |
// Determine end date based on whether we'll include today in predictions
|
| 209 |
const today = new Date();
|
| 210 |
today.setHours(0, 0, 0, 0);
|
|
|
|
| 211 |
|
| 212 |
// Check if today has activities
|
| 213 |
const todayHasActivities = activities.some(activity => {
|
|
|
|
| 241 |
activities,
|
| 242 |
(activity) => activity.distance,
|
| 243 |
dateRange,
|
| 244 |
+
targetAcwr
|
|
|
|
| 245 |
);
|
| 246 |
const durationData = calculateMetricACWR(
|
| 247 |
activities,
|
| 248 |
(activity) => activity.duration,
|
| 249 |
dateRange,
|
| 250 |
+
targetAcwr
|
|
|
|
| 251 |
);
|
| 252 |
const tssData = calculateMetricACWR(
|
| 253 |
activities,
|
| 254 |
(activity) => activity.trainingStressScore,
|
| 255 |
dateRange,
|
| 256 |
+
targetAcwr
|
|
|
|
| 257 |
);
|
| 258 |
const caloriesData = calculateMetricACWR(
|
| 259 |
activities,
|
| 260 |
(activity) => activity.calories,
|
| 261 |
dateRange,
|
| 262 |
+
targetAcwr
|
|
|
|
| 263 |
);
|
| 264 |
|
| 265 |
// Destroy existing charts
|
src/utils/metricAcwr.ts
CHANGED
|
@@ -138,14 +138,12 @@ function calculateOptimalFutureDays(
|
|
| 138 |
* @param metricExtractor - Function to extract the metric value from an activity
|
| 139 |
* @param dateRange - Optional date range to maintain consistency
|
| 140 |
* @param targetACWR - Target ACWR value for predictions
|
| 141 |
-
* @param predictToday - If true, include today in predictions; if false, predictions start tomorrow
|
| 142 |
*/
|
| 143 |
export function calculateMetricACWR(
|
| 144 |
activities: Activity[],
|
| 145 |
metricExtractor: (activity: Activity) => number | undefined,
|
| 146 |
dateRange?: { start: Date; end: Date },
|
| 147 |
-
targetACWR: number = 1.3
|
| 148 |
-
predictToday: boolean = false
|
| 149 |
): MetricACWRData {
|
| 150 |
if (activities.length === 0 && !dateRange) {
|
| 151 |
return {
|
|
@@ -353,24 +351,7 @@ export function calculateMetricACWR(
|
|
| 353 |
todayValue: undefined,
|
| 354 |
activitiesByDate,
|
| 355 |
// Add future predictions if we have enough data
|
| 356 |
-
//
|
| 357 |
-
...(allDates.length >= 28 ? (
|
| 358 |
-
const today = new Date();
|
| 359 |
-
const todayStr = formatDateLocal(today);
|
| 360 |
-
const lastDateStr = formatDateLocal(allDates[allDates.length - 1]);
|
| 361 |
-
|
| 362 |
-
// Check if today is the last date in our data and if it has any activities
|
| 363 |
-
const todayHasActivities = todayStr === lastDateStr && dailyValues.has(todayStr);
|
| 364 |
-
|
| 365 |
-
// startOffset determines which day to start predictions from relative to lastDate
|
| 366 |
-
// startOffset=0: predictions start from lastDate + 1 (next day after last data)
|
| 367 |
-
// startOffset=1: predictions start from lastDate + 2 (skip one day)
|
| 368 |
-
// predictToday unchecked: start from next day (offset 0)
|
| 369 |
-
// predictToday checked and today has activities: start from next day (offset 0)
|
| 370 |
-
// predictToday checked and today has no activities: start from next day (offset 0), but lastDate was yesterday
|
| 371 |
-
const startOffset = 0;
|
| 372 |
-
|
| 373 |
-
return calculateOptimalFutureDays(allDates, dailyValues, targetACWR, 7, startOffset);
|
| 374 |
-
})() : {}),
|
| 375 |
};
|
| 376 |
}
|
|
|
|
| 138 |
* @param metricExtractor - Function to extract the metric value from an activity
|
| 139 |
* @param dateRange - Optional date range to maintain consistency
|
| 140 |
* @param targetACWR - Target ACWR value for predictions
|
|
|
|
| 141 |
*/
|
| 142 |
export function calculateMetricACWR(
|
| 143 |
activities: Activity[],
|
| 144 |
metricExtractor: (activity: Activity) => number | undefined,
|
| 145 |
dateRange?: { start: Date; end: Date },
|
| 146 |
+
targetACWR: number = 1.3
|
|
|
|
| 147 |
): MetricACWRData {
|
| 148 |
if (activities.length === 0 && !dateRange) {
|
| 149 |
return {
|
|
|
|
| 351 |
todayValue: undefined,
|
| 352 |
activitiesByDate,
|
| 353 |
// Add future predictions if we have enough data
|
| 354 |
+
// Predictions always start from the day after lastDate
|
| 355 |
+
...(allDates.length >= 28 ? calculateOptimalFutureDays(allDates, dailyValues, targetACWR, 7, 0) : {}),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 356 |
};
|
| 357 |
}
|