mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-20 19:55:00 +00:00
feature: allow to view contribution chart based on selected author (#1196)
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
90b37663ed
commit
33a463ce59
3 changed files with 81 additions and 26 deletions
|
@ -11,36 +11,31 @@ using SkiaSharp;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
public enum StaticsticsMode
|
public enum StatisticsMode
|
||||||
{
|
{
|
||||||
All,
|
All,
|
||||||
ThisMonth,
|
ThisMonth,
|
||||||
ThisWeek,
|
ThisWeek,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StaticsticsAuthor(User user, int count)
|
public class StatisticsAuthor(User user, int count)
|
||||||
{
|
{
|
||||||
public User User { get; set; } = user;
|
public User User { get; set; } = user;
|
||||||
public int Count { get; set; } = count;
|
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 class StatisticsReport
|
||||||
{
|
{
|
||||||
public static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
|
public static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
|
||||||
|
|
||||||
public int Total { get; set; } = 0;
|
public int Total { get; set; } = 0;
|
||||||
public List<StaticsticsAuthor> Authors { get; set; } = new List<StaticsticsAuthor>();
|
public List<StatisticsAuthor> Authors { get; set; } = new List<StatisticsAuthor>();
|
||||||
public List<ISeries> Series { get; set; } = new List<ISeries>();
|
public List<ISeries> Series { get; set; } = new List<ISeries>();
|
||||||
public List<Axis> XAxes { get; set; } = new List<Axis>();
|
public List<Axis> XAxes { get; set; } = new List<Axis>();
|
||||||
public List<Axis> YAxes { get; set; } = new List<Axis>();
|
public List<Axis> YAxes { get; set; } = new List<Axis>();
|
||||||
|
public StatisticsAuthor SelectedAuthor { get => _selectedAuthor; set => ChangeAuthor(value); }
|
||||||
|
|
||||||
public StatisticsReport(StaticsticsMode mode, DateTime start)
|
public StatisticsReport(StatisticsMode mode, DateTime start)
|
||||||
{
|
{
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
|
||||||
|
@ -51,14 +46,14 @@ namespace SourceGit.Models
|
||||||
SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 }
|
SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 }
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (mode == StaticsticsMode.ThisWeek)
|
if (mode == StatisticsMode.ThisWeek)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 7; i++)
|
for (int i = 0; i < 7; i++)
|
||||||
_mapSamples.Add(start.AddDays(i), 0);
|
_mapSamples.Add(start.AddDays(i), 0);
|
||||||
|
|
||||||
XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(1), v => WEEKDAYS[(int)v.DayOfWeek]) { TextSize = 10 });
|
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 now = DateTime.Now;
|
||||||
var maxDays = DateTime.DaysInMonth(now.Year, now.Month);
|
var maxDays = DateTime.DaysInMonth(now.Year, now.Month);
|
||||||
|
@ -78,7 +73,7 @@ namespace SourceGit.Models
|
||||||
Total++;
|
Total++;
|
||||||
|
|
||||||
var normalized = DateTime.MinValue;
|
var normalized = DateTime.MinValue;
|
||||||
if (_mode == StaticsticsMode.ThisWeek || _mode == StaticsticsMode.ThisMonth)
|
if (_mode == StatisticsMode.ThisWeek || _mode == StatisticsMode.ThisMonth)
|
||||||
normalized = time.Date;
|
normalized = time.Date;
|
||||||
else
|
else
|
||||||
normalized = new DateTime(time.Year, time.Month, 1).ToLocalTime();
|
normalized = new DateTime(time.Year, time.Month, 1).ToLocalTime();
|
||||||
|
@ -92,10 +87,30 @@ namespace SourceGit.Models
|
||||||
_mapUsers[author] = vu + 1;
|
_mapUsers[author] = vu + 1;
|
||||||
else
|
else
|
||||||
_mapUsers.Add(author, 1);
|
_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<DateTime, int>
|
||||||
|
{
|
||||||
|
{ normalized, 1 }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Complete()
|
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<DateTimePoint>();
|
var samples = new List<DateTimePoint>();
|
||||||
foreach (var kv in _mapSamples)
|
foreach (var kv in _mapSamples)
|
||||||
samples.Add(new DateTimePoint(kv.Key, kv.Value));
|
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();
|
_mapUsers.Clear();
|
||||||
_mapSamples.Clear();
|
_mapSamples.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeColor(uint color)
|
public void ChangeColor(uint color)
|
||||||
{
|
{
|
||||||
if (Series is [ColumnSeries<DateTimePoint> series])
|
_fillColor = color;
|
||||||
series.Fill = new SolidColorPaint(new SKColor(color));
|
|
||||||
|
var fill = new SKColor(color);
|
||||||
|
|
||||||
|
if (Series.Count > 0 && Series[0] is ColumnSeries<DateTimePoint> total)
|
||||||
|
total.Fill = new SolidColorPaint(_selectedAuthor == null ? fill : fill.WithAlpha(51));
|
||||||
|
|
||||||
|
if (Series.Count > 1 && Series[1] is ColumnSeries<DateTimePoint> 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<DateTimePoint>();
|
||||||
|
foreach (var kv in userSamples)
|
||||||
|
samples.Add(new DateTimePoint(kv.Key, kv.Value));
|
||||||
|
|
||||||
|
Series.Add(
|
||||||
|
new ColumnSeries<DateTimePoint>()
|
||||||
|
{
|
||||||
|
Values = samples,
|
||||||
|
Stroke = null,
|
||||||
|
Fill = null,
|
||||||
|
Padding = 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ChangeColor(_fillColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private StatisticsMode _mode = StatisticsMode.All;
|
||||||
private Dictionary<User, int> _mapUsers = new Dictionary<User, int>();
|
private Dictionary<User, int> _mapUsers = new Dictionary<User, int>();
|
||||||
private Dictionary<DateTime, int> _mapSamples = new Dictionary<DateTime, int>();
|
private Dictionary<DateTime, int> _mapSamples = new Dictionary<DateTime, int>();
|
||||||
|
private Dictionary<User, Dictionary<DateTime, int>> _mapUserSamples = new Dictionary<User, Dictionary<DateTime, int>>();
|
||||||
|
private StatisticsAuthor _selectedAuthor = null;
|
||||||
|
private uint _fillColor = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Statistics
|
public class Statistics
|
||||||
|
@ -143,9 +193,9 @@ namespace SourceGit.Models
|
||||||
_thisWeekStart = _today.AddDays(-weekOffset);
|
_thisWeekStart = _today.AddDays(-weekOffset);
|
||||||
_thisMonthStart = _today.AddDays(1 - _today.Day);
|
_thisMonthStart = _today.AddDays(1 - _today.Day);
|
||||||
|
|
||||||
All = new StatisticsReport(StaticsticsMode.All, DateTime.MinValue);
|
All = new StatisticsReport(StatisticsMode.All, DateTime.MinValue);
|
||||||
Month = new StatisticsReport(StaticsticsMode.ThisMonth, _thisMonthStart);
|
Month = new StatisticsReport(StatisticsMode.ThisMonth, _thisMonthStart);
|
||||||
Week = new StatisticsReport(StaticsticsMode.ThisWeek, _thisWeekStart);
|
Week = new StatisticsReport(StatisticsMode.ThisWeek, _thisWeekStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommit(string author, double timestamp)
|
public void AddCommit(string author, double timestamp)
|
||||||
|
|
|
@ -28,7 +28,11 @@ namespace SourceGit.ViewModels
|
||||||
public Models.StatisticsReport SelectedReport
|
public Models.StatisticsReport SelectedReport
|
||||||
{
|
{
|
||||||
get => _selectedReport;
|
get => _selectedReport;
|
||||||
private set => SetProperty(ref _selectedReport, value);
|
private set
|
||||||
|
{
|
||||||
|
value?.ChangeAuthor(null);
|
||||||
|
SetProperty(ref _selectedReport, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint SampleColor
|
public uint SampleColor
|
||||||
|
|
|
@ -139,6 +139,7 @@
|
||||||
<!-- Table By Autor -->
|
<!-- Table By Autor -->
|
||||||
<ListBox Grid.Column="0"
|
<ListBox Grid.Column="0"
|
||||||
ItemsSource="{Binding Authors}"
|
ItemsSource="{Binding Authors}"
|
||||||
|
SelectedItem="{Binding SelectedAuthor, Mode=TwoWay}"
|
||||||
SelectionMode="Single"
|
SelectionMode="Single"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
BorderBrush="{DynamicResource Brush.Border2}"
|
BorderBrush="{DynamicResource Brush.Border2}"
|
||||||
|
@ -160,7 +161,7 @@
|
||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
|
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate DataType="m:StaticsticsAuthor">
|
<DataTemplate DataType="m:StatisticsAuthor">
|
||||||
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}">
|
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}">
|
||||||
<Grid ColumnDefinitions="26,*,100">
|
<Grid ColumnDefinitions="26,*,100">
|
||||||
<v:Avatar Grid.Column="0"
|
<v:Avatar Grid.Column="0"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue