Affinamento display update
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user