Skip to content

Commit ec6da97

Browse files
authored
Merge branch 'sourcegit-scm:develop' into develop
2 parents 1906be5 + 0d565f8 commit ec6da97

File tree

13 files changed

+148
-310
lines changed

13 files changed

+148
-310
lines changed

src/Commands/Statistics.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,43 @@ public class Statistics : Command
66
{
77
public Statistics(string repo)
88
{
9-
_statistics = new Models.Statistics();
10-
119
WorkingDirectory = repo;
1210
Context = repo;
13-
Args = $"log --date-order --branches --remotes --since=\"{_statistics.Since()}\" --pretty=format:\"%ct$%an\"";
11+
Args = $"log --date-order --branches --remotes -20000 --pretty=format:\"%ct$%aN\"";
1412
}
1513

1614
public Models.Statistics Result()
1715
{
18-
Exec();
19-
_statistics.Complete();
20-
return _statistics;
16+
var statistics = new Models.Statistics();
17+
var rs = ReadToEnd();
18+
if (!rs.IsSuccess)
19+
return statistics;
20+
21+
var start = 0;
22+
var end = rs.StdOut.IndexOf('\n', start);
23+
while (end > 0)
24+
{
25+
ParseLine(statistics, rs.StdOut.Substring(start, end - start));
26+
start = end + 1;
27+
end = rs.StdOut.IndexOf('\n', start);
28+
}
29+
30+
if (start < rs.StdOut.Length)
31+
ParseLine(statistics, rs.StdOut.Substring(start));
32+
33+
statistics.Complete();
34+
return statistics;
2135
}
2236

23-
protected override void OnReadline(string line)
37+
private void ParseLine(Models.Statistics statistics, string line)
2438
{
2539
var dateEndIdx = line.IndexOf('$', StringComparison.Ordinal);
2640
if (dateEndIdx == -1)
2741
return;
2842

2943
var dateStr = line.Substring(0, dateEndIdx);
3044
if (double.TryParse(dateStr, out var date))
31-
_statistics.AddCommit(line.Substring(dateEndIdx + 1), date);
45+
statistics.AddCommit(line.Substring(dateEndIdx + 1), date);
3246
}
33-
34-
private readonly Models.Statistics _statistics = null;
3547
}
3648
}

src/Models/Statistics.cs

Lines changed: 112 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,166 @@
11
using System;
22
using System.Collections.Generic;
33

4+
using LiveChartsCore;
5+
using LiveChartsCore.Defaults;
6+
using LiveChartsCore.SkiaSharpView;
7+
using LiveChartsCore.SkiaSharpView.Painting;
8+
9+
using SkiaSharp;
10+
411
namespace SourceGit.Models
512
{
6-
public class StatisticsSample(string name)
13+
public enum StaticsticsMode
14+
{
15+
All,
16+
ThisMonth,
17+
ThisWeek,
18+
}
19+
20+
public class StaticsticsAuthor(string name, int count)
721
{
822
public string Name { get; set; } = name;
9-
public int Count { get; set; } = 0;
23+
public int Count { get; set; } = count;
24+
}
25+
26+
public class StaticsticsSample(DateTime time, int count)
27+
{
28+
public DateTime Time { get; set; } = time;
29+
public int Count { get; set; } = count;
1030
}
1131

1232
public class StatisticsReport
1333
{
34+
public static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
35+
1436
public int Total { get; set; } = 0;
15-
public List<StatisticsSample> Samples { get; set; } = new List<StatisticsSample>();
16-
public List<StatisticsSample> ByAuthor { get; set; } = new List<StatisticsSample>();
37+
public List<StaticsticsAuthor> Authors { get; set; } = new List<StaticsticsAuthor>();
38+
public List<ISeries> Series { get; set; } = new List<ISeries>();
39+
public List<Axis> XAxes { get; set; } = new List<Axis>();
40+
public List<Axis> YAxes { get; set; } = new List<Axis>();
1741

18-
public void AddCommit(int index, string author)
42+
public StatisticsReport(StaticsticsMode mode, DateTime start)
1943
{
20-
Total++;
21-
Samples[index].Count++;
44+
_mode = mode;
45+
46+
YAxes = [new Axis() {
47+
TextSize = 10,
48+
MinLimit = 0,
49+
SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = .6f }
50+
}];
51+
52+
if (mode == StaticsticsMode.ThisWeek)
53+
{
54+
for (int i = 0; i < 7; i++)
55+
_mapSamples.Add(start.AddDays(i), 0);
2256

23-
if (_mapUsers.TryGetValue(author, out var value))
57+
XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(1), v => WEEKDAYS[(int)v.DayOfWeek]) { TextSize = 10 });
58+
}
59+
else if (mode == StaticsticsMode.ThisMonth)
2460
{
25-
value.Count++;
61+
var now = DateTime.Now;
62+
var maxDays = DateTime.DaysInMonth(now.Year, now.Month);
63+
for (int i = 0; i < maxDays; i++)
64+
_mapSamples.Add(start.AddDays(i), 0);
65+
66+
XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(1), v => $"{v:MM/dd}") { TextSize = 10 });
2667
}
2768
else
2869
{
29-
var sample = new StatisticsSample(author);
30-
sample.Count++;
31-
32-
_mapUsers.Add(author, sample);
33-
ByAuthor.Add(sample);
70+
XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(365), v => $"{v:yyyy/MM}") { TextSize = 10 });
3471
}
3572
}
3673

