diff --git a/src/Models/Statistics.cs b/src/Models/Statistics.cs index 87a6eabd..d982a3ed 100644 --- a/src/Models/Statistics.cs +++ b/src/Models/Statistics.cs @@ -11,36 +11,31 @@ using SkiaSharp; namespace SourceGit.Models { - public enum StaticsticsMode + public enum StatisticsMode { All, ThisMonth, ThisWeek, } - public class StaticsticsAuthor(User user, int count) + public class StatisticsAuthor(User user, int count) { public User User { get; set; } = user; public int Count { get; set; } = count; } - public class StaticsticsSample(DateTime time, int count) - { - public DateTime Time { get; set; } = time; - public int Count { get; set; } = count; - } - public class StatisticsReport { public static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]; public int Total { get; set; } = 0; - public List Authors { get; set; } = new List(); + public List Authors { get; set; } = new List(); public List Series { get; set; } = new List(); public List XAxes { get; set; } = new List(); public List YAxes { get; set; } = new List(); + public StatisticsAuthor SelectedAuthor { get => _selectedAuthor; set => ChangeAuthor(value); } - public StatisticsReport(StaticsticsMode mode, DateTime start) + public StatisticsReport(StatisticsMode mode, DateTime start) { _mode = mode; @@ -51,14 +46,14 @@ namespace SourceGit.Models SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 } }]; - if (mode == StaticsticsMode.ThisWeek) + if (mode == StatisticsMode.ThisWeek) { for (int i = 0; i < 7; i++) _mapSamples.Add(start.AddDays(i), 0); XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(1), v => WEEKDAYS[(int)v.DayOfWeek]) { TextSize = 10 }); } - else if (mode == StaticsticsMode.ThisMonth) + else if (mode == StatisticsMode.ThisMonth) { var now = DateTime.Now; var maxDays = DateTime.DaysInMonth(now.Year, now.Month); @@ -78,7 +73,7 @@ namespace SourceGit.Models Total++; var normalized = DateTime.MinValue; - if (_mode == StaticsticsMode.ThisWeek || _mode == StaticsticsMode.ThisMonth) + if (_mode == StatisticsMode.ThisWeek || _mode == StatisticsMode.ThisMonth) normalized = time.Date; else normalized = new DateTime(time.Year, time.Month, 1).ToLocalTime(); @@ -92,10 +87,30 @@ namespace SourceGit.Models _mapUsers[author] = vu + 1; else _mapUsers.Add(author, 1); + + if (_mapUserSamples.TryGetValue(author, out var vus)) + { + if (vus.TryGetValue(normalized, out var n)) + vus[normalized] = n + 1; + else + vus.Add(normalized, 1); + } + else + { + _mapUserSamples.Add(author, new Dictionary + { + { normalized, 1 } + }); + } } public void Complete() { + foreach (var kv in _mapUsers) + Authors.Add(new StatisticsAuthor(kv.Key, kv.Value)); + + Authors.Sort((l, r) => r.Count - l.Count); + var samples = new List(); foreach (var kv in _mapSamples) samples.Add(new DateTimePoint(kv.Key, kv.Value)); @@ -110,24 +125,59 @@ namespace SourceGit.Models } ); - foreach (var kv in _mapUsers) - Authors.Add(new StaticsticsAuthor(kv.Key, kv.Value)); - - Authors.Sort((l, r) => r.Count - l.Count); - _mapUsers.Clear(); _mapSamples.Clear(); } public void ChangeColor(uint color) { - if (Series is [ColumnSeries series]) - series.Fill = new SolidColorPaint(new SKColor(color)); + _fillColor = color; + + var fill = new SKColor(color); + + if (Series.Count > 0 && Series[0] is ColumnSeries total) + total.Fill = new SolidColorPaint(_selectedAuthor == null ? fill : fill.WithAlpha(51)); + + if (Series.Count > 1 && Series[1] is ColumnSeries user) + user.Fill = new SolidColorPaint(fill); } - private StaticsticsMode _mode = StaticsticsMode.All; + public void ChangeAuthor(StatisticsAuthor author) + { + if (author == _selectedAuthor) + return; + + _selectedAuthor = author; + Series.RemoveRange(1, Series.Count - 1); + if (author == null || !_mapUserSamples.TryGetValue(author.User, out var userSamples)) + { + ChangeColor(_fillColor); + return; + } + + var samples = new List(); + foreach (var kv in userSamples) + samples.Add(new DateTimePoint(kv.Key, kv.Value)); + + Series.Add( + new ColumnSeries() + { + Values = samples, + Stroke = null, + Fill = null, + Padding = 1, + } + ); + + ChangeColor(_fillColor); + } + + private StatisticsMode _mode = StatisticsMode.All; private Dictionary _mapUsers = new Dictionary(); private Dictionary _mapSamples = new Dictionary(); + private Dictionary> _mapUserSamples = new Dictionary>(); + private StatisticsAuthor _selectedAuthor = null; + private uint _fillColor = 255; } public class Statistics @@ -143,9 +193,9 @@ namespace SourceGit.Models _thisWeekStart = _today.AddDays(-weekOffset); _thisMonthStart = _today.AddDays(1 - _today.Day); - All = new StatisticsReport(StaticsticsMode.All, DateTime.MinValue); - Month = new StatisticsReport(StaticsticsMode.ThisMonth, _thisMonthStart); - Week = new StatisticsReport(StaticsticsMode.ThisWeek, _thisWeekStart); + All = new StatisticsReport(StatisticsMode.All, DateTime.MinValue); + Month = new StatisticsReport(StatisticsMode.ThisMonth, _thisMonthStart); + Week = new StatisticsReport(StatisticsMode.ThisWeek, _thisWeekStart); } public void AddCommit(string author, double timestamp) diff --git a/src/ViewModels/Statistics.cs b/src/ViewModels/Statistics.cs index 68098a63..3a87607e 100644 --- a/src/ViewModels/Statistics.cs +++ b/src/ViewModels/Statistics.cs @@ -28,7 +28,11 @@ namespace SourceGit.ViewModels public Models.StatisticsReport SelectedReport { get => _selectedReport; - private set => SetProperty(ref _selectedReport, value); + private set + { + value?.ChangeAuthor(null); + SetProperty(ref _selectedReport, value); + } } public uint SampleColor diff --git a/src/Views/Statistics.axaml b/src/Views/Statistics.axaml index 3bbdafbe..577849df 100644 --- a/src/Views/Statistics.axaml +++ b/src/Views/Statistics.axaml @@ -139,6 +139,7 @@ - +