Remove Windows-only dashboard charts. Add overall playtime chart.

main
Pat Hartl 2023-12-03 14:09:48 -06:00
parent e2883322e6
commit 03b0d9da93
5 changed files with 67 additions and 290 deletions

View File

@ -1,94 +0,0 @@
@using System.Diagnostics;
@using LANCommander.Extensions;
@using AntDesign.Charts;
@using System.Collections.Concurrent;
<Spin Spinning="Loading">
<Area @ref="Chart" Config="Config" />
</Spin>
@code {
[Parameter] public int TimerHistory { get; set; }
[Parameter] public int TimerInterval { get; set; }
IChartComponent? Chart;
System.Timers.Timer Timer;
bool Loading = true;
Dictionary<string, double[]> Data = new Dictionary<string, double[]>();
ConcurrentDictionary<string, PerformanceCounter> PerformanceCounters = new ConcurrentDictionary<string, PerformanceCounter>();
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
}
}

View File

@ -1,93 +0,0 @@
@using System.Diagnostics;
@using LANCommander.Extensions;
@using AntDesign.Charts;
@using System.Collections.Concurrent;
<Spin Spinning="Loading">
<Area @ref="Chart" Config="Config" />
</Spin>
@code {
[Parameter] public int TimerHistory { get; set; }
[Parameter] public int TimerInterval { get; set; }
IChartComponent? Chart;
System.Timers.Timer Timer;
bool Loading = true;
Dictionary<string, double[]> Data = new Dictionary<string, double[]>();
ConcurrentDictionary<string, PerformanceCounter> PerformanceCounters = new ConcurrentDictionary<string, PerformanceCounter>();
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
}
}

View File

@ -0,0 +1,65 @@
@using AntDesign.Charts
@using ByteSizeLib
@inject PlaySessionService PlaySessionService
<Spin Spinning="Loading">
<Pie Data="Data" Config="Config" JsConfig="@JsConfig" />
</Spin>
@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<string, TimeSpan> playtimes = new Dictionary<string, TimeSpan>();
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();
}
}
}

View File

@ -1,85 +0,0 @@
@using System.Diagnostics;
@using LANCommander.Extensions;
@using AntDesign.Charts;
<Spin Spinning="Loading">
<Area @ref="Chart" Config="Config" />
</Spin>
@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
}
}

View File

@ -7,25 +7,9 @@
<GridRow Gutter="(16, 16)">
<GridCol Xs="24" Md="12">
<Card Title="Network Download Rate">
<Card Title="Overall Playtime">
<Body>
<NetworkDownloadRate TimerHistory="60" TimerInterval="1000" />
</Body>
</Card>
</GridCol>
<GridCol Xs="24" Md="12">
<Card Title="Network Upload Rate">
<Body>
<NetworkUploadRate TimerHistory="60" TimerInterval="1000" />
</Body>
</Card>
</GridCol>
<GridCol Xs="24" Md="12">
<Card Title="CPU Usage (%)">
<Body>
<ProcessorUtilization TimerHistory="60" TimerInterval="1000" />
<OverallPlaytime />
</Body>
</Card>
</GridCol>