22using System . Collections . Generic ;
33using System . Globalization ;
44
5- using LiveChartsCore ;
6- using LiveChartsCore . Defaults ;
7- using LiveChartsCore . SkiaSharpView ;
8- using LiveChartsCore . SkiaSharpView . Painting ;
9-
10- using SkiaSharp ;
11-
125namespace SourceGit . Models
136{
147 public enum StatisticsMode
158 {
16- All ,
9+ All = 0 ,
1710 ThisMonth ,
1811 ThisWeek ,
1912 }
@@ -24,45 +17,47 @@ public class StatisticsAuthor(User user, int count)
2417 public int Count { get ; set ; } = count ;
2518 }
2619
20+ public class StatisticsSample ( DateTime time , int count )
21+ {
22+ public DateTime Time { get ; set ; } = time ;
23+ public int Count { get ; set ; } = count ;
24+ }
25+
26+ public class StatisticsSeries
27+ {
28+ public int MaxSampleValue = 0 ;
29+ public DateTime MinSampleTime = DateTime . MaxValue ;
30+ public DateTime MaxSampleTime = DateTime . MinValue ;
31+ public Dictionary < DateTime , int > TotalSamples = null ;
32+ public Dictionary < DateTime , int > UserSamples = null ;
33+ }
34+
2735 public class StatisticsReport
2836 {
2937 public int Total { get ; set ; } = 0 ;
38+ public StatisticsMode Mode { get ; set ; } = StatisticsMode . All ;
3039 public List < StatisticsAuthor > Authors { get ; set ; } = new ( ) ;
31- public List < ISeries > Series { get ; set ; } = new ( ) ;
32- public List < Axis > XAxes { get ; set ; } = new ( ) ;
33- public List < Axis > YAxes { get ; set ; } = new ( ) ;
34- public StatisticsAuthor SelectedAuthor { get => _selectedAuthor ; set => ChangeAuthor ( value ) ; }
3540
3641 public StatisticsReport ( StatisticsMode mode , DateTime start )
3742 {
38- _mode = mode ;
39-
40- YAxes . Add ( new Axis ( )
41- {
42- TextSize = 10 ,
43- MinLimit = 0 ,
44- SeparatorsPaint = new SolidColorPaint ( new SKColor ( 0x40808080 ) ) { StrokeThickness = 1 }
45- } ) ;
43+ Mode = mode ;
4644
4745 if ( mode == StatisticsMode . ThisWeek )
4846 {
47+ _minSampleTime = start ;
48+ _maxSampleTime = start . AddDays ( 6 ) ;
49+
4950 for ( int i = 0 ; i < 7 ; i ++ )
5051 _mapSamples . Add ( start . AddDays ( i ) , 0 ) ;
51-
52- XAxes . Add ( new DateTimeAxis ( TimeSpan . FromDays ( 1 ) , v => WEEKDAYS [ ( int ) v . DayOfWeek ] ) { TextSize = 10 } ) ;
5352 }
5453 else if ( mode == StatisticsMode . ThisMonth )
5554 {
5655 var now = DateTime . Now ;
5756 var maxDays = DateTime . DaysInMonth ( now . Year , now . Month ) ;
57+ _minSampleTime = start ;
58+ _maxSampleTime = start . AddDays ( maxDays - 1 ) ;
5859 for ( int i = 0 ; i < maxDays ; i ++ )
5960 _mapSamples . Add ( start . AddDays ( i ) , 0 ) ;
60-
61- XAxes . Add ( new DateTimeAxis ( TimeSpan . FromDays ( 1 ) , v => $ "{ v : MM/dd} ") { TextSize = 10 } ) ;
62- }
63- else
64- {
65- XAxes . Add ( new DateTimeAxis ( TimeSpan . FromDays ( 30 ) , v => $ "{ v : yyyy/MM} ") { TextSize = 10 } ) ;
6661 }
6762 }
6863
@@ -71,10 +66,19 @@ public void AddCommit(DateTime time, User author)
7166 Total ++ ;
7267
7368 DateTime normalized ;
74- if ( _mode == StatisticsMode . ThisWeek || _mode == StatisticsMode . ThisMonth )
69+ if ( Mode == StatisticsMode . ThisWeek || Mode == StatisticsMode . ThisMonth )
70+ {
7571 normalized = time . Date ;
72+ }
7673 else
77- normalized = new DateTime ( time . Year , time . Month , 1 ) . ToLocalTime ( ) ;
74+ {
75+ normalized = new DateTime ( time . Year , time . Month , 1 ) . ToLocalTime ( ) . Date ;
76+
77+ if ( normalized < _minSampleTime )
78+ _minSampleTime = normalized ;
79+ if ( normalized > _maxSampleTime )
80+ _maxSampleTime = normalized ;
81+ }
7882
7983 if ( _mapSamples . TryGetValue ( normalized , out var vs ) )
8084 _mapSamples [ normalized ] = vs + 1 ;
@@ -95,10 +99,9 @@ public void AddCommit(DateTime time, User author)
9599 }
96100 else
97101 {
98- _mapUserSamples . Add ( author , new Dictionary < DateTime , int >
99- {
100- { normalized , 1 }
101- } ) ;
102+ var added = new Dictionary < DateTime , int > ( ) ;
103+ added . Add ( normalized , 1 ) ;
104+ _mapUserSamples . Add ( author , added ) ;
102105 }
103106 }
104107
@@ -107,76 +110,36 @@ public void Complete()
107110 foreach ( var kv in _mapUsers )
108111 Authors . Add ( new StatisticsAuthor ( kv . Key , kv . Value ) ) ;
109112
113+ _mapUsers . Clear ( ) ;
110114 Authors . Sort ( ( l , r ) => r . Count - l . Count ) ;
111115
112- var samples = new List < DateTimePoint > ( ) ;
113116 foreach ( var kv in _mapSamples )
114- samples . Add ( new DateTimePoint ( kv . Key , kv . Value ) ) ;
115-
116- Series . Add (
117- new ColumnSeries < DateTimePoint > ( )
118- {
119- Values = samples ,
120- Stroke = null ,
121- Fill = null ,
122- Padding = 1 ,
123- }
124- ) ;
125-
126- _mapUsers . Clear ( ) ;
127- _mapSamples . Clear ( ) ;
128- }
129-
130- public void ChangeColor ( uint color )
131- {
132- _fillColor = color ;
133-
134- var fill = new SKColor ( color ) ;
135-
136- if ( Series . Count > 0 && Series [ 0 ] is ColumnSeries < DateTimePoint > total )
137- total . Fill = new SolidColorPaint ( _selectedAuthor == null ? fill : fill . WithAlpha ( 51 ) ) ;
138-
139- if ( Series . Count > 1 && Series [ 1 ] is ColumnSeries < DateTimePoint > user )
140- user . Fill = new SolidColorPaint ( fill ) ;
117+ {
118+ if ( kv . Value > _maxSampleValue )
119+ _maxSampleValue = kv . Value ;
120+ }
141121 }
142122
143- public void ChangeAuthor ( StatisticsAuthor author )
123+ public StatisticsSeries GetStatisticsSeries ( StatisticsAuthor extraAuthor = null )
144124 {
145- if ( author == _selectedAuthor )
146- return ;
125+ var series = new StatisticsSeries ( ) ;
126+ series . MaxSampleValue = _maxSampleValue ;
127+ series . MinSampleTime = _minSampleTime ;
128+ series . MaxSampleTime = _maxSampleTime ;
129+ series . TotalSamples = _mapSamples ;
147130
148- _selectedAuthor = author ;
149- Series . RemoveRange ( 1 , Series . Count - 1 ) ;
150- if ( author == null || ! _mapUserSamples . TryGetValue ( author . User , out var userSamples ) )
151- {
152- ChangeColor ( _fillColor ) ;
153- return ;
154- }
131+ if ( extraAuthor != null && _mapUserSamples . TryGetValue ( extraAuthor . User , out var userSamples ) )
132+ series . UserSamples = userSamples ;
155133
156- var samples = new List < DateTimePoint > ( ) ;
157- foreach ( var kv in userSamples )
158- samples . Add ( new DateTimePoint ( kv . Key , kv . Value ) ) ;
159-
160- Series . Add (
161- new ColumnSeries < DateTimePoint > ( )
162- {
163- Values = samples ,
164- Stroke = null ,
165- Fill = null ,
166- Padding = 1 ,
167- }
168- ) ;
169-
170- ChangeColor ( _fillColor ) ;
134+ return series ;
171135 }
172136
173- private static readonly string [ ] WEEKDAYS = [ "SUN" , "MON" , "TUE" , "WED" , "THU" , "FRI" , "SAT" ] ;
174- private StatisticsMode _mode ;
137+ private DateTime _minSampleTime = DateTime . MaxValue ;
138+ private DateTime _maxSampleTime = DateTime . MinValue ;
139+ private int _maxSampleValue = 0 ;
175140 private Dictionary < User , int > _mapUsers = new ( ) ;
176141 private Dictionary < DateTime , int > _mapSamples = new ( ) ;
177142 private Dictionary < User , Dictionary < DateTime , int > > _mapUserSamples = new ( ) ;
178- private StatisticsAuthor _selectedAuthor = null ;
179- private uint _fillColor = 255 ;
180143 }
181144
182145 public class Statistics
@@ -207,7 +170,7 @@ public void AddCommit(string author, double timestamp)
207170 _users . Add ( email , user ) ;
208171 }
209172
210- var time = DateTime . UnixEpoch . AddSeconds ( timestamp ) . ToLocalTime ( ) ;
173+ var time = DateTime . UnixEpoch . AddSeconds ( timestamp ) . ToLocalTime ( ) . Date ;
211174 if ( time >= _thisWeekStart )
212175 Week . AddCommit ( time , user ) ;
213176
0 commit comments