mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
feature<Statistics>: add simple statistic page
This commit is contained in:
parent
f04c01b878
commit
c52ed4a711
10 changed files with 512 additions and 0 deletions
15
src/Models/StatisticSample.cs
Normal file
15
src/Models/StatisticSample.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace SourceGit.Models {
|
||||||
|
/// <summary>
|
||||||
|
/// 统计图表样品
|
||||||
|
/// </summary>
|
||||||
|
public class StatisticSample {
|
||||||
|
/// <summary>
|
||||||
|
/// 样品名
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 提交个数
|
||||||
|
/// </summary>
|
||||||
|
public int Count { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
<Geometry x:Key="Icon.Preference">M716.3 383.1c0 38.4-6.5 76-19.4 111.8l-10.7 29.7 229.6 229.5c44.5 44.6 44.5 117.1 0 161.6a113.6 113.6 0 01-80.8 33.5a113.6 113.6 0 01-80.8-33.5L529 694l-32 13a331.6 331.6 0 01-111.9 19.4A333.5 333.5 0 0150 383.1c0-39 6.8-77.2 20-113.6L285 482l194-195-214-210A331 331 0 01383.1 50A333.5 333.5 0 01716.3 383.1zM231.6 31.6l-22.9 9.9a22.2 22.2 0 00-5.9 4.2a19.5 19.5 0 000 27.5l215 215.2L288.4 417.8 77.8 207.1a26 26 0 00-17.2-7.1a22.8 22.8 0 00-21.5 15a400.5 400.5 0 00-7.5 16.6A381.6 381.6 0 000 384c0 211.7 172.2 384 384 384c44.3 0 87.6-7.5 129-22.3L743.1 975.8A163.5 163.5 0 00859.5 1024c43.9 0 85.3-17.1 116.4-48.2a164.8 164.8 0 000-233L745.5 513C760.5 471.5 768 428 768 384C768 172 596 0 384 0c-53 0-104 10.5-152.5 31.5z</Geometry>
|
<Geometry x:Key="Icon.Preference">M716.3 383.1c0 38.4-6.5 76-19.4 111.8l-10.7 29.7 229.6 229.5c44.5 44.6 44.5 117.1 0 161.6a113.6 113.6 0 01-80.8 33.5a113.6 113.6 0 01-80.8-33.5L529 694l-32 13a331.6 331.6 0 01-111.9 19.4A333.5 333.5 0 0150 383.1c0-39 6.8-77.2 20-113.6L285 482l194-195-214-210A331 331 0 01383.1 50A333.5 333.5 0 01716.3 383.1zM231.6 31.6l-22.9 9.9a22.2 22.2 0 00-5.9 4.2a19.5 19.5 0 000 27.5l215 215.2L288.4 417.8 77.8 207.1a26 26 0 00-17.2-7.1a22.8 22.8 0 00-21.5 15a400.5 400.5 0 00-7.5 16.6A381.6 381.6 0 000 384c0 211.7 172.2 384 384 384c44.3 0 87.6-7.5 129-22.3L743.1 975.8A163.5 163.5 0 00859.5 1024c43.9 0 85.3-17.1 116.4-48.2a164.8 164.8 0 000-233L745.5 513C760.5 471.5 768 428 768 384C768 172 596 0 384 0c-53 0-104 10.5-152.5 31.5z</Geometry>
|
||||||
<Geometry x:Key="Icon.Setting">M928 500a21 21 0 00-19-20L858 472a11 11 0 01-9-9c-1-6-2-13-3-19a11 11 0 015-12l46-25a21 21 0 0010-26l-8-22a21 21 0 00-24-13l-51 10a11 11 0 01-12-6c-3-6-6-11-10-17a11 11 0 011-13l34-39a21 21 0 001-28l-15-18a20 20 0 00-27-4l-45 27a11 11 0 01-13-1c-5-4-10-9-15-12a11 11 0 01-3-12l19-49a21 21 0 00-9-26l-20-12a21 21 0 00-27 6L650 193a9 9 0 01-11 3c-1-1-12-5-20-7a11 11 0 01-7-10l1-52a21 21 0 00-17-22l-23-4a21 21 0 00-24 14L532 164a11 11 0 01-11 7h-20a11 11 0 01-11-7l-17-49a21 21 0 00-24-15l-23 4a21 21 0 00-17 22l1 52a11 11 0 01-8 11c-5 2-15 6-19 7c-4 1-8 0-12-4l-33-40A21 21 0 00313 146l-20 12A21 21 0 00285 184l19 49a11 11 0 01-3 12c-5 4-10 8-15 12a11 11 0 01-13 1L228 231a21 21 0 00-27 4L186 253a21 21 0 001 28L221 320a11 11 0 011 13c-3 5-7 11-10 17a11 11 0 01-12 6l-51-10a21 21 0 00-24 13l-8 22a21 21 0 0010 26l46 25a11 11 0 015 12l0 3c-1 6-2 11-3 16a11 11 0 01-9 9l-51 8A21 21 0 0096 500v23A21 21 0 00114 544l51 8a11 11 0 019 9c1 6 2 13 3 19a11 11 0 01-5 12l-46 25a21 21 0 00-10 26l8 22a21 21 0 0024 13l51-10a11 11 0 0112 6c3 6 6 11 10 17a11 11 0 01-1 13l-34 39a21 21 0 00-1 28l15 18a20 20 0 0027 4l45-27a11 11 0 0113 1c5 4 10 9 15 12a11 11 0 013 12l-19 49a21 21 0 009 26l20 12a21 21 0 0027-6L374 832c3-3 7-5 10-4c7 3 12 5 20 7a11 11 0 018 10l-1 52a21 21 0 0017 22l23 4a21 21 0 0024-14l17-50a11 11 0 0111-7h20a11 11 0 0111 7l17 49a21 21 0 0020 15a19 19 0 004 0l23-4a21 21 0 0017-22l-1-52a11 11 0 018-10c8-3 13-5 18-7l1 0c6-2 9 0 11 3l34 41A21 21 0 00710 878l20-12a21 21 0 009-26l-18-49a11 11 0 013-12c5-4 10-8 15-12a11 11 0 0113-1l45 27a21 21 0 0027-4l15-18a21 21 0 00-1-28l-34-39a11 11 0 01-1-13c3-5 7-11 10-17a11 11 0 0112-6l51 10a21 21 0 0024-13l8-22a21 21 0 00-10-26l-46-25a11 11 0 01-5-12l0-3c1-6 2-11 3-16a11 11 0 019-9l51-8a21 21 0 0018-21v-23zm-565 188a32 32 0 01-51 5a270 270 0 011-363a32 32 0 0151 6l91 161a32 32 0 010 31zM512 782a270 270 0 01-57-6a32 32 0 01-20-47l92-160a32 32 0 0127-16h184a32 32 0 0130 41c-35 109-137 188-257 188zm15-328L436 294a32 32 0 0121-47a268 268 0 0155-6c120 0 222 79 257 188a32 32 0 01-30 41h-184a32 32 0 01-28-16z</Geometry>
|
<Geometry x:Key="Icon.Setting">M928 500a21 21 0 00-19-20L858 472a11 11 0 01-9-9c-1-6-2-13-3-19a11 11 0 015-12l46-25a21 21 0 0010-26l-8-22a21 21 0 00-24-13l-51 10a11 11 0 01-12-6c-3-6-6-11-10-17a11 11 0 011-13l34-39a21 21 0 001-28l-15-18a20 20 0 00-27-4l-45 27a11 11 0 01-13-1c-5-4-10-9-15-12a11 11 0 01-3-12l19-49a21 21 0 00-9-26l-20-12a21 21 0 00-27 6L650 193a9 9 0 01-11 3c-1-1-12-5-20-7a11 11 0 01-7-10l1-52a21 21 0 00-17-22l-23-4a21 21 0 00-24 14L532 164a11 11 0 01-11 7h-20a11 11 0 01-11-7l-17-49a21 21 0 00-24-15l-23 4a21 21 0 00-17 22l1 52a11 11 0 01-8 11c-5 2-15 6-19 7c-4 1-8 0-12-4l-33-40A21 21 0 00313 146l-20 12A21 21 0 00285 184l19 49a11 11 0 01-3 12c-5 4-10 8-15 12a11 11 0 01-13 1L228 231a21 21 0 00-27 4L186 253a21 21 0 001 28L221 320a11 11 0 011 13c-3 5-7 11-10 17a11 11 0 01-12 6l-51-10a21 21 0 00-24 13l-8 22a21 21 0 0010 26l46 25a11 11 0 015 12l0 3c-1 6-2 11-3 16a11 11 0 01-9 9l-51 8A21 21 0 0096 500v23A21 21 0 00114 544l51 8a11 11 0 019 9c1 6 2 13 3 19a11 11 0 01-5 12l-46 25a21 21 0 00-10 26l8 22a21 21 0 0024 13l51-10a11 11 0 0112 6c3 6 6 11 10 17a11 11 0 01-1 13l-34 39a21 21 0 00-1 28l15 18a20 20 0 0027 4l45-27a11 11 0 0113 1c5 4 10 9 15 12a11 11 0 013 12l-19 49a21 21 0 009 26l20 12a21 21 0 0027-6L374 832c3-3 7-5 10-4c7 3 12 5 20 7a11 11 0 018 10l-1 52a21 21 0 0017 22l23 4a21 21 0 0024-14l17-50a11 11 0 0111-7h20a11 11 0 0111 7l17 49a21 21 0 0020 15a19 19 0 004 0l23-4a21 21 0 0017-22l-1-52a11 11 0 018-10c8-3 13-5 18-7l1 0c6-2 9 0 11 3l34 41A21 21 0 00710 878l20-12a21 21 0 009-26l-18-49a11 11 0 013-12c5-4 10-8 15-12a11 11 0 0113-1l45 27a21 21 0 0027-4l15-18a21 21 0 00-1-28l-34-39a11 11 0 01-1-13c3-5 7-11 10-17a11 11 0 0112-6l51 10a21 21 0 0024-13l8-22a21 21 0 00-10-26l-46-25a11 11 0 01-5-12l0-3c1-6 2-11 3-16a11 11 0 019-9l51-8a21 21 0 0018-21v-23zm-565 188a32 32 0 01-51 5a270 270 0 011-363a32 32 0 0151 6l91 161a32 32 0 010 31zM512 782a270 270 0 01-57-6a32 32 0 01-20-47l92-160a32 32 0 0127-16h184a32 32 0 0130 41c-35 109-137 188-257 188zm15-328L436 294a32 32 0 0121-47a268 268 0 0155-6c120 0 222 79 257 188a32 32 0 01-30 41h-184a32 32 0 01-28-16z</Geometry>
|
||||||
|
<Geometry x:Key="Icon.Statistics">M296 912H120c-4.4 0-8-3.6-8-8V520c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v384c0 4.4-3.6 8-8 8zM600 912H424c-4.4 0-8-3.6-8-8V121c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v783c0 4.4-3.6 8-8 8zM904 912H728c-4.4 0-8-3.6-8-8V280c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v624c0 4.4-3.6 8-8 8z</Geometry>
|
||||||
<Geometry x:Key="Icon.Help">M550 627h-81v-21a142 142 0 0113-64a198 198 0 0152-57a390 390 0 0047-42a56 56 0 0012-34a58 58 0 00-21-45a81 81 0 00-56-19a85 85 0 00-57 20a103 103 0 00-32 59l-82-10a136 136 0 0149-96A172 172 0 01512 276a178 178 0 01123 40a122 122 0 0145 94a103 103 0 01-17 56a366 366 0 01-71 72A136 136 0 00556 576a128 128 0 00-6 51zm-81 120v-89h89v89zM512 64a448 448 0 10448 448A448 448 0 00512 64zm0 832a384 384 0 010-768a389 389 0 01384 384a389 389 0 01-384 384z</Geometry>
|
<Geometry x:Key="Icon.Help">M550 627h-81v-21a142 142 0 0113-64a198 198 0 0152-57a390 390 0 0047-42a56 56 0 0012-34a58 58 0 00-21-45a81 81 0 00-56-19a85 85 0 00-57 20a103 103 0 00-32 59l-82-10a136 136 0 0149-96A172 172 0 01512 276a178 178 0 01123 40a122 122 0 0145 94a103 103 0 01-17 56a366 366 0 01-71 72A136 136 0 00556 576a128 128 0 00-6 51zm-81 120v-89h89v89zM512 64a448 448 0 10448 448A448 448 0 00512 64zm0 832a384 384 0 010-768a389 389 0 01384 384a389 389 0 01-384 384z</Geometry>
|
||||||
<Geometry x:Key="Icon.Folder">M64 864h896V288h-396a64 64 0 01-57-35L460 160H64v704zm-64 32V128a32 32 0 0132-32h448a32 32 0 0129 18L564 224H992a32 32 0 0132 32v640a32 32 0 01-32 32H32a32 32 0 01-32-32z</Geometry>
|
<Geometry x:Key="Icon.Folder">M64 864h896V288h-396a64 64 0 01-57-35L460 160H64v704zm-64 32V128a32 32 0 0132-32h448a32 32 0 0129 18L564 224H992a32 32 0 0132 32v640a32 32 0 01-32 32H32a32 32 0 01-32-32z</Geometry>
|
||||||
<Geometry x:Key="Icon.Folder.Fill">M448 64l128 128h448v768H0V64z</Geometry>
|
<Geometry x:Key="Icon.Folder.Fill">M448 64l128 128h448v768H0V64z</Geometry>
|
||||||
|
|
|
@ -121,6 +121,7 @@
|
||||||
<sys:String x:Key="Text.Dashboard.Terminal">Open In Git Bash</sys:String>
|
<sys:String x:Key="Text.Dashboard.Terminal">Open In Git Bash</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Refresh">Refresh</sys:String>
|
<sys:String x:Key="Text.Dashboard.Refresh">Refresh</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Search">Search Commit</sys:String>
|
<sys:String x:Key="Text.Dashboard.Search">Search Commit</sys:String>
|
||||||
|
<sys:String x:Key="Text.Dashboard.Statistics">Statistics</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Configure">Configure this repository</sys:String>
|
<sys:String x:Key="Text.Dashboard.Configure">Configure this repository</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Workspace">WORKSPACE</sys:String>
|
<sys:String x:Key="Text.Dashboard.Workspace">WORKSPACE</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.LocalBranches">LOCAL BRANCHES</sys:String>
|
<sys:String x:Key="Text.Dashboard.LocalBranches">LOCAL BRANCHES</sys:String>
|
||||||
|
@ -487,6 +488,14 @@
|
||||||
<sys:String x:Key="Text.Squash.To">To :</sys:String>
|
<sys:String x:Key="Text.Squash.To">To :</sys:String>
|
||||||
<sys:String x:Key="Text.Squash.Message">Reword :</sys:String>
|
<sys:String x:Key="Text.Squash.Message">Reword :</sys:String>
|
||||||
|
|
||||||
|
<sys:String x:Key="Text.Statistics">Statistics</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.ThisWeek">WEEK</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.ThisMonth">MONTH</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.TotalCommitterCount">Total Committers: {0}</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.TotalCommitsCount">Total Commits:{0}</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.CommitterName">COMMITTER</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.CommitAmount">COMMITS</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="Text.NotConfigured">Git has NOT been configured. Please to go [Preference] and configure it first.</sys:String>
|
<sys:String x:Key="Text.NotConfigured">Git has NOT been configured. Please to go [Preference] and configure it first.</sys:String>
|
||||||
<sys:String x:Key="Text.PathNotFound">Path[{0}] not exists!</sys:String>
|
<sys:String x:Key="Text.PathNotFound">Path[{0}] not exists!</sys:String>
|
||||||
<sys:String x:Key="Text.MissingBash">Can NOT locate bash.exe. Make sure bash.exe exists under the same folder with git.exe</sys:String>
|
<sys:String x:Key="Text.MissingBash">Can NOT locate bash.exe. Make sure bash.exe exists under the same folder with git.exe</sys:String>
|
||||||
|
|
|
@ -120,6 +120,7 @@
|
||||||
<sys:String x:Key="Text.Dashboard.Terminal">在GIT终端中打开</sys:String>
|
<sys:String x:Key="Text.Dashboard.Terminal">在GIT终端中打开</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Refresh">重新加载</sys:String>
|
<sys:String x:Key="Text.Dashboard.Refresh">重新加载</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Search">查找提交</sys:String>
|
<sys:String x:Key="Text.Dashboard.Search">查找提交</sys:String>
|
||||||
|
<sys:String x:Key="Text.Dashboard.Statistics">提交统计</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Configure">配置本仓库</sys:String>
|
<sys:String x:Key="Text.Dashboard.Configure">配置本仓库</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.Workspace">工作区</sys:String>
|
<sys:String x:Key="Text.Dashboard.Workspace">工作区</sys:String>
|
||||||
<sys:String x:Key="Text.Dashboard.LocalBranches">本地分支</sys:String>
|
<sys:String x:Key="Text.Dashboard.LocalBranches">本地分支</sys:String>
|
||||||
|
@ -486,6 +487,14 @@
|
||||||
<sys:String x:Key="Text.Squash.To">合并到 :</sys:String>
|
<sys:String x:Key="Text.Squash.To">合并到 :</sys:String>
|
||||||
<sys:String x:Key="Text.Squash.Message">修改提交信息:</sys:String>
|
<sys:String x:Key="Text.Squash.Message">修改提交信息:</sys:String>
|
||||||
|
|
||||||
|
<sys:String x:Key="Text.Statistics">提交统计</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.ThisWeek">本周</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.ThisMonth">本月</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.TotalCommitterCount">提交者人数:{0}</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.TotalCommitsCount">总计提交次数:{0}</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.CommitterName">提交者</sys:String>
|
||||||
|
<sys:String x:Key="Text.Statistics.CommitAmount">提交次数</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="Text.NotConfigured">GIT尚未配置。请打开【偏好设置】配置GIT路径。</sys:String>
|
<sys:String x:Key="Text.NotConfigured">GIT尚未配置。请打开【偏好设置】配置GIT路径。</sys:String>
|
||||||
<sys:String x:Key="Text.PathNotFound">路径({0})不存在或不可读取!</sys:String>
|
<sys:String x:Key="Text.PathNotFound">路径({0})不存在或不可读取!</sys:String>
|
||||||
<sys:String x:Key="Text.MissingBash">无法找到bash.exe,请确保其在git.exe同目录中!</sys:String>
|
<sys:String x:Key="Text.MissingBash">无法找到bash.exe,请确保其在git.exe同目录中!</sys:String>
|
||||||
|
|
|
@ -80,4 +80,37 @@
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="Style.TabControl.MiddleSwitch" TargetType="{x:Type TabControl}">
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type TabControl}">
|
||||||
|
<Grid KeyboardNavigation.TabNavigation="Local">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TabPanel
|
||||||
|
x:Name="HeaderPanel"
|
||||||
|
Grid.Row="0"
|
||||||
|
IsItemsHost="True" HorizontalAlignment="Center" KeyboardNavigation.TabIndex="1" Background="Transparent" />
|
||||||
|
<Border
|
||||||
|
x:Name="Border"
|
||||||
|
Grid.Row="1"
|
||||||
|
Background="Transparent"
|
||||||
|
KeyboardNavigation.TabNavigation="Local"
|
||||||
|
KeyboardNavigation.DirectionalNavigation="Contained"
|
||||||
|
KeyboardNavigation.TabIndex="2">
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="PART_SelectedContentHost"
|
||||||
|
Margin="4"
|
||||||
|
ContentSource="SelectedContent"/>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
118
src/Views/Controls/Chart.cs
Normal file
118
src/Views/Controls/Chart.cs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace SourceGit.Views.Controls {
|
||||||
|
/// <summary>
|
||||||
|
/// 绘制提交频率柱状图
|
||||||
|
/// </summary>
|
||||||
|
public class Chart : FrameworkElement {
|
||||||
|
public static readonly int LABEL_UNIT = 32;
|
||||||
|
public static readonly double MAX_SHAPE_WIDTH = 24;
|
||||||
|
|
||||||
|
public static readonly DependencyProperty LineBrushProperty = DependencyProperty.Register(
|
||||||
|
"LineBrush",
|
||||||
|
typeof(Brush),
|
||||||
|
typeof(Chart),
|
||||||
|
new PropertyMetadata(Brushes.White));
|
||||||
|
|
||||||
|
public Brush LineBrush {
|
||||||
|
get { return (Brush)GetValue(LineBrushProperty); }
|
||||||
|
set { SetValue(LineBrushProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ChartBrushProperty = DependencyProperty.Register(
|
||||||
|
"ChartBrush",
|
||||||
|
typeof(Brush),
|
||||||
|
typeof(Chart),
|
||||||
|
new PropertyMetadata(Brushes.White));
|
||||||
|
|
||||||
|
public Brush ChartBrush {
|
||||||
|
get { return (Brush)GetValue(ChartBrushProperty); }
|
||||||
|
set { SetValue(ChartBrushProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int maxV = 0;
|
||||||
|
private List<Models.StatisticSample> samples = new List<Models.StatisticSample>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置绘制数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="samples">数据源</param>
|
||||||
|
public void SetData(List<Models.StatisticSample> samples) {
|
||||||
|
this.samples = samples;
|
||||||
|
maxV = 0;
|
||||||
|
|
||||||
|
foreach (var s in samples) {
|
||||||
|
if (maxV < s.Count) maxV = s.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxV = (int)Math.Ceiling(maxV / 10.0) * 10;
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnRender(DrawingContext dc) {
|
||||||
|
base.OnRender(dc);
|
||||||
|
|
||||||
|
var font = new FontFamily("Consolas");
|
||||||
|
var pen = new Pen(LineBrush, 1);
|
||||||
|
dc.DrawLine(pen, new Point(LABEL_UNIT, 0), new Point(LABEL_UNIT, ActualHeight - LABEL_UNIT));
|
||||||
|
dc.DrawLine(pen, new Point(LABEL_UNIT, ActualHeight - LABEL_UNIT), new Point(ActualWidth, ActualHeight - LABEL_UNIT));
|
||||||
|
|
||||||
|
if (samples.Count == 0) return;
|
||||||
|
|
||||||
|
var stepV = (ActualHeight - LABEL_UNIT) / 5;
|
||||||
|
var labelStepV = maxV / 5;
|
||||||
|
var gridPen = new Pen(LineBrush, 1) { DashStyle = DashStyles.Dash };
|
||||||
|
for (int i = 1; i < 5; i++) {
|
||||||
|
var vLabel = new FormattedText(
|
||||||
|
$"{maxV - i * labelStepV}",
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
FlowDirection.LeftToRight,
|
||||||
|
new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal),
|
||||||
|
12.0,
|
||||||
|
LineBrush,
|
||||||
|
VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||||
|
|
||||||
|
var dashHeight = i * stepV;
|
||||||
|
var vy = Math.Max(0, dashHeight - vLabel.Height * 0.5);
|
||||||
|
dc.DrawLine(gridPen, new Point(LABEL_UNIT + 1, dashHeight), new Point(ActualWidth, dashHeight));
|
||||||
|
dc.DrawText(vLabel, new Point(0, vy));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stepX = (ActualWidth - LABEL_UNIT) / samples.Count;
|
||||||
|
var shapeWidth = Math.Min(LABEL_UNIT, stepX - 4);
|
||||||
|
for (int i = 0; i < samples.Count; i++) {
|
||||||
|
var h = samples[i].Count * (ActualHeight - LABEL_UNIT) / maxV;
|
||||||
|
var x = LABEL_UNIT + 1 + stepX * i + (stepX - shapeWidth) * 0.5;
|
||||||
|
var y = ActualHeight - LABEL_UNIT - h;
|
||||||
|
var rect = new Rect(x, y, shapeWidth, h);
|
||||||
|
|
||||||
|
var hLabel = new FormattedText(
|
||||||
|
samples[i].Name,
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
FlowDirection.LeftToRight,
|
||||||
|
new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal),
|
||||||
|
10.0,
|
||||||
|
LineBrush,
|
||||||
|
VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||||
|
var xLabel = x - (hLabel.Width - shapeWidth) * 0.5;
|
||||||
|
var yLabel = ActualHeight - LABEL_UNIT + 4;
|
||||||
|
|
||||||
|
dc.DrawRectangle(ChartBrush, null, rect);
|
||||||
|
|
||||||
|
if (stepX < LABEL_UNIT) {
|
||||||
|
dc.PushTransform(new TranslateTransform(xLabel, yLabel));
|
||||||
|
dc.PushTransform(new RotateTransform(45, hLabel.Width * 0.5, hLabel.Height * 0.5));
|
||||||
|
dc.DrawText(hLabel, new Point(0, 0));
|
||||||
|
dc.Pop();
|
||||||
|
dc.Pop();
|
||||||
|
} else {
|
||||||
|
dc.DrawText(hLabel, new Point(xLabel, yLabel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
195
src/Views/Statistics.xaml
Normal file
195
src/Views/Statistics.xaml
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
<controls:Window
|
||||||
|
x:Class="SourceGit.Views.Statistics"
|
||||||
|
x:Name="me"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="clr-namespace:SourceGit.Views.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Statistics"
|
||||||
|
Height="450" Width="600"
|
||||||
|
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
<RowDefinition Height="1"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Title Bar -->
|
||||||
|
<Grid Grid.Row="0" Background="{DynamicResource Brush.TitleBar}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<Path Grid.Column="0" Margin="6,0" Width="16" Height="16" Data="{StaticResource Icon.Statistics}"/>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<TextBlock Grid.Column="1" Text="{DynamicResource Text.Statistics}"/>
|
||||||
|
|
||||||
|
<!-- Window Commands -->
|
||||||
|
<StackPanel Grid.Column="3" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">
|
||||||
|
<controls:IconButton Click="Quit" Width="28" Padding="9" Icon="{StaticResource Icon.Close}" HoverBackground="Red" Opacity="1"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Rectangle
|
||||||
|
Grid.Row="1"
|
||||||
|
Height="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Fill="{DynamicResource Brush.Border0}"/>
|
||||||
|
|
||||||
|
<!-- Contents -->
|
||||||
|
<TabControl
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="8"
|
||||||
|
Style="{DynamicResource Style.TabControl.MiddleSwitch}">
|
||||||
|
<TabItem Header="{DynamicResource Text.Statistics.ThisWeek}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="32"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="8"/>
|
||||||
|
<ColumnDefinition Width="2*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<DataGrid
|
||||||
|
x:Name="lstCommitterWeek"
|
||||||
|
Grid.Row="0" Grid.Column="0"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
Background="{DynamicResource Brush.Contents}"
|
||||||
|
GridLinesVisibility="All"
|
||||||
|
HorizontalGridLinesBrush="{DynamicResource Brush.Border0}"
|
||||||
|
VerticalGridLinesBrush="{DynamicResource Brush.Border0}"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
|
HeadersVisibility="Column"
|
||||||
|
RowHeight="24"
|
||||||
|
ColumnHeaderHeight="24"
|
||||||
|
CanUserAddRows="False"
|
||||||
|
CanUserDeleteRows="False"
|
||||||
|
CanUserResizeColumns="False"
|
||||||
|
CanUserResizeRows="False"
|
||||||
|
CanUserReorderColumns="False"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{DynamicResource Brush.Border0}">
|
||||||
|
<DataGrid.ColumnHeaderStyle>
|
||||||
|
<Style TargetType="{x:Type DataGridColumnHeader}">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
|
||||||
|
<Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource Brush.Border0}" Background="{DynamicResource Brush.Window}">
|
||||||
|
<TextBlock
|
||||||
|
Text="{TemplateBinding Content}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="DemiBold"/>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</DataGrid.ColumnHeaderStyle>
|
||||||
|
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Width="*" Header="{DynamicResource Text.Statistics.CommitterName}" IsReadOnly="True" Binding="{Binding .Name}" ElementStyle="{StaticResource Style.TextBlock.LineContent}"/>
|
||||||
|
<DataGridTextColumn Width="*" Header="{DynamicResource Text.Statistics.CommitAmount}" IsReadOnly="True" Binding="{Binding .Count}" ElementStyle="{StaticResource Style.TextBlock.LineContent}"/>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="0" x:Name="txtMemberCountWeek" Text="Total Committers: -"/>
|
||||||
|
|
||||||
|
<controls:Chart
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="8,16,0,0"
|
||||||
|
x:Name="chartWeek"
|
||||||
|
LineBrush="{DynamicResource Brush.FG1}"
|
||||||
|
ChartBrush="{DynamicResource Brush.Accent1}"/>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="2" x:Name="txtCommitCountWeek" HorizontalAlignment="Right" Text="Total Commits: -"/>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{DynamicResource Text.Statistics.ThisMonth}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="32"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="8"/>
|
||||||
|
<ColumnDefinition Width="2*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<DataGrid
|
||||||
|
x:Name="lstCommitterMonth"
|
||||||
|
Grid.Row="0" Grid.Column="0"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
Background="{DynamicResource Brush.Contents}"
|
||||||
|
GridLinesVisibility="All"
|
||||||
|
HorizontalGridLinesBrush="{DynamicResource Brush.Border0}"
|
||||||
|
VerticalGridLinesBrush="{DynamicResource Brush.Border0}"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
|
HeadersVisibility="Column"
|
||||||
|
RowHeight="24"
|
||||||
|
ColumnHeaderHeight="24"
|
||||||
|
CanUserAddRows="False"
|
||||||
|
CanUserDeleteRows="False"
|
||||||
|
CanUserResizeColumns="False"
|
||||||
|
CanUserResizeRows="False"
|
||||||
|
CanUserReorderColumns="False"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{DynamicResource Brush.Border0}">
|
||||||
|
<DataGrid.ColumnHeaderStyle>
|
||||||
|
<Style TargetType="{x:Type DataGridColumnHeader}">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
|
||||||
|
<Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource Brush.Border0}" Background="{DynamicResource Brush.Window}">
|
||||||
|
<TextBlock
|
||||||
|
Text="{TemplateBinding Content}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="DemiBold"/>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</DataGrid.ColumnHeaderStyle>
|
||||||
|
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Width="*" Header="{DynamicResource Text.Statistics.CommitterName}" IsReadOnly="True" Binding="{Binding .Name}" ElementStyle="{StaticResource Style.TextBlock.LineContent}"/>
|
||||||
|
<DataGridTextColumn Width="*" Header="{DynamicResource Text.Statistics.CommitAmount}" IsReadOnly="True" Binding="{Binding .Count}" ElementStyle="{StaticResource Style.TextBlock.LineContent}"/>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="0" x:Name="txtMemberCountMonth" Text="Total Committers: -"/>
|
||||||
|
|
||||||
|
<controls:Chart
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="8,16,0,0"
|
||||||
|
x:Name="chartMonth"
|
||||||
|
LineBrush="{DynamicResource Brush.FG1}"
|
||||||
|
ChartBrush="{DynamicResource Brush.Accent1}"/>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="2" x:Name="txtCommitCountMonth" HorizontalAlignment="Right" Text="Total Commits: -"/>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
</TabControl>
|
||||||
|
|
||||||
|
<!-- Loading -->
|
||||||
|
<controls:Loading Grid.Row="2" x:Name="loading" Width="48" Height="48" IsAnimating="True"/>
|
||||||
|
</Grid>
|
||||||
|
</controls:Window>
|
120
src/Views/Statistics.xaml.cs
Normal file
120
src/Views/Statistics.xaml.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace SourceGit.Views {
|
||||||
|
/// <summary>
|
||||||
|
/// 提交统计
|
||||||
|
/// </summary>
|
||||||
|
public partial class Statistics : Controls.Window {
|
||||||
|
private static readonly string[] WEEK_DAYS = new string[] { "一", "二", "三", "四", "五", "六", "日" };
|
||||||
|
private string repo = null;
|
||||||
|
|
||||||
|
public Statistics(string repo) {
|
||||||
|
this.repo = repo;
|
||||||
|
InitializeComponent();
|
||||||
|
Task.Run(Refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Quit(object sender, RoutedEventArgs e) {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Refresh() {
|
||||||
|
var mapsWeek = new Dictionary<int, Models.StatisticSample>();
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
mapsWeek.Add(i, new Models.StatisticSample {
|
||||||
|
Name = $"星期{WEEK_DAYS[i]}",
|
||||||
|
Count = 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapsMonth = new Dictionary<int, Models.StatisticSample>();
|
||||||
|
var today = DateTime.Now;
|
||||||
|
var maxDays = DateTime.DaysInMonth(today.Year, today.Month);
|
||||||
|
for (int i = 1; i <= maxDays; i++) {
|
||||||
|
mapsMonth.Add(i, new Models.StatisticSample {
|
||||||
|
Name = $"{i}",
|
||||||
|
Count = 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapCommitterWeek = new Dictionary<string, Models.StatisticSample>();
|
||||||
|
var mapCommitterMonth = new Dictionary<string, Models.StatisticSample>();
|
||||||
|
var week = today.DayOfWeek;
|
||||||
|
var month = today.Month;
|
||||||
|
|
||||||
|
var limits = $"--since=\"{today.ToString("yyyy-MM-01 00:00:00")}\"";
|
||||||
|
var commits = new Commands.Commits(repo, limits).Result();
|
||||||
|
var totalCommitsMonth = commits.Count;
|
||||||
|
var totalCommitsWeek = 0;
|
||||||
|
foreach (var c in commits) {
|
||||||
|
var commitTime = DateTime.Parse(c.Committer.Time);
|
||||||
|
if (IsSameWeek(today, commitTime)) {
|
||||||
|
mapsWeek[(int)commitTime.DayOfWeek].Count++;
|
||||||
|
if (mapCommitterWeek.ContainsKey(c.Committer.Name)) {
|
||||||
|
mapCommitterWeek[c.Committer.Name].Count++;
|
||||||
|
} else {
|
||||||
|
mapCommitterWeek[c.Committer.Name] = new Models.StatisticSample {
|
||||||
|
Name = c.Committer.Name,
|
||||||
|
Count = 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCommitsWeek++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapsMonth[commitTime.Day].Count++;
|
||||||
|
|
||||||
|
if (mapCommitterMonth.ContainsKey(c.Committer.Name)) {
|
||||||
|
mapCommitterMonth[c.Committer.Name].Count++;
|
||||||
|
} else {
|
||||||
|
mapCommitterMonth[c.Committer.Name] = new Models.StatisticSample {
|
||||||
|
Name = c.Committer.Name,
|
||||||
|
Count = 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var samplesChartWeek = new List<Models.StatisticSample>();
|
||||||
|
var samplesChartMonth = new List<Models.StatisticSample>();
|
||||||
|
var samplesCommittersWeek = new List<Models.StatisticSample>();
|
||||||
|
var samplesCommittersMonth = new List<Models.StatisticSample>();
|
||||||
|
for (int i = 0; i < 7; i++) samplesChartWeek.Add(mapsWeek[i]);
|
||||||
|
for (int i = 1; i <= maxDays; i++) samplesChartMonth.Add(mapsMonth[i]);
|
||||||
|
foreach (var kv in mapCommitterWeek) samplesCommittersWeek.Add(kv.Value);
|
||||||
|
foreach (var kv in mapCommitterMonth) samplesCommittersMonth.Add(kv.Value);
|
||||||
|
mapsMonth.Clear();
|
||||||
|
mapsWeek.Clear();
|
||||||
|
mapCommitterMonth.Clear();
|
||||||
|
mapCommitterWeek.Clear();
|
||||||
|
commits.Clear();
|
||||||
|
samplesCommittersWeek.Sort((x, y) => y.Count - x.Count);
|
||||||
|
samplesCommittersMonth.Sort((x, y) => y.Count - x.Count);
|
||||||
|
|
||||||
|
Dispatcher.Invoke(() => {
|
||||||
|
loading.IsAnimating = false;
|
||||||
|
loading.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
chartWeek.SetData(samplesChartWeek);
|
||||||
|
chartMonth.SetData(samplesChartMonth);
|
||||||
|
|
||||||
|
lstCommitterWeek.ItemsSource = samplesCommittersWeek;
|
||||||
|
lstCommitterMonth.ItemsSource = samplesCommittersMonth;
|
||||||
|
|
||||||
|
txtMemberCountWeek.Text = App.Text("Statistics.TotalCommitterCount", samplesCommittersWeek.Count);
|
||||||
|
txtMemberCountMonth.Text = App.Text("Statistics.TotalCommitterCount", samplesCommittersMonth.Count);
|
||||||
|
txtCommitCountWeek.Text = App.Text("Statistics.TotalCommitsCount", totalCommitsWeek);
|
||||||
|
txtCommitCountMonth.Text = App.Text("Statistics.TotalCommitsCount", totalCommitsMonth);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsSameWeek(DateTime t1, DateTime t2) {
|
||||||
|
double diffDay = t1.Subtract(t2).Duration().TotalDays;
|
||||||
|
if (diffDay >= 7) return false;
|
||||||
|
|
||||||
|
return t1.CompareTo(t2) > 0 ? (t1.DayOfWeek >= t2.DayOfWeek) : t1.DayOfWeek <= t2.DayOfWeek;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -108,6 +108,13 @@
|
||||||
IsChecked="{Binding Source={x:Static models:Preference.Instance}, Path=Window.MoveCommitInfoRight, Mode=TwoWay, Converter={StaticResource InverseBool}}"
|
IsChecked="{Binding Source={x:Static models:Preference.Instance}, Path=Window.MoveCommitInfoRight, Mode=TwoWay, Converter={StaticResource InverseBool}}"
|
||||||
Checked="ChangeOrientation" Unchecked="ChangeOrientation"/>
|
Checked="ChangeOrientation" Unchecked="ChangeOrientation"/>
|
||||||
|
|
||||||
|
<controls:IconButton
|
||||||
|
Margin="8,0"
|
||||||
|
Padding="0,8"
|
||||||
|
Icon="{DynamicResource Icon.Statistics}"
|
||||||
|
ToolTip="{DynamicResource Text.Dashboard.Statistics}"
|
||||||
|
Click="OpenStatistics"/>
|
||||||
|
|
||||||
<controls:IconButton
|
<controls:IconButton
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
Padding="0,9,0,8"
|
Padding="0,9,0,8"
|
||||||
|
|
|
@ -408,6 +408,11 @@ namespace SourceGit.Views.Widgets {
|
||||||
(pages.Get("histories") as Histories)?.ChangeOrientation();
|
(pages.Get("histories") as Histories)?.ChangeOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OpenStatistics(object sender, RoutedEventArgs e) {
|
||||||
|
var dialog = new Statistics(repo.Path) { Owner = App.Current.MainWindow };
|
||||||
|
dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
private void OpenConfigure(object sender, RoutedEventArgs e) {
|
private void OpenConfigure(object sender, RoutedEventArgs e) {
|
||||||
new Popups.Configure(repo.Path).Show();
|
new Popups.Configure(repo.Path).Show();
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
|
|
Loading…
Reference in a new issue