Affinamento display update

This commit is contained in:
Samuele Locatelli
2023-07-29 09:50:51 +02:00
parent 90560b4024
commit 7fd09155e0
4 changed files with 154 additions and 89 deletions
@@ -11,4 +11,4 @@
</div>
<button class="btn btn-success" @onclick="StartLongTimer">Start</button>
<ProgressDisplay RefreshInterval="100" Title="@titleMsg" MaxVal="@maxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMSec"></ProgressDisplay>
<ProgressDisplay RefreshInterval="100" Title="@titleMsg" MaxVal="@maxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMSec" DisplaySize="ProgressDisplay.ModalSize.Medium" ModalCss="card alert-primary"></ProgressDisplay>
@@ -4,7 +4,7 @@ namespace EgwCoreLib.BlazorTest.Pages
{
#region Protected Properties
protected double expTime { get; set; } = 20;
protected double expTime { get; set; } = 6;
protected int numSteps { get; set; } = 4;
#endregion Protected Properties
@@ -18,12 +18,11 @@ namespace EgwCoreLib.BlazorTest.Pages
int stepVal = maxVal / numSteps;
// imposto i valori x progress..
maxVal = 100;
expTimeMSec = stdWait * 1000;
expTimeMSec = (int)(stdWait * 1000);
//nextVal = stepVal;
//currVal = 0;
for (int currStep = 1; currStep <= numSteps; currStep++)
{
//await Task.Delay(1);
// aggiorno valori
currVal = (currStep - 1) * stepVal;
nextVal = currStep * stepVal;
@@ -33,7 +32,8 @@ namespace EgwCoreLib.BlazorTest.Pages
nextVal = maxVal;
}
await InvokeAsync(StateHasChanged);
nextWait = (int)(rnd.Next(2000, 2500) * stdWait);
// simulo ritardo importante (da 2 a 3 volte
nextWait = (int)(rnd.Next(2000, 3000) * stdWait);
// attendo step successivi...
await Task.Delay(nextWait);
}
@@ -47,11 +47,11 @@ namespace EgwCoreLib.BlazorTest.Pages
#region Private Fields
private int currVal = 100;
private double expTimeMSec = 10000;
private int expTimeMSec = 10000;
private int maxVal = 100;
private int nextVal = 100;
private Random rnd = new Random();
private string titleMsg = "Test Progress";
private string titleMsg = "SIM Progress";
#endregion Private Fields
}
+21 -22
View File
@@ -1,29 +1,28 @@
@*<div class="row p-3 m-2">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-5x"></i>
</div>
</div>
*@
@if (IsLoading)
@if (isLoading)
{
<dialog class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
<div class="modal-dialog modal-xl">
<div class="@modalDialogCss rounded shadow">
<div class="modal-content">
<div class="col-12 text-center my-0 py-2 @modalCss">
<div class="d-flex justify-content-around py-5">
<div>
<h2>@Title</h2>
<i>@DisplayMsg</i>
</div>
<div class="@ModalCss text-center">
<div class="card-header">
@if (!string.IsNullOrEmpty(Title))
{
<b>@Title</b>
}
</div>
@* <div class="d-flex justify-content-around py-2">
<div><i class="fas fa-circle-notch fa-spin fa-5x"></i></div>
</div>*@
<div class="w-100">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: @currWidth"></div>
<div class="card-body p-4 bg-light text-dark">
@if (ShowPercent)
{
<div class="d-flex justify-content-around">
<div>
@displayMsg
</div>
</div>
}
<div class="w-100">
<div class="progress">
<div class="@ProgressCss" style="width: @currWidth"></div>
</div>
</div>
</div>
</div>
+126 -60
View File
@@ -4,32 +4,98 @@ namespace EgwCoreLib.Razor
{
public partial class ProgressDisplay : IDisposable
{
#region Public Enums
public enum ModalSize
{
Small,
Medium,
Large
}
#endregion Public Enums
#region Public Properties
/// <summary>
/// Valore corrente
/// </summary>
[Parameter]
public double CurrVal
{
get => ActVal;
get => actVal;
set
{
ActVal = value;
StartVal = value;
IsLoading = ActVal < MaxVal;
actVal = value;
startVal = value;
isLoading = actVal < MaxVal;
}
}
/// <summary>
/// Dimensioni attese modale
/// default: ModalSize.Medium
/// </summary>
[Parameter]
public double ExpTimeMSec { get; set; } = 10000;
public ModalSize DisplaySize { get; set; } = ModalSize.Medium;
/// <summary>
/// Tempo atteso per prossimo step
/// default: 10000
/// </summary>
[Parameter]
public bool IsLoading { get; set; } = false;
public int ExpTimeMSec { get; set; } = 10000;
/// <summary>
/// Valore massimo ammesso
/// default: 100
/// </summary>
[Parameter]
public double MaxVal { get; set; } = 100;
/// <summary>
/// Style modale
/// default: card
/// alternative: card alert-primary
/// </summary>
[Parameter]
public string ModalCss { get; set; } = "card";
/// <summary>
/// Prossimo valore ammesso (fino al max)
/// default: 100
/// </summary>
[Parameter]
public double NextVal { get; set; } = 100;
/// <summary>
/// Style progressbar
/// default: progress-bar progress-bar-striped progress-bar-animated
/// </summary>
[Parameter]
public string ProgressCss { get; set; } = "progress-bar progress-bar-striped progress-bar-animated";
/// <summary>
/// Intervallo interno per refresh percentuale avanzamento
/// default: 100ms
/// </summary>
[Parameter]
public int RefreshInterval { get; set; } = 100;
/// <summary>
/// Indica se mostrare la percentuale vanzamento
/// default: true
/// </summary>
[Parameter]
public bool ShowPercent { get; set; } = true;
/// <summary>
/// Numero di secondi prima (rispetto valore ExpTimeMsec) da cui iniziare rallentamento
/// </summary>
[Parameter]
public int SlowWindowMSec { get; set; } = 3000;
//Titolo da mostrare (se "" NON lo mostra)
[Parameter]
public string Title { get; set; } = "Progress";
@@ -39,33 +105,40 @@ namespace EgwCoreLib.Razor
public void Dispose()
{
periodicTimer?.Dispose();
uiTimer?.Dispose();
}
#endregion Public Methods
#region Protected Fields
protected PeriodicTimer? periodicTimer = null;
#endregion Protected Fields
#region Protected Properties
protected string currWidth { get; set; } = "";
protected string modalCss { get; set; } = "alert alert-success";
protected string modalDialogCss
{
get
{
string answ = "modal-dialog";
switch (DisplaySize)
{
case ModalSize.Small:
answ = "modal-dialog modal-sm";
break;
case ModalSize.Large:
answ = "modal-dialog modal-xl";
break;
case ModalSize.Medium:
default:
break;
}
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
#if false
protected override void OnInitialized()
{
RunTimer(); // fire-and-forget
}
#endif
protected override async Task OnParametersSetAsync()
{
// salvo valori aggiornamento...
@@ -75,78 +148,71 @@ namespace EgwCoreLib.Razor
nextUpdate = lastUpdate.AddMilliseconds(ExpTimeMSec);
await RefreshDisplay();
}
if(IsLoading)
if (isLoading)
{
periodicTimer?.Dispose();
periodicTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(RefInt));
uiTimer?.Dispose();
uiTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(RefreshInterval));
RunTimer();
}
else
{
periodicTimer = null;
uiTimer = null;
}
}
protected async Task RefreshDisplay()
{
currWidth = $"{(double)ActVal / MaxVal:P0}";
DisplayMsg = $"{ActVal / MaxVal:P2}";
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Fields
[Parameter]
public int RefreshInterval
{
get => RefInt;
set
{
if (RefInt != value && value > 0)
{
RefInt = value;
#if false
periodicTimer?.Dispose();
periodicTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(value));
RunTimer();
#endif
}
}
}
private int RefInt { get; set; } = 100;
private PeriodicTimer? uiTimer = null;
#endregion Private Fields
#region Private Properties
private double ActVal { get; set; } = 100;
private string DisplayMsg { get; set; } = "Loading...";
private double actVal { get; set; } = 100;
private string currWidth { get; set; } = "";
private string displayMsg { get; set; } = "Loading...";
private bool isLoading { get; set; } = false;
private DateTime lastUpdate { get; set; } = DateTime.Now.AddMinutes(-1);
private DateTime nextUpdate { get; set; } = DateTime.Now;
private double StartVal { get; set; } = 100;
private double startVal { get; set; } = 100;
#endregion Private Properties
#region Private Methods
private async Task RefreshDisplay()
{
currWidth = $"{(double)actVal / MaxVal:P0}";
if (ShowPercent)
{
displayMsg = $"{actVal / MaxVal:P2}";
}
await InvokeAsync(StateHasChanged);
}
private async void RunTimer()
{
while (periodicTimer!=null && await periodicTimer.WaitForNextTickAsync())
while (uiTimer != null && await uiTimer.WaitForNextTickAsync())
{
if (IsLoading)
if (isLoading)
{
DateTime adesso = DateTime.Now;
if (nextUpdate <= adesso)
if (nextUpdate <= adesso.AddMilliseconds(SlowWindowMSec))
{
nextUpdate = adesso.AddMilliseconds(RefreshInterval);
}
// calcolo delta ms...
var deltaMs = adesso.Subtract(lastUpdate).TotalMilliseconds;
var denomMs = nextUpdate.Subtract(lastUpdate).TotalMilliseconds;
var numMs = adesso.Subtract(lastUpdate).TotalMilliseconds;
var denMs = nextUpdate.Subtract(lastUpdate).TotalMilliseconds;
denMs = denMs > 0 ? denMs : 1;
// aggiorno display...
ActVal = StartVal + (NextVal - StartVal) * (deltaMs / denomMs);
actVal = startVal + (NextVal - startVal) * (numMs / denMs);
await RefreshDisplay();
}
}