1- using System . Globalization ;
21using Microsoft . JSInterop ;
32
43namespace Tevling . Pages ;
54
65public partial class Statistics : ComponentBase , IAsyncDisposable
76{
7+ private record Stats
8+ {
9+ public required string Type { get ; init ; }
10+ public required float [ ] LastMonthsAggregate { get ; init ; }
11+ public double LastMonthsAverage => Math . Round ( LastMonthsAggregate . Average ( ) , 1 ) ;
12+ public double LastMonthsTotal => Math . Round ( LastMonthsAggregate . Sum ( ) , 1 ) ;
13+
14+ public float ThisMonth => LastMonthsAggregate [ ^ 1 ] ;
15+
16+ public double CurrentMonthComparedToAverage ( )
17+ {
18+ if ( LastMonthsAverage == 0 )
19+ {
20+ return 100 ;
21+ }
22+
23+ double difference =
24+ 100 * ( Math . Round ( ThisMonth , 1 ) / LastMonthsAverage ) ;
25+ if ( difference > 100 )
26+ {
27+ return difference - 100 ;
28+ }
29+
30+ return 100 - difference ;
31+ }
32+
33+ public string IncreaseVsDecrease ( )
34+ {
35+ if ( LastMonthsAverage == 0 )
36+ {
37+ return "<span style='color:green'>increase</span>" ;
38+ }
39+
40+ return Math . Round ( ThisMonth , 1 ) / LastMonthsAverage > 1
41+ ? "<span style='color:green'>increase</span>"
42+ : "<span style='color:red'>decrease</span>" ;
43+ }
44+ }
45+
46+
847 [ Inject ] private IJSRuntime Js { get ; set ; } = null ! ;
948 [ Inject ] private IAuthenticationService AuthenticationService { get ; set ; } = null ! ;
1049 [ Inject ] private IActivityService ActivityService { get ; set ; } = null ! ;
@@ -15,39 +54,45 @@ public partial class Statistics : ComponentBase, IAsyncDisposable
1554
1655 private int NumberOfMonthsToReview { get ; set ; } = 3 ;
1756 private ChallengeMeasurement Measurement { get ; set ; } = ChallengeMeasurement . Distance ;
18- private Dictionary < string , float [ ] > Distances { get ; set ; } = [ ] ;
19- private Dictionary < string , float [ ] > Elevations { get ; set ; } = [ ] ;
20- private Dictionary < string , float [ ] > Durations { get ; set ; } = [ ] ;
57+ private IReadOnlyList < Stats > Distances { get ; set ; } = [ ] ;
58+ private IReadOnlyList < Stats > Elevations { get ; set ; } = [ ] ;
59+ private IReadOnlyList < Stats > Durations { get ; set ; } = [ ] ;
2160
2261 protected override async Task OnInitializedAsync ( )
2362 {
2463 _athlete = await AuthenticationService . GetCurrentAthleteAsync ( ) ;
2564 await UpdateMeasurementData ( ) ;
2665 }
2766
28- private Dictionary < string , float [ ] > GetAggregatedMeasurementData ( Func < Activity , float > selector , int monthCount = 3 )
67+ private List < Stats > GetAggregatedMeasurementData ( Func < Activity , float > selector , int monthCount = 3 )
2968 {
3069 DateTimeOffset now = DateTimeOffset . Now ;
3170
32- Dictionary < string , float [ ] > aggregatedData = _activities
33- . GroupBy ( a => ActivityTypeExt . ToString ( a . Details . Type ) )
34- . ToDictionary (
35- g => g . Key . ToString ( ) ,
36- g => Enumerable . Range ( - monthCount + 1 , monthCount )
37- . Select ( m =>
71+ return
72+ [
73+ .. _activities
74+ . GroupBy ( a => ActivityTypeExt . ToString ( a . Details . Type ) )
75+ . ToDictionary (
76+ g => g . Key . ToString ( ) ,
77+ g => Enumerable . Range ( - monthCount + 1 , monthCount )
78+ . Select ( m =>
79+ {
80+ int month = now . AddMonths ( m ) . Month ;
81+ int year = now . AddMonths ( m ) . Year ;
82+ return g
83+ . Where ( a => a . Details . StartDate . Month == month && a . Details . StartDate . Year == year )
84+ . Sum ( selector ) ;
85+ } )
86+ . ToArray ( )
87+ )
88+ . Where ( d => d . Value . Any ( v => v > 0 ) )
89+ . Select ( kvp => new Stats
3890 {
39- int month = now . AddMonths ( m ) . Month ;
40- int year = now . AddMonths ( m ) . Year ;
41- return g
42- . Where ( a => a . Details . StartDate . Month == month && a . Details . StartDate . Year == year )
43- . Sum ( selector ) ;
44- } )
45- . ToArray ( )
46- )
47- . Where ( d => d . Value . Any ( v => v > 0 ) )
48- . ToDictionary ( ) ;
49-
50- return aggregatedData ;
91+ Type = kvp . Key ,
92+ LastMonthsAggregate = kvp . Value ,
93+ }
94+ ) ,
95+ ] ;
5196 }
5297
5398 private static string [ ] CreateMonthArray ( int monthCount )
@@ -79,14 +124,23 @@ private async Task UpdateMeasurementData()
79124 false ,
80125 DateTimeOffset . Now . AddMonths ( - NumberOfMonthsToReview + 1 ) . ToFirstOfTheMonth ( ) ) ;
81126 _activities = await ActivityService . GetActivitiesAsync ( filter ) ;
82-
83- Distances = GetAggregatedMeasurementData (
84- a => a . Details . DistanceInMeters / 1000 ,
85- NumberOfMonthsToReview ) ;
86- Elevations = GetAggregatedMeasurementData ( a => a . Details . TotalElevationGain , NumberOfMonthsToReview ) ;
87- Durations = GetAggregatedMeasurementData (
88- a => ( float ) a . Details . MovingTimeInSeconds / 3600 ,
89- NumberOfMonthsToReview ) ;
127+
128+ Distances =
129+ [
130+ .. GetAggregatedMeasurementData (
131+ a => a . Details . DistanceInMeters / 1000 ,
132+ NumberOfMonthsToReview ) ,
133+ ] ;
134+ Elevations =
135+ [
136+ .. GetAggregatedMeasurementData ( a => a . Details . TotalElevationGain , NumberOfMonthsToReview ) ,
137+ ] ;
138+ Durations =
139+ [
140+ .. GetAggregatedMeasurementData (
141+ a => ( float ) a . Details . MovingTimeInSeconds / 3600 ,
142+ NumberOfMonthsToReview ) ,
143+ ] ;
90144 }
91145
92146 private async Task DrawChart ( )
@@ -102,7 +156,7 @@ private async Task DrawChart()
102156 case ChallengeMeasurement . Distance :
103157 await _module . InvokeVoidAsync (
104158 "drawChart" ,
105- Distances ,
159+ Distances . ToDictionary ( stat => stat . Type , stat => stat . LastMonthsAggregate ) ,
106160 months ,
107161 "TheChart" ,
108162 "Total Distance [km]" ,
@@ -111,7 +165,7 @@ await _module.InvokeVoidAsync(
111165 case ChallengeMeasurement . Elevation :
112166 await _module . InvokeVoidAsync (
113167 "drawChart" ,
114- Elevations ,
168+ Elevations . ToDictionary ( stat => stat . Type , stat => stat . LastMonthsAggregate ) ,
115169 months ,
116170 "TheChart" ,
117171 "Total Elevation [m]" ,
@@ -120,7 +174,7 @@ await _module.InvokeVoidAsync(
120174 case ChallengeMeasurement . Time :
121175 await _module . InvokeVoidAsync (
122176 "drawChart" ,
123- Durations ,
177+ Durations . ToDictionary ( stat => stat . Type , stat => stat . LastMonthsAggregate ) ,
124178 months ,
125179 "TheChart" ,
126180 "Total Time [h]" ,
0 commit comments