Skip to content

Commit c7395b6

Browse files
committed
refactor: statistics window
- Add a new custom `Chart` control - Remove third-party package `LiveChartsCore.SkiaSharpView.Avalonia` Signed-off-by: leo <longshuang@msn.cn>
1 parent bbf640b commit c7395b6

8 files changed

Lines changed: 435 additions & 181 deletions

File tree

THIRD-PARTY-LICENSES.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,25 @@ The project uses the following third-party libraries or assets
77
### AvaloniaUI
88

99
- **Source**: https://github.com/AvaloniaUI/Avalonia
10-
- **Version**: 11.3.15
10+
- **Version**: 12.0.4
1111
- **License**: MIT License
1212
- **License Link**: https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md
1313

1414
### Avalonia.Controls.DataGrid
1515

1616
- **Source**: https://github.com/AvaloniaUI/Avalonia.Controls.DataGrid
17-
- **Version**: 11.3.13
17+
- **Version**: 12.0.2
1818
- **License**: MIT License
1919
- **License Link**: https://github.com/AvaloniaUI/Avalonia.Controls.DataGrid/blob/master/licence.md
2020

2121
### AvaloniaEdit
2222

2323
- **Official Source**: https://github.com/AvaloniaUI/AvaloniaEdit
2424
- **Fork (Modified)**: https://github.com/love-linger/AvaloniaEdit
25-
- **Version**: 11.4.1
25+
- **Version**: Based on 12.0.x
2626
- **License**: MIT License
2727
- **License Link**: https://github.com/AvaloniaUI/AvaloniaEdit/blob/master/LICENSE
2828

29-
### LiveChartsCore.SkiaSharpView.Avalonia
30-
31-
- **Source**: https://github.com/beto-rodriguez/LiveCharts2
32-
- **Version**: 2.0.0
33-
- **License**: MIT License
34-
- **License Link**: https://github.com/beto-rodriguez/LiveCharts2/blob/master/LICENSE
35-
3629
### TextMateSharp
3730

3831
- **Source**: https://github.com/danipen/TextMateSharp

src/Models/Statistics.cs

Lines changed: 55 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,11 @@
22
using System.Collections.Generic;
33
using System.Globalization;
44

5-
using LiveChartsCore;
6-
using LiveChartsCore.Defaults;
7-
using LiveChartsCore.SkiaSharpView;
8-
using LiveChartsCore.SkiaSharpView.Painting;
9-
10-
using SkiaSharp;
11-
125
namespace 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

src/SourceGit.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
<PackageReference Include="Azure.AI.OpenAI" Version="2.9.0-beta.1" />
5757
<PackageReference Include="BitMiracle.LibTiff.NET" Version="2.4.660" />
5858
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
59-
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.1.0-dev-570" />
6059
<PackageReference Include="OpenAI" Version="2.10.0" />
6160
<PackageReference Include="Pfim" Version="0.11.4" />
6261
<PackageReference Include="StbImageSharp" Version="2.30.15" />

src/ViewModels/Preferences.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,6 @@ public string ExternalMergeToolMergeArgs
468468
}
469469
}
470470

471-
public uint StatisticsSampleColor
472-
{
473-
get => _statisticsSampleColor;
474-
set => SetProperty(ref _statisticsSampleColor, value);
475-
}
476-
477471
public List<RepositoryNode> RepositoryNodes
478472
{
479473
get;
@@ -846,6 +840,5 @@ private bool RemoveInvalidRepositoriesRecursive(List<RepositoryNode> collection)
846840

847841
private string _gitDefaultCloneDir = string.Empty;
848842
private int _shellOrTerminalType = -1;
849-
private uint _statisticsSampleColor = 0xFF00FF00;
850843
}
851844
}

0 commit comments

Comments
 (0)