update interafaccia Callstats
This commit is contained in:
@@ -62,14 +62,28 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<b>@currDetail</b>
|
||||
if (tsDataDetail.Count == 0)
|
||||
{
|
||||
<div class="alert alert-info">← No data found</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MultiLine Id="@currTsId" AspRatio="4" DataTSList="@TSDataMulti" Labels="@LabelPlot" lineColor="@lineColorsMLine" backColor="@bgColorsMLine" lTens="0" Titles="@lineTitles" Stepped="false" yScale="logarithmic"></MultiLine>
|
||||
<div class="card shadow">
|
||||
<div class="card-header d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
<b>@currDetail</b>
|
||||
</div>
|
||||
<div class="px-0">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"># giorni</span>
|
||||
<input type="number" class="form-control form-control-sm" @bind="numDays" @bind:after="OnDaysChangedAsync">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<MultiLine Id="@currTsId" AspRatio="2.5" DataTSList="@TSDataMulti" Labels="@LabelPlot" lineColor="@lineColorsMLine" backColor="@bgColorsMLine" lTens="0" Titles="@lineTitles" Stepped="false" yScale="logarithmic"></MultiLine>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,28 @@ namespace MP.IOC.Components.Pages
|
||||
{
|
||||
public partial class CallStats
|
||||
{
|
||||
#region Protected Properties
|
||||
|
||||
private int numDays
|
||||
{
|
||||
get => _numDays;
|
||||
set
|
||||
{
|
||||
if (_numDays != value)
|
||||
{
|
||||
_numDays = value;
|
||||
//_ = ShowDetail(currDetail);
|
||||
}
|
||||
}
|
||||
}
|
||||
private async Task OnDaysChangedAsync()
|
||||
{
|
||||
// Questo metodo viene invocato automaticamente dopo che numDays è stato aggiornato
|
||||
await ShowDetail(currDetail);
|
||||
// Non serve chiamare StateHasChanged(), Blazor lo fa al termine del Task
|
||||
}
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -20,6 +42,7 @@ namespace MP.IOC.Components.Pages
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private int _numDays = 5;
|
||||
private List<StatDataDTO> currData = new();
|
||||
|
||||
private string currDetail = "";
|
||||
@@ -64,17 +87,12 @@ namespace MP.IOC.Components.Pages
|
||||
|
||||
private List<double> DatiPareto
|
||||
{
|
||||
get => currData.Where(x => x.Value > 10).OrderByDescending(x => x.Value).Take(ParetoTake).Select(x => x.Value).ToList();
|
||||
get => currData.OrderByDescending(x => x.Value).Take(ParetoTake).Select(x => x.Value).ToList();
|
||||
}
|
||||
|
||||
private List<string> LabelPareto
|
||||
{
|
||||
get => currData.Where(x => x.Value > 10).OrderByDescending(x => x.Value).Take(ParetoTake).Select(x => x.Label).ToList();
|
||||
}
|
||||
|
||||
private int ParetoTake
|
||||
{
|
||||
get => currData.Count() <= 30 ? currData.Count() : 30;
|
||||
get => currData.OrderByDescending(x => x.Value).Take(ParetoTake).Select(x => x.Label).ToList();
|
||||
}
|
||||
|
||||
private List<string> LabelPlot
|
||||
@@ -96,6 +114,11 @@ namespace MP.IOC.Components.Pages
|
||||
get => GetDistinctColors(tsDataDetail.Count, "1");
|
||||
}
|
||||
|
||||
private int ParetoTake
|
||||
{
|
||||
get => currData.Count() <= 30 ? currData.Count() : 30;
|
||||
}
|
||||
|
||||
[Inject]
|
||||
private IStatsDetailService SDetService { get; set; } = null!;
|
||||
|
||||
@@ -131,36 +154,37 @@ namespace MP.IOC.Components.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
private List<string> GetDistinctColors(int numRecords, string alpha)
|
||||
{
|
||||
ParetoDay = await SDetService.GetParetoStatsDayAsync();
|
||||
}
|
||||
List<string> colors = new List<string>();
|
||||
if (numRecords <= 0) return colors;
|
||||
|
||||
/// <summary>
|
||||
/// Genera colori sfondo 33% rosso / arancione / giallo
|
||||
/// </summary>
|
||||
/// <param name="numRecords"></param>
|
||||
/// <param name="alpha"></param>
|
||||
/// <returns></returns>
|
||||
private List<string> semaphColors(int numRecords, string alpha)
|
||||
{
|
||||
List<string> answ = new List<string>();
|
||||
// verde...
|
||||
for (int i = 0; i < numRecords / 3; i++)
|
||||
// Partiamo dal Blu (240°) invece che dal Rosso (0°)
|
||||
double startHue = 240.0;
|
||||
|
||||
for (int i = 0; i < numRecords; i++)
|
||||
{
|
||||
answ.Add($"rgba(54, 235, 82, {alpha})");
|
||||
}
|
||||
// arancione
|
||||
for (int i = 0; i < numRecords / 3; i++)
|
||||
{
|
||||
answ.Add($"rgba(255, 206, 86, {alpha})");
|
||||
}
|
||||
while (answ.Count < numRecords)
|
||||
{
|
||||
answ.Add($"rgba(255, 99, 132, {alpha}");
|
||||
// Distribuiamo la tonalità aggiungendo l'offset iniziale
|
||||
// L'operatore % 360 assicura di rimanere nel cerchio se superiamo il rosso
|
||||
double hue = (startHue + ((double)i * 360 / numRecords)) % 360;
|
||||
|
||||
// Strategia di distinzione (attiva sempre, ma più efficace sopra i 5 colori)
|
||||
// Alterniamo i valori per i record pari/dispari
|
||||
string saturation = "70%";
|
||||
string lightness = "50%";
|
||||
|
||||
if (numRecords > 5)
|
||||
{
|
||||
// Se i colori sono molti, alterniamo luminosità e saturazione
|
||||
// I record dispari saranno più chiari e saturi, i pari più scuri e tenui
|
||||
lightness = (i % 2 == 0) ? "45%" : "65%";
|
||||
saturation = (i % 2 == 0) ? "80%" : "60%";
|
||||
}
|
||||
|
||||
colors.Add($"hsla({hue:0.##}, {saturation}, {lightness}, {alpha})");
|
||||
}
|
||||
|
||||
return answ;
|
||||
return colors;
|
||||
}
|
||||
|
||||
private List<string> GetSemaforicColors(int numRecords, string alpha)
|
||||
@@ -202,53 +226,10 @@ namespace MP.IOC.Components.Pages
|
||||
|
||||
return colors;
|
||||
}
|
||||
//private List<string> GetDistinctColors(int numRecords, string alpha)
|
||||
//{
|
||||
// List<string> colors = new List<string>();
|
||||
|
||||
// for (int i = 0; i < numRecords; i++)
|
||||
// {
|
||||
// // Distribuiamo la tonalità (Hue) uniformemente sui 360 gradi
|
||||
// double hue = (double)i * 360 / numRecords;
|
||||
|
||||
// // Usiamo il formato CSS hsla() che è più semplice da generare direttamente
|
||||
// // Saturazione 70% e Luminosità 50-60% di solito danno colori vivaci e distinti
|
||||
// colors.Add($"hsla({hue:0.##}, 70%, 50%, {alpha})");
|
||||
// }
|
||||
|
||||
// return colors;
|
||||
//}
|
||||
private List<string> GetDistinctColors(int numRecords, string alpha)
|
||||
private async Task ReloadData()
|
||||
{
|
||||
List<string> colors = new List<string>();
|
||||
if (numRecords <= 0) return colors;
|
||||
|
||||
// Partiamo dal Blu (240°) invece che dal Rosso (0°)
|
||||
double startHue = 240.0;
|
||||
|
||||
for (int i = 0; i < numRecords; i++)
|
||||
{
|
||||
// Distribuiamo la tonalità aggiungendo l'offset iniziale
|
||||
// L'operatore % 360 assicura di rimanere nel cerchio se superiamo il rosso
|
||||
double hue = (startHue + ((double)i * 360 / numRecords)) % 360;
|
||||
|
||||
// Strategia di distinzione (attiva sempre, ma più efficace sopra i 5 colori)
|
||||
// Alterniamo i valori per i record pari/dispari
|
||||
string saturation = "70%";
|
||||
string lightness = "50%";
|
||||
|
||||
if (numRecords > 5)
|
||||
{
|
||||
// Se i colori sono molti, alterniamo luminosità e saturazione
|
||||
// I record dispari saranno più chiari e saturi, i pari più scuri e tenui
|
||||
lightness = (i % 2 == 0) ? "45%" : "65%";
|
||||
saturation = (i % 2 == 0) ? "80%" : "60%";
|
||||
}
|
||||
|
||||
colors.Add($"hsla({hue:0.##}, {saturation}, {lightness}, {alpha})");
|
||||
}
|
||||
|
||||
return colors;
|
||||
ParetoDay = await SDetService.GetParetoStatsDayAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -260,7 +241,7 @@ namespace MP.IOC.Components.Pages
|
||||
currDetail = selDetail;
|
||||
// recupero dettaglio 7gg...
|
||||
DateTime adesso = DateTime.Now;
|
||||
List<StatsDetailModel> rawData = await SDetService.GetFiltAsync(adesso.AddDays(-5), adesso, "", selDetail);
|
||||
List<StatsDetailModel> rawData = await SDetService.GetFiltAsync(adesso.AddDays(-numDays), adesso, "", selDetail);
|
||||
// conversione con grouping
|
||||
tsData = rawData.Select(r => new chartJsData.chartJsTSerie() { x = r.Hour, y = (double)r.AvgDuration })
|
||||
.OrderBy(o => o.x)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>6.16.2604.1809</Version>
|
||||
<Version>6.16.2604.1810</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-IOC </i>
|
||||
<h4>Versione: 6.16.2604.1809</h4>
|
||||
<h4>Versione: 6.16.2604.1810</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2604.1809
|
||||
6.16.2604.1810
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2604.1809</version>
|
||||
<version>6.16.2604.1810</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user