74+
public void AddCommit(DateTime time, string author)
75+
{
76+
Total++;
77+
78+
var normalized = DateTime.MinValue;
79+
if (_mode == StaticsticsMode.ThisWeek || _mode == StaticsticsMode.ThisMonth)
80+
normalized = time.Date;
81+
else
82+
normalized = new DateTime(time.Year, time.Month, 1).ToLocalTime();
83+
84+
if (_mapSamples.TryGetValue(normalized, out var vs))
85+
_mapSamples[normalized] = vs + 1;
86+
else
87+
_mapSamples.Add(normalized, 1);
88+
89+
if (_mapUsers.TryGetValue(author, out var vu))
90+
_mapUsers[author] = vu + 1;
91+
else
92+
_mapUsers.Add(author, 1);
93+
}
94+
3795
public void Complete()
3896
{
39-
ByAuthor.Sort((l, r) => r.Count - l.Count);
97+
var samples = new List<DateTimePoint>();
98+
foreach (var kv in _mapSamples)
99+
samples.Add(new DateTimePoint(kv.Key, kv.Value));
100+
101+
Series.Add(
102+
new LineSeries<DateTimePoint>()
103+
{
104+
Values = samples,
105+
Stroke = new SolidColorPaint(SKColors.Green) { StrokeThickness = 1 },
106+
Fill = new SolidColorPaint(SKColors.SkyBlue.WithAlpha(90)),
107+
GeometrySize = 8,
108+
GeometryStroke = new SolidColorPaint(SKColors.Green) { StrokeThickness = 2 }
109+
}
110+
);
111+
112+
foreach (var kv in _mapUsers)
113+
Authors.Add(new StaticsticsAuthor(kv.Key, kv.Value));
114+
115+
Authors.Sort((l, r) => r.Count - l.Count);
116+
40117
_mapUsers.Clear();
118+
_mapSamples.Clear();
41119
}
42120

43-
private readonly Dictionary<string, StatisticsSample> _mapUsers = new Dictionary<string, StatisticsSample>();
121+
private StaticsticsMode _mode = StaticsticsMode.All;
122+
private Dictionary<string, int> _mapUsers = new Dictionary<string, int>();
123+
private Dictionary<DateTime, int> _mapSamples = new Dictionary<DateTime, int>();
44124
}
45125

46126
public class Statistics
47127
{
48-
public StatisticsReport Year { get; set; } = new StatisticsReport();
49-
public StatisticsReport Month { get; set; } = new StatisticsReport();
50-
public StatisticsReport Week { get; set; } = new StatisticsReport();
128+
public StatisticsReport All { get; set; }
129+
public StatisticsReport Month { get; set; }
130+
public StatisticsReport Week { get; set; }
51131

52132
public Statistics()
53133
{
54-
_today = DateTime.Today;
55-
_thisWeekStart = _today.AddSeconds(-(int)_today.DayOfWeek * 3600 * 24 - _today.Hour * 3600 - _today.Minute * 60 - _today.Second);
56-
_thisWeekEnd = _thisWeekStart.AddDays(7);
57-
58-
for (int i = 0; i < 12; i++)
59-
Year.Samples.Add(new StatisticsSample(""));
60-
61-
var monthDays = DateTime.DaysInMonth(_today.Year, _today.Month);
62-
for (int i = 0; i < monthDays; i++)
63-
Month.Samples.Add(new StatisticsSample($"{i + 1}"));
134+
_today = DateTime.Now.ToLocalTime().Date;
135+
_thisWeekStart = _today.AddSeconds(-(int)_today.DayOfWeek * 3600 * 24);
136+
_thisMonthStart = _today.AddDays(1 - _today.Day);
64137

65-
string[] weekDayNames = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
66-
for (int i = 0; i < weekDayNames.Length; i++)
67-
Week.Samples.Add(new StatisticsSample(weekDayNames[i]));
68-
}
69-
70-
public string Since()
71-
{
72-
return _today.AddMonths(-11).ToString("yyyy-MM-01 00:00:00");
138+
All = new StatisticsReport(StaticsticsMode.All, DateTime.MinValue);
139+
Month = new StatisticsReport(StaticsticsMode.ThisMonth, _thisMonthStart);
140+
Week = new StatisticsReport(StaticsticsMode.ThisWeek, _thisWeekStart);
73141
}
74142

75143
public void AddCommit(string author, double timestamp)
76144
{
77145
var time = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime();
78-
if (time.CompareTo(_thisWeekStart) >= 0 && time.CompareTo(_thisWeekEnd) < 0)
79-
Week.AddCommit((int)time.DayOfWeek, author);
146+
if (time >= _thisWeekStart)
147+
Week.AddCommit(time, author);
80148

81-
if (time.Month == _today.Month)
82-
Month.AddCommit(time.Day - 1, author);
149+
if (time >= _thisMonthStart)
150+
Month.AddCommit(time, author);
83151

84-
Year.AddCommit(time.Month - 1, author);
152+
All.AddCommit(time, author);
85153
}
86154

87155
public void Complete()
88156
{
89-
Year.Complete();
157+
All.Complete();
90158
Month.Complete();
91159
Week.Complete();
92-
93-
// Year is start from 11 months ago from now.
94-
var thisYear = _today.Year;
95-
var start = _today.AddMonths(-11);
96-
if (start.Month == 1)
97-
{
98-
for (int i = 0; i < 12; i++)
99-
Year.Samples[i].Name = $"{thisYear}/{i + 1:00}";
100-
}
101-
else
102-
{
103-
var lastYearIdx = start.Month - 1;
104-
var lastYearMonths = Year.Samples.GetRange(lastYearIdx, 12 - lastYearIdx);
105-
for (int i = 0; i < lastYearMonths.Count; i++)
106-
lastYearMonths[i].Name = $"{thisYear - 1}/{lastYearIdx + i + 1:00}";
107-
108-
var thisYearMonths = Year.Samples.GetRange(0, lastYearIdx);
109-
for (int i = 0; i < thisYearMonths.Count; i++)
110-
thisYearMonths[i].Name = $"{thisYear}/{i + 1:00}";
111-
112-
Year.Samples.Clear();
113-
Year.Samples.AddRange(lastYearMonths);
114-
Year.Samples.AddRange(thisYearMonths);
115-
}
116160
}
117161

118162
private readonly DateTime _today;
163+
private readonly DateTime _thisMonthStart;
119164
private readonly DateTime _thisWeekStart;
120-
private readonly DateTime _thisWeekEnd;
121165
}
122166
}

src/Resources/Locales/de_DE.axaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,6 @@
567567
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
568568
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONAT</x:String>
569569
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WOCHE</x:String>
570-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">JAHR</x:String>
571570
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
572571
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTOREN: </x:String>
573572
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULE</x:String>

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,9 @@
571571
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
572572
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONTH</x:String>
573573
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WEEK</x:String>
574-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">YEAR</x:String>
575574
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
576575
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTHORS: </x:String>
576+
<x:String x:Key="Text.Statistics.Overview" xml:space="preserve">OVERVIEW</x:String>
577577
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>
578578
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String>
579579
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String>

src/Resources/Locales/fr_FR.axaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,6 @@
552552
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
553553
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONTH</x:String>
554554
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WEEK</x:String>
555-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">YEAR</x:String>
556555
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
557556
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTHORS: </x:String>
558557
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>

src/Resources/Locales/pt_BR.axaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,6 @@
545545
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
546546
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MÊS</x:String>
547547
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">SEMANA</x:String>
548-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">ANO</x:String>
549548
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
550549
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTORES: </x:String>
551550
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String>

src/Resources/Locales/ru_RU.axaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,6 @@
571571
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">ФИКСАТОРЫ</x:String>
572572
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">МЕСЯЦ</x:String>
573573
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">НЕДЕЛЯ</x:String>
574-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">ГОД</x:String>
575574
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">ФИКСАЦИИ: </x:String>
576575
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">АВТОРЫ: </x:String>
577576
<x:String x:Key="Text.Submodule" xml:space="preserve">ПОДМОДУЛИ</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,9 @@
569569
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">提交者</x:String>
570570
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">本月</x:String>
571571
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">本周</x:String>
572-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">最近一年</x:String>
573572
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">提交次数: </x:String>
574573
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">贡献者人数: </x:String>
574+
<x:String x:Key="Text.Statistics.Overview" xml:space="preserve">总览</x:String>
575575
<x:String x:Key="Text.Submodule" xml:space="preserve">子模块</x:String>
576576
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">添加子模块</x:String>
577577
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">复制路径</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,9 @@
574574
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">提交者</x:String>
575575
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">本月</x:String>
576576
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">本週</x:String>
577-
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">最近一年</x:String>
578577
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">提交次數:</x:String>
579578
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">貢獻者人數:</x:String>
579+
<x:String x:Key="Text.Statistics.Overview" xml:space="preserve">總覽</x:String>
580580
<x:String x:Key="Text.Submodule" xml:space="preserve">子模組</x:String>
581581
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">新增子模組</x:String>
582582
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">複製路徑</x:String>

src/SourceGit.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
<PackageReference Include="Avalonia.Diagnostics" Version="11.1.3" Condition="'$(Configuration)' == 'Debug'" />
4646
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
4747
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
48-
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
48+
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
49+
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc3.3" />
4950
<PackageReference Include="TextMateSharp" Version="1.0.63" />
5051
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.63" />
5152
</ItemGroup>

0 commit comments

Comments
 (0)