diff --git a/LANCommander/Pages/Dashboard/Charts/NetworkDownloadRate.razor b/LANCommander/Pages/Dashboard/Charts/NetworkDownloadRate.razor
deleted file mode 100644
index 665c16b..0000000
--- a/LANCommander/Pages/Dashboard/Charts/NetworkDownloadRate.razor
+++ /dev/null
@@ -1,94 +0,0 @@
-@using System.Diagnostics;
-@using LANCommander.Extensions;
-@using AntDesign.Charts;
-@using System.Collections.Concurrent;
-
-
-
-
-
-@code {
- [Parameter] public int TimerHistory { get; set; }
- [Parameter] public int TimerInterval { get; set; }
-
- IChartComponent? Chart;
- System.Timers.Timer Timer;
- bool Loading = true;
-
- Dictionary Data = new Dictionary();
-
- ConcurrentDictionary PerformanceCounters = new ConcurrentDictionary();
-
- string JsConfig = @"{
- meta: {
- value: {
- alias: 'Speed',
- formatter: (v) => humanFileSize(v, true) + '/s'
- }
- }
- }";
-
- AreaConfig Config = new AreaConfig
- {
- Name = "Network Download Rate",
- Padding = "auto",
- SeriesField = "series",
- YField = "value",
- XField = "index",
- Animation = false,
- XAxis = new ValueCatTimeAxis
- {
- Visible = false
- }
- };
-
- protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- if (firstRender)
- {
- if (Timer == null)
- {
- Timer = new System.Timers.Timer();
-
- Timer.Interval = TimerInterval;
-
- Timer.Elapsed += async (s, e) =>
- {
- await RefreshData();
- };
- }
-
- await Chart.UpdateChart(Config, null, null, JsConfig);
-
- Timer.Start();
-
- Loading = false;
-
- StateHasChanged();
- }
- }
-
- private async Task RefreshData()
- {
- #if WINDOWS
- var category = new PerformanceCounterCategory("Network Interface");
-
- foreach (var instance in category.GetInstanceNames())
- {
- if (!Data.ContainsKey(instance))
- Data[instance] = new double[TimerHistory];
-
- if (!PerformanceCounters.ContainsKey(instance))
- PerformanceCounters[instance] = new PerformanceCounter("Network Interface", "Bytes Received/sec", instance);
-
- Data[instance] = Data[instance].ShiftArrayAndInsert((double)PerformanceCounters[instance].NextValue(), TimerHistory);
- }
-
- try
- {
- await Chart.ChangeData(Data.SelectMany(x => x.Value.Select((y, i) => new { value = y, index = i, series = x.Key })), true);
- }
- catch { }
- #endif
- }
-}
diff --git a/LANCommander/Pages/Dashboard/Charts/NetworkUploadRate.razor b/LANCommander/Pages/Dashboard/Charts/NetworkUploadRate.razor
deleted file mode 100644
index 5ed24a4..0000000
--- a/LANCommander/Pages/Dashboard/Charts/NetworkUploadRate.razor
+++ /dev/null
@@ -1,93 +0,0 @@
-@using System.Diagnostics;
-@using LANCommander.Extensions;
-@using AntDesign.Charts;
-@using System.Collections.Concurrent;
-
-
-
-
-
-@code {
- [Parameter] public int TimerHistory { get; set; }
- [Parameter] public int TimerInterval { get; set; }
-
- IChartComponent? Chart;
- System.Timers.Timer Timer;
- bool Loading = true;
-
- Dictionary Data = new Dictionary();
-
- ConcurrentDictionary PerformanceCounters = new ConcurrentDictionary();
-
- string JsConfig = @"{
- meta: {
- value: {
- alias: 'Speed',
- formatter: (v) => humanFileSize(v, true) + '/s'
- }
- }
- }";
-
- AreaConfig Config = new AreaConfig
- {
- Name = "Network Upload Rate",
- Padding = "auto",
- SeriesField = "series",
- YField = "value",
- XField = "index",
- Animation = false,
- XAxis = new ValueCatTimeAxis
- {
- Visible = false
- }
- };
-
- protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- if (firstRender)
- {
- if (Timer == null)
- {
- Timer = new System.Timers.Timer();
-
- Timer.Interval = TimerInterval;
-
- Timer.Elapsed += async (s, e) =>
- {
- await RefreshData();
- };
- }
-
- await Chart.UpdateChart(Config, null, null, JsConfig);
- Timer.Start();
-
- Loading = false;
-
- StateHasChanged();
- }
- }
-
- private async Task RefreshData()
- {
- #if WINDOWS
- var category = new PerformanceCounterCategory("Network Interface");
-
- foreach (var instance in category.GetInstanceNames())
- {
- if (!Data.ContainsKey(instance))
- Data[instance] = new double[TimerHistory];
-
- if (!PerformanceCounters.ContainsKey(instance))
- PerformanceCounters[instance] = new PerformanceCounter("Network Interface", "Bytes Sent/sec", instance);
-
- Data[instance] = Data[instance].ShiftArrayAndInsert((double)PerformanceCounters[instance].NextValue(), TimerHistory);
- }
-
- try
- {
- await Chart.ChangeData(Data.SelectMany(x => x.Value.Select((y, i) => new { value = y, index = i, series = x.Key })), true);
- }
- catch { }
- #endif
- }
-}
diff --git a/LANCommander/Pages/Dashboard/Charts/OverallPlaytime.razor b/LANCommander/Pages/Dashboard/Charts/OverallPlaytime.razor
new file mode 100644
index 0000000..cd1d67f
--- /dev/null
+++ b/LANCommander/Pages/Dashboard/Charts/OverallPlaytime.razor
@@ -0,0 +1,65 @@
+@using AntDesign.Charts
+@using ByteSizeLib
+@inject PlaySessionService PlaySessionService
+
+
+
+
+
+@code {
+ object[] Data;
+
+ bool Loading = true;
+
+ string JsConfig = @"{
+ meta: {
+ value: {
+ alias: 'Overall Playtime',
+ formatter: (v) => new Date(v * 1000).toISOString().slice(11, 19)
+ }
+ },
+ label: {
+ visible: true,
+ type: 'outer-center'
+ }
+ }";
+
+ PieConfig Config = new PieConfig
+ {
+ Radius = 0.8,
+ AngleField = "value",
+ ColorField = "type",
+ };
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ Dictionary playtimes = new Dictionary();
+
+ var sessions = await PlaySessionService.Get();
+
+ foreach (var gameSessions in sessions.Where(s => s.GameId.HasValue && s.GameId.Value != Guid.Empty).GroupBy(s => s.GameId))
+ {
+ var total = new TimeSpan();
+
+ foreach (var session in gameSessions.Where(gs => gs.Start != null && gs.End != null))
+ {
+ total = total.Add(session.End.Value.Subtract(session.Start.Value));
+ }
+
+ playtimes[gameSessions.First().Game.Title] = total;
+ }
+
+ Data = playtimes.Select(pt => new
+ {
+ type = pt.Key,
+ value = (int)pt.Value.TotalSeconds
+ }).ToArray();
+
+ Loading = false;
+
+ StateHasChanged();
+ }
+ }
+}
\ No newline at end of file
diff --git a/LANCommander/Pages/Dashboard/Charts/ProcessorUtilization.razor b/LANCommander/Pages/Dashboard/Charts/ProcessorUtilization.razor
deleted file mode 100644
index c4ccf52..0000000
--- a/LANCommander/Pages/Dashboard/Charts/ProcessorUtilization.razor
+++ /dev/null
@@ -1,85 +0,0 @@
-@using System.Diagnostics;
-@using LANCommander.Extensions;
-@using AntDesign.Charts;
-
-
-
-
-
-@code {
- [Parameter] public int TimerHistory { get; set; }
- [Parameter] public int TimerInterval { get; set; }
- IChartComponent? Chart;
- System.Timers.Timer Timer;
- bool Loading = true;
-
- double[] Data;
-
- PerformanceCounter PerformanceCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
-
- string JsConfig = @"{
- meta: {
- value: {
- alias: '% Usage',
- formatter: (v) => v + '%'
- }
- }
- }";
-
- AreaConfig Config = new AreaConfig
- {
- Name = "Processor Utilization",
- Padding = "auto",
- YField = "value",
- XField = "index",
- Animation = false,
- IsPercent = true,
- YAxis = new ValueAxis
- {
- Min = 0,
- Max = 100
- },
- XAxis = new ValueCatTimeAxis
- {
- Visible = false
- }
- };
-
- protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- if (firstRender)
- {
- if (Timer == null)
- {
- Timer = new System.Timers.Timer();
-
- Timer.Interval = TimerInterval;
-
- Timer.Elapsed += async (s, e) =>
- {
- await RefreshData();
- };
- }
-
- await Chart.UpdateChart(Config, null, null, JsConfig);
- Timer.Start();
-
- Loading = false;
-
- StateHasChanged();
- }
- }
-
- private async Task RefreshData()
- {
- #if WINDOWS
- Data = Data.ShiftArrayAndInsert((double)Math.Ceiling(PerformanceCounter.NextValue()), TimerHistory);
-
- try
- {
- await Chart.ChangeData(Data.Select((x, i) => new { value = x, index = i }), true);
- }
- catch { }
- #endif
- }
-}
diff --git a/LANCommander/Pages/Dashboard/Index.razor b/LANCommander/Pages/Dashboard/Index.razor
index 57ed517..33b6f29 100644
--- a/LANCommander/Pages/Dashboard/Index.razor
+++ b/LANCommander/Pages/Dashboard/Index.razor
@@ -7,25 +7,9 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+