glutamatt HF Staff commited on
Commit
0f92957
Β·
verified Β·
1 Parent(s): b10734b
index.html CHANGED
@@ -56,11 +56,17 @@
56
  </div>
57
 
58
  <div class="chart-container">
59
- <h2>πŸ”‹ TSS-based ACWR</h2>
60
  <div id="tss-target" class="target-info"></div>
61
  <canvas id="tss-chart"></canvas>
62
  </div>
63
 
 
 
 
 
 
 
64
  <div class="legend">
65
  <div class="legend-item">
66
  <span class="legend-color low"></span>
 
56
  </div>
57
 
58
  <div class="chart-container">
59
+ <h2>πŸ₯΅ TSS-based ACWR</h2>
60
  <div id="tss-target" class="target-info"></div>
61
  <canvas id="tss-chart"></canvas>
62
  </div>
63
 
64
+ <div class="chart-container">
65
+ <h2>πŸ”‹ Calories-based ACWR</h2>
66
+ <div id="calories-target" class="target-info"></div>
67
+ <canvas id="calories-chart"></canvas>
68
+ </div>
69
+
70
  <div class="legend">
71
  <div class="legend-item">
72
  <span class="legend-color low"></span>
src/components/charts.ts CHANGED
@@ -7,6 +7,7 @@ Chart.register(...registerables);
7
  let distanceChart: Chart | null = null;
8
  let durationChart: Chart | null = null;
9
  let tssChart: Chart | null = null;
 
10
 
11
  // ACWR color zones
12
  function getACWRColor(value: number | null): string {
@@ -327,6 +328,20 @@ export function createTSSChart(data: MetricACWRData): void {
327
  updateTargetInfo('tss-target', data.targetTomorrowValue, 'TSS', data.targetACWR);
328
  }
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  function updateTargetInfo(elementId: string, targetValue: number | null | undefined, unit: string, targetACWR: number | undefined): void {
331
  const element = document.getElementById(elementId);
332
  if (!element) return;
@@ -354,4 +369,8 @@ export function destroyAllCharts(): void {
354
  tssChart.destroy();
355
  tssChart = null;
356
  }
 
 
 
 
357
  }
 
7
  let distanceChart: Chart | null = null;
8
  let durationChart: Chart | null = null;
9
  let tssChart: Chart | null = null;
10
+ let caloriesChart: Chart | null = null;
11
 
12
  // ACWR color zones
13
  function getACWRColor(value: number | null): string {
 
328
  updateTargetInfo('tss-target', data.targetTomorrowValue, 'TSS', data.targetACWR);
329
  }
330
 
331
+ export function createCaloriesChart(data: MetricACWRData): void {
332
+ if (caloriesChart) {
333
+ caloriesChart.destroy();
334
+ }
335
+ caloriesChart = createDualAxisChart(
336
+ 'calories-chart',
337
+ data,
338
+ 'Calories',
339
+ '(kcal)',
340
+ 'rgba(234, 179, 8, 0.8)'
341
+ );
342
+ updateTargetInfo('calories-target', data.targetTomorrowValue, 'kcal', data.targetACWR);
343
+ }
344
+
345
  function updateTargetInfo(elementId: string, targetValue: number | null | undefined, unit: string, targetACWR: number | undefined): void {
346
  const element = document.getElementById(elementId);
347
  if (!element) return;
 
369
  tssChart.destroy();
370
  tssChart = null;
371
  }
372
+ if (caloriesChart) {
373
+ caloriesChart.destroy();
374
+ caloriesChart = null;
375
+ }
376
  }
src/main.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
  createDistanceChart,
7
  createDurationChart,
8
  createTSSChart,
 
9
  destroyAllCharts,
10
  } from './components/charts';
11
 
@@ -192,6 +193,11 @@ function renderCharts(activities: Activity[]): void {
192
  (activity) => activity.trainingStressScore,
193
  dateRange
194
  );
 
 
 
 
 
195
 
196
  // Destroy existing charts
197
  destroyAllCharts();
@@ -200,6 +206,7 @@ function renderCharts(activities: Activity[]): void {
200
  createDistanceChart(distanceData);
201
  createDurationChart(durationData);
202
  createTSSChart(tssData);
 
203
  }
204
 
205
  // Initialize
 
6
  createDistanceChart,
7
  createDurationChart,
8
  createTSSChart,
9
+ createCaloriesChart,
10
  destroyAllCharts,
11
  } from './components/charts';
12
 
 
193
  (activity) => activity.trainingStressScore,
194
  dateRange
195
  );
196
+ const caloriesData = calculateMetricACWR(
197
+ activities,
198
+ (activity) => activity.calories,
199
+ dateRange
200
+ );
201
 
202
  // Destroy existing charts
203
  destroyAllCharts();
 
206
  createDistanceChart(distanceData);
207
  createDurationChart(durationData);
208
  createTSSChart(tssData);
209
+ createCaloriesChart(caloriesData);
210
  }
211
 
212
  // Initialize
src/types/index.ts CHANGED
@@ -4,6 +4,7 @@ export interface Activity {
4
  distance?: number; // in kilometers
5
  duration?: number; // in minutes
6
  trainingStressScore?: number;
 
7
  }
8
 
9
  export interface ProcessedData {
 
4
  distance?: number; // in kilometers
5
  duration?: number; // in minutes
6
  trainingStressScore?: number;
7
+ calories?: number;
8
  }
9
 
10
  export interface ProcessedData {
src/utils/csvParser.ts CHANGED
@@ -117,12 +117,23 @@ export function parseCSV(file: File, userFTP: number = 343): Promise<Activity[]>
117
  // Get activity type
118
  const activityType = row['Activity Type'] || row['Type'] || row['Sport'];
119
 
 
 
 
 
 
 
 
 
 
 
120
  const activity: Activity = {
121
  date,
122
  activityType,
123
  distance,
124
  duration,
125
  trainingStressScore,
 
126
  };
127
 
128
  return activity;
 
117
  // Get activity type
118
  const activityType = row['Activity Type'] || row['Type'] || row['Sport'];
119
 
120
+ // Parse calories
121
+ const caloriesStr = row['Calories'];
122
+ let calories: number | undefined;
123
+ if (caloriesStr && caloriesStr !== '--') {
124
+ const parsed = parseFloat(caloriesStr);
125
+ if (!isNaN(parsed) && parsed > 0) {
126
+ calories = parsed;
127
+ }
128
+ }
129
+
130
  const activity: Activity = {
131
  date,
132
  activityType,
133
  distance,
134
  duration,
135
  trainingStressScore,
136
+ calories,
137
  };
138
 
139
  return activity;