45 Commits

Author SHA1 Message Date
Samuele Locatelli e7c16518db Merge tag 'FixProgBarLimit01' into develop
Aggiunta fix ProgBar
2023-12-15 10:58:36 +01:00
Samuele Locatelli 02f7128884 Merge branch 'release/FixProgBarLimit01' 2023-12-15 10:58:09 +01:00
Samuele Locatelli 35ef4e8a47 Merge branch 'develop' of https://gitlab.steamware.net/egalware/egwcorelib into develop 2023-12-15 10:57:32 +01:00
Samuele Locatelli 2cf7e2236d ProgBar:
- update limiti yellow/red int --> double
2023-12-15 10:57:23 +01:00
zaccaria.majid 41e6ee23b9 Merge branch 'develop' 2023-11-16 12:25:06 +01:00
zaccaria.majid 9f87d54140 Merge branch 'develop' of https://gitlab.steamware.net/egalware/egwcorerazorcomp into develop 2023-11-16 10:01:17 +01:00
zaccaria.majid da56024b62 aggiunto zxing compo 2023-11-16 09:59:20 +01:00
Samuele Locatelli 90ce60adb7 Merge tag 'AddTitleOnLoading02' into develop
Fix errore display titolo su componenti loading
2023-10-24 17:26:41 +02:00
Samuele Locatelli 1d0721471a Merge branch 'release/AddTitleOnLoading02' 2023-10-24 17:26:29 +02:00
Samuele Locatelli eae8bac539 Update data loader x titolo da mostrare 2023-10-24 17:26:06 +02:00
Samuele Locatelli 9732a98861 Merge tag 'AddTitleOnLoading' into develop
Aggiunto titolo x componente loading
2023-10-24 09:09:38 +02:00
Samuele Locatelli 9fa9d02e79 Merge branch 'release/AddTitleOnLoading' 2023-10-24 09:09:29 +02:00
Samuele Locatelli 36be2d83f5 Update loader: parametro titolo 2023-10-24 08:11:32 +02:00
Samuele Locatelli 509f2ed0ae Merge tag 'AddMultiGauge01' into develop
Aggiunto multigauge (ex TAB)
2023-10-13 12:15:38 +02:00
Samuele Locatelli c38af98b5a Merge branch 'release/AddMultiGauge01' 2023-10-13 12:15:25 +02:00
Samuele Locatelli 605f155fac Aggiunta componente gaugeMulti 2023-10-13 12:15:04 +02:00
Samuele Locatelli 502e2bf22a Merge tag 'UpdateGaugeComp' into develop
Aggiornamento componente Gauge
2023-10-12 19:25:25 +02:00
Samuele Locatelli 42cbb964c7 Merge branch 'release/UpdateGaugeComp' 2023-10-12 19:25:14 +02:00
Samuele Locatelli 0d38635b40 Display cerchi:
- Aggiunta proprietà x colore esterno
- cambio nome con maiuscole
2023-10-12 19:24:48 +02:00
Samuele Locatelli 1eb7acca41 ix api key nexus gestita da variabili globali nexus 2023-09-21 10:13:27 +02:00
Samuele Locatelli 56f6156cef Merge tag 'UpdateLoadingDataComp03' into develop
Update componenti loading (in particolare LARGE)
2023-08-02 16:55:25 +02:00
Samuele Locatelli b275d9f15d Merge branch 'release/UpdateLoadingDataComp03' 2023-08-02 16:55:14 +02:00
Samuele Locatelli facc808368 Update loader BIG 2023-08-02 16:54:56 +02:00
Samuele Locatelli e20929fb7d Merge tag 'UpdateLoadingDataComp02' into develop
Update proprietà x calcolo anticipo display aggiornamento
2023-07-31 09:32:29 +02:00
Samuele Locatelli c034637757 Merge branch 'release/UpdateLoadingDataComp02' 2023-07-31 09:32:14 +02:00
Samuele Locatelli aec1e932d1 Update proprietà progressBar 2023-07-31 09:31:53 +02:00
Samuele Locatelli 429009c915 Merge tag 'UpdateLoadingDataComp01' into develop
Aggiunta componenti parametrici
2023-07-29 12:11:34 +02:00
Samuele Locatelli 608565c43b Merge branch 'release/UpdateLoadingDataComp01' 2023-07-29 12:05:56 +02:00
Samuele Locatelli 53618c605f Completata versione attuale componenti loading 2023-07-29 12:04:11 +02:00
Samuele Locatelli 99ce59f76f Update con aggiunta loader slide oltre a glow 2023-07-29 11:42:05 +02:00
Samuele Locatelli 7fd09155e0 Affinamento display update 2023-07-29 09:50:51 +02:00
Samuele Locatelli 90560b4024 Update componente loading con stima fake 2023-07-28 19:03:12 +02:00
Samuele Locatelli 9bc8473d64 Merge tag 'AddMultiLineChartJs01' into develop
Aggiunta componente x display Chart multi-line
2023-07-25 15:21:28 +02:00
Samuele Locatelli be8de10e07 Merge branch 'release/AddMultiLineChartJs01' 2023-07-25 15:21:09 +02:00
Samuele Locatelli 8e13de8d1e Aggiunta componente multiline x ChartJs + refresh 2023-07-25 15:18:38 +02:00
Samuele Locatelli 59c2ad7929 Merge tag 'PeriodoAddClona' into develop
Fix gestione periodo: aggiunto clona obj
2023-07-03 08:36:12 +02:00
Samuele Locatelli ef1d4c1654 Merge branch 'release/PeriodoAddClona' 2023-07-03 08:35:31 +02:00
Samuele Locatelli 0e3103d8b8 Aggiunto metodo clone x periodo 2023-07-03 08:16:34 +02:00
Samuele Locatelli e31e071889 Merge tag 'AddChartJsOnMaster02' into develop
Fix js script insert x charts vecchi
2023-06-29 17:57:04 +02:00
Samuele Locatelli bb73b26dcd Merge branch 'release/AddChartJsOnMaster02' 2023-06-29 17:56:25 +02:00
Samuele Locatelli add63946e1 code reorg 2023-06-29 17:56:03 +02:00
Samuele Locatelli cfe61aac1d Update ChartTS x jscript 2023-06-29 17:54:40 +02:00
Samuele Locatelli 5e71139543 Update componenti vecchi ChartJs:
- fix rispetto dimensione ext
- fix jscript
2023-06-29 17:53:57 +02:00
Samuele Locatelli abeae5ef1a Merge tag 'AddChartJsOnMaster' into develop
Add chart js + jscript vari su main
2023-06-29 17:04:25 +02:00
Samuele Locatelli d0f0c6e495 Merge branch 'release/AddChartJsOnMaster' 2023-06-29 17:04:11 +02:00
46 changed files with 2293 additions and 117 deletions
+4 -4
View File
@@ -138,7 +138,7 @@ EgwCoreLib.Razor:release-dev:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet pack -p:Configuration=Debug -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
# - *renameDeb
- '& "$env:NUGET_PATH" setapikey fe387daa-d07c-3207-877e-96c8be1be91b -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" push $env:APP_NAME/bin/Debug/$env:APP_NAME.$env:NUM_DEB.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted'
EgwCoreLib.Utils:release-dev:
@@ -160,7 +160,7 @@ EgwCoreLib.Utils:release-dev:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet pack -p:Configuration=Debug -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
# - *renameDeb
- '& "$env:NUGET_PATH" setapikey fe387daa-d07c-3207-877e-96c8be1be91b -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" push $env:APP_NAME/bin/Debug/$env:APP_NAME.$env:NUM_DEB.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted'
# ---------- RELEASE ----------
@@ -183,7 +183,7 @@ EgwCoreLib.Razor:release-rel:
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet pack -p:Configuration=Debug -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
- '& "$env:NUGET_PATH" setapikey fe387daa-d07c-3207-877e-96c8be1be91b -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" push $env:APP_NAME/bin/Debug/$env:APP_NAME.$env:NUM_REL.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted'
EgwCoreLib.Utils:release-rel:
@@ -205,6 +205,6 @@ EgwCoreLib.Utils:release-rel:
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet pack -p:Configuration=Debug -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
- '& "$env:NUGET_PATH" setapikey fe387daa-d07c-3207-877e-96c8be1be91b -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted'
- '& "$env:NUGET_PATH" push $env:APP_NAME/bin/Debug/$env:APP_NAME.$env:NUM_REL.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted'
+58 -19
View File
@@ -5,6 +5,14 @@
<div class="row py-4" style="background-color: #ACDDAC;">
<div class="col-4">
@*<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<rect width="10" height="10">
<animate attributeName="rx"
values="0;5;0"
dur="5s"
repeatCount="indefinite" />
</rect>
</svg>*@
</div>
<div class="col-4">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
@@ -20,7 +28,7 @@
</rect>
<text id="TitleElem" x="10%" y="50%" class="text-light" style="font-size:2rem;">Titolo</text>
<g>
<rect x="10%" y="10%" width="80%" height="80%" fill="white" fill-opacity="0.1" >
<rect x="10%" y="10%" width="80%" height="80%" fill="white" fill-opacity="0.1">
</rect>
<text x="10%" y="70%" class="text-light" style="font-size:0.8rem;">
testo più lungo... 0123456789
@@ -33,20 +41,6 @@
</g>
</svg>
</div>
<div class="col-4">
</div>
@*<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<rect width="10" height="10">
<animate attributeName="rx"
values="0;5;0"
dur="5s"
repeatCount="indefinite" />
</rect>
</svg>*@
</div>
<div class="row py-4" style="background-color: #34495E;">
<div class="col-4">
</div>
<div class="col-4">
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<defs>
@@ -61,7 +55,19 @@
</rect>
</svg>
</div>
<div class="col-4">
<div class="col-2 bg-dark">
</div>
<div class="col-2 bg-dark">
</div>
<div class="col-2 bg-dark">
<CircleGaugeMulti Titolo="@($"{currVal1}")" Testo="#pz prod" maxVal="@maxVal" ListInner="@DDemo1" ShowCircleBtn="true"></CircleGaugeMulti>
</div>
<div class="col-2 bg-dark">
<CircleGaugeMulti Titolo="@($"{currVal2}")" Testo="#pz prod" maxVal="@maxVal" ListInner="@DDemoIn2" ListOuter="@DDemoOut2" ShowCircleBtn="true"></CircleGaugeMulti>
</div>
<div class="col-2 bg-dark">
</div>
<div class="col-2 bg-dark">
</div>
</div>
<div class="row">
@@ -69,10 +75,13 @@
<div class="calendario">
<div class="d-flex justify-content-between">
<div>
<CircleGauge Titolo="9:00" Testo="Caricate" maxVal="480" currVal="540" strokeColorVal="#F1C40F" ShowCircleBtn="true"></CircleGauge>
<CircleGauge Titolo="9:00" Testo="Caricate" maxVal="480" currVal="540" StrokeColorVal="#F1C40F" ShowCircleBtn="true"></CircleGauge>
</div>
<div>
<CircleGauge Titolo="4:00" Testo="Lavorate" maxVal="480" currVal="240" strokeColorVal="#00FF00" ShowCircleBtn="true"></CircleGauge>
<CircleGauge Titolo="4:00" Testo="Lavorate" maxVal="480" currVal="240" StrokeColorVal="#00FF00" ShowCircleBtn="true"></CircleGauge>
</div>
<div>
<CircleGauge Titolo="12:00" Testo="Caricate" maxVal="480" currVal="720" StrokeColorVal="#F1C40F" StrokeColorValOuter="#01C4FF" ShowCircleBtn="true"></CircleGauge>
</div>
</div>
<div class="containerBtnTemp">
@@ -83,4 +92,34 @@
</div>
</div>
</div>
</div>
</div>
@code {
protected List<CircleGaugeMulti.CircSegm> DDemo1 = new List<CircleGaugeMulti.CircSegm>();
protected List<CircleGaugeMulti.CircSegm> DDemoIn2 = new List<CircleGaugeMulti.CircSegm>();
protected List<CircleGaugeMulti.CircSegm> DDemoOut2 = new List<CircleGaugeMulti.CircSegm>();
protected int currVal1 = 1000;
protected int currVal2 = 1000;
protected int maxVal = 1000;
protected override void OnInitialized()
{
DDemo1.Clear();
currVal1 = 800;
DDemo1.Add(new CircleGaugeMulti.CircSegm() { Color = "#DCFD15", Value = 800 });
DDemo1.Add(new CircleGaugeMulti.CircSegm() { Color = "#13FD67", Value = 300 });
Random rnd = new Random();
DDemoIn2.Clear();
DDemoOut2.Clear();
currVal2 = 1300;
DDemoIn2.Add(new CircleGaugeMulti.CircSegm() { Color = "#DCFD15", Value = 1000 });
DDemoIn2.Add(new CircleGaugeMulti.CircSegm() { Color = "#13FD67", Value = 600 });
DDemoOut2.Add(new CircleGaugeMulti.CircSegm() { Color = "#1367FD", Value = 300 });
// DataDemo.Add(new CircleGaugeMulti.CircSegm() { Color = "#1515FD", Value = 700 });
// currVal = rnd.Next(maxVal - 200, maxVal + 500);
// DataDemo.Add(new CircleGaugeMulti.CircSegm() { Color = "#13FD67", Value = currVal / 4 });
// DataDemo.Add(new CircleGaugeMulti.CircSegm() { Color = "#ACFD15", Value = currVal / 4 });
// DataDemo.Add(new CircleGaugeMulti.CircSegm() { Color = "#1515FD", Value = currVal / 2 });
}
}
+31 -1
View File
@@ -91,11 +91,41 @@
</div>
</div>
<BarcodeReader ScanResult="(e) => ScanDoneHandler(e)"
ScanBtnTitle="Scan"
ResetBtnTitle="Reset"
CloseBtnTitle="Close"
UseBuiltinDiv="false"
@ref="barcodeReaderCustom"
SelectDeviceBtnTitle="Select Device">
</BarcodeReader>
<div @ref="barcodeReaderCustom.Element" class="d-flex justify-content-center">
@* <div style="width: 480px; max-width: 100%"> *@
<div class="col-12 col-md-8 col-lg-6">
<button class="btn btn-outline-success p-2 m-1 w-25" data-action="startButton">Scan</button>
<button class="btn btn-outline-success p-2 m-1 w-25" data-action="resetButton">Reset</button>
<div data-action="sourceSelectPanel" style="display:none">
<label for="sourceSelect">Source:</label>
<select data-action="sourceSelect" style="max-width:100%" class="form-control">
</select>
</div>
<div>
<video id="video" playsinline="true" autoplay="true" class="w-100 h-100 border rounded shadow" muted="true"></video>
</div>
</div>
</div>
@code {
private int currentCount = 0;
protected BarcodeReader barcodeReaderCustom { get; set; } = null!;
protected Random rnd = new Random();
protected async Task ScanDoneHandler(string value)
{
await Task.Delay(1);
}
private void IncrementCount()
{
currentCount++;
+63 -17
View File
@@ -6,7 +6,7 @@
<h3>TestCompo</h3>
@*<div class="row">
<div class="row">
<div class="col-6">
@if (periodo != null)
{
@@ -18,21 +18,32 @@
<div class="col-6">
<PeriodoSel E_PeriodoSel="setPeriodo" CurrPeriodo="@periodo"></PeriodoSel>
</div>
</div>*@
</div>
<Doughnut Type="@Doughnut.ChartType.Doughnut" Data="@Data.ToArray()" BackgroundColor="@colors"></Doughnut>
<div class="row" style="max-height: 30rem;">
<div class="col-2">
<Doughnut Id="00" Type="@Doughnut.ChartType.Doughnut" Data="@SimData()" BackgroundColor="@colors"></Doughnut>
</div>
<div class="col-4">
<ChartHist Id="01" Data="@histData(1)" Labels="@histLabel(1)" LineColor="rgb(7, 173, 236)" BackColor="rgba(107, 223, 255, 0.5)" ChartLabel="Ore 01"></ChartHist>
</div>
<div class="col-4">
<ChartHist Id="02" Data="@histData(2)" Labels="@histLabel(2)" LineColor="rgb(173, 7, 236)" BackColor="rgba(223,107, 255, 0.5)" ChartLabel="Ore 02"></ChartHist>
</div>
<div class="col-2">
<Doughnut Id="03" Type="@Doughnut.ChartType.Doughnut" Data="@SimData()" BackgroundColor="@colors"></Doughnut>
</div>
</div>
@code {
#if false
protected DtUtils.Periodo? periodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisTrim);
protected async Task setPeriodo(DtUtils.Periodo newPeriodo)
{
await Task.Delay(1);
periodo = newPeriodo;
await Task.Delay(1);
periodo = newPeriodo;
}
#endif
public List<DoughnutStyling> colors = new List<DoughnutStyling>();
@@ -51,19 +62,54 @@
await Task.Delay(1);
}
protected double[] SimData()
{
List<double> answ = new List<double>();
double currColor = 0;
for (int i = 0; i < 10; i++)
{
currColor = (double)(rnd.Next(10, 100)) / 10;
answ.Add(currColor);
if(currColor>7)
{
colors.Add(new DoughnutStyling("#28FF69", "ccc"));
}
else if (currColor > 3)
{
colors.Add(new DoughnutStyling("orange", "ccc"));
}
else
{
colors.Add(new DoughnutStyling("red", "ccc"));
}
}
return answ.ToArray();
}
protected async Task ReloadData()
{
Data.Clear();
Labels.Clear();
colors.Clear();
for (int x = 0; x < 5; x++)
{
Data.Add(x);
Labels.Add($"test n#: {x} - {x}min");
colors.Add(new DoughnutStyling("orange", "ccc"));
colors.Add(new DoughnutStyling("#2874A6", "ccc"));
}
await Task.Delay(1);
}
protected Random rnd = new Random();
protected string[] histLabel(int num)
{
List<string> answ = new List<string>();
for (int i = 0; i < 50; i++)
{
answ.Add($"LBL_{i:00}");
}
return answ.ToArray();
}
protected string[] histData(int num)
{
List<string> answ = new List<string>();
for (int i = 0; i < 50; i++)
{
answ.Add($"{(double)(rnd.Next(10, 100)) / 10 + i}");
}
return answ.ToArray();
}
}
@@ -0,0 +1,14 @@
@page "/TestLoading"
<h3>TestLoading</h3>
<div>
<label class="form-label">Tempo sim</label>
<input css="form-control" @bind="@expTime" type="number" />
</div>
<div>
<label class="form-label">Num steps</label>
<input css="form-control" @bind="@numSteps" type="number" />
</div>
<button class="btn btn-success" @onclick="StartLongTimer">Start</button>
<ProgressDisplay RefreshInterval="100" Title="@titleMsg" MaxVal="@maxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMSec" DisplaySize="ProgressDisplay.ModalSize.Medium" ModalCss="card alert-primary" SlowLimit="0.4"></ProgressDisplay>
@@ -0,0 +1,57 @@
namespace EgwCoreLib.BlazorTest.Pages
{
public partial class TestLoading
{
#region Protected Properties
protected double expTime { get; set; } = 6;
protected int numSteps { get; set; } = 4;
#endregion Protected Properties
#region Protected Methods
protected async Task StartLongTimer()
{
maxVal = numSteps * 10;
double stdWait = expTime / numSteps;
int nextWait = 1000;
int stepVal = maxVal / numSteps;
// imposto i valori x progress..
expTimeMSec = (int)(stdWait * 1000);
//nextVal = stepVal;
for (int currStep = 1; currStep <= numSteps; currStep++)
{
// aggiorno valori
currVal = (currStep - 1) * stepVal;
nextVal = currStep * stepVal;
// se max mi fermo...
if (nextVal > maxVal)
{
nextVal = maxVal;
}
await InvokeAsync(StateHasChanged);
// simulo ritardo importante (da 2 a 3 volte
nextWait = (int)(rnd.Next(2000, 3000) * stdWait);
// attendo step successivi...
await Task.Delay(nextWait);
}
await Task.Delay(1);
currVal = maxVal;
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Fields
private int currVal = 100;
private int expTimeMSec = 10000;
private int maxVal = 100;
private int nextVal = 100;
private Random rnd = new Random();
private string titleMsg = "SIM Progress";
#endregion Private Fields
}
}
@@ -0,0 +1,53 @@
@page "/TestMultiLine"
@if (currDS == null)
{
<LoadingData></LoadingData>
}
else
{
<h3>TestMultiLine</h3>
<div class="row" style="height: 500px;">
<div class="col-6">
<ChartHist Id="01" Data="@histData(1)" Labels="@histLabel(1)" LineColor="rgb(7, 173, 236)" BackColor="rgba(107, 223, 255, 0.5)" ChartLabel="Ore 01"></ChartHist>
</div>
<div class="col-6">
<ChartMultiLine DataSets="currDS" ChartLabels="ChLabels"></ChartMultiLine>
</div>
</div>
}
<hr />
<div class="row">
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Small" DisplayMode="LoadingData.SpinMode.Normal"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Small" DisplayMode="LoadingData.SpinMode.Growl"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Small" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
</div>
</div>
<div class="row">
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Normal" DisplayMode="LoadingData.SpinMode.Normal"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Normal" DisplayMode="LoadingData.SpinMode.Growl"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Normal" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
</div>
</div>
<div class="row">
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.Normal"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.Growl"></LoadingData>
</div>
<div class="col-4">
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
</div>
</div>
@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using EgwCoreLib.BlazorTest;
using EgwCoreLib.BlazorTest.Components;
using EgwCoreLib.BlazorTest.Shared;
using EgwCoreLib.Razor;
using EgwCoreLib.Razor.Data;
using static EgwCoreLib.Razor.Data.chartJsData;
namespace EgwCoreLib.BlazorTest.Pages
{
public partial class TestMultiLine
{
protected override async Task OnInitializedAsync()
{
currDS = null;
await Task.Delay(200);
await setupData();
}
protected List<chartJsData.chartJsDataSetXY>? currDS { get; set; } = null;
protected List<string>? ChLabels { get; set; } = null;
protected Random rnd = new Random();
private async Task setupData()
{
currDS = null;
List<chartJsData.chartJsDataSetXY> currDemo = new List<chartJsData.chartJsDataSetXY>();
ChLabels = new List<string>();
int numMesi = 6;
for (int iMese = 1; iMese <= numMesi; iMese++)
{
ChLabels.Add($"{iMese:00}");
}
for (int iSerie = 0; iSerie < 4; iSerie++)
{
// simulo 12 mesi...
List<chartJsXY> simData = new List<chartJsXY>();
for (int iMese = 1; iMese <= numMesi; iMese++)
{
simData.Add(new chartJsXY() { x = iMese, y = iMese + rnd.Next(-4, 4) });
}
int rCol = rnd.Next(0, 155);
int gCol = rnd.Next(0, 155);
int bCol = rnd.Next(0, 100);
chartJsData.chartJsDataSetXY singleData = new chartJsData.chartJsDataSetXY()
{
label = $"Data_{iSerie:00}",
data = simData,
borderColor = $"#{10 + rCol:X2}{30 + gCol:X2}{100 + bCol:X2}",
backgroundColor = $"rgba({60 + rCol},{80 + gCol},{155 + bCol},0.3)",
lineTension = 0,
stepped = iSerie % 5 == 0,
fill = iSerie % 3 == 0 ? "start" : "false"
};
// aggiungo
currDemo.Add(singleData);
}
currDS = currDemo;
await Task.Delay(10);
}
protected string[] histLabel(int num)
{
List<string> answ = new List<string>();
for (int i = 0; i < 50; i++)
{
answ.Add($"LBL_{i:00}");
}
return answ.ToArray();
}
protected string[] histData(int num)
{
List<string> answ = new List<string>();
for (int i = 0; i < 50; i++)
{
answ.Add($"{(double)(rnd.Next(10, 100)) / 10 + i}");
}
return answ.ToArray();
}
}
}
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
@if (UseBuiltinDiv)
{
<div class="modal alert-popup" tabindex="-1" style="display:block" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<!-- Edit form for the current item -->
<div class="modal-body" @ref="Element">
<button class="btn btn-primary p-2 m-1 w-25" data-action="startButton">@ScanBtnTitle</button>
<button class="btn btn-secondary p-2 m-1 w-25" data-action="resetButton">@ResetBtnTitle</button>
<button type="button" class="btn btn-info p-2 m-1 w-25" data-action="closeButton">@CloseBtnTitle</button>
<div data-action="sourceSelectPanel" style="display:none">
<label for="sourceSelect">@SelectDeviceBtnTitle:</label>
<select data-action="sourceSelect" style="max-width:100%" class="form-select form-control">
</select>
</div>
<div>
<video id="video"
muted
webkit-playsinline
playsinline
x-webkit-airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
style="min-height:150px;max-height:50%; max-width: 100%;border: 1px solid gray"></video>
</div>
</div>
</div>
</div>
</div>
}
+260
View File
@@ -0,0 +1,260 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using EgwCoreLib.Utils;
using ZXingBlazor.Components;
namespace EgwCoreLib.Razor
{
public partial class BarcodeReader : IAsyncDisposable
{
[Inject]
[NotNull]
private IJSRuntime? JS { get; set; }
private IJSObjectReference? module;
private DotNetObjectReference<BarcodeReader>? Instance { get; set; }
[NotNull]
private StorageService? Storage { get; set; }
/// <summary>
/// Scan button title
/// </summary>
[Parameter]
public string ScanBtnTitle { get; set; } = "扫码";
/// <summary>
/// Reset button title
/// </summary>
[Parameter]
public string ResetBtnTitle { get; set; } = "复位";
/// <summary>
/// Close button title
/// </summary>
[Parameter]
public string CloseBtnTitle { get; set; } = "关闭";
/// <summary>
/// Select device button title
/// </summary>
[Parameter]
public string SelectDeviceBtnTitle { get; set; } = "选择设备";
/// <summary>
/// Scan result callback method
/// </summary>
[Parameter]
public EventCallback<string> ScanResult { get; set; }
/// <summary>
/// Close scan code callback method
/// </summary>
[Parameter]
public EventCallback Close { get; set; }
/// <summary>
/// Error callback method
/// </summary>
[Parameter]
public Func<string, Task>? OnError { get; set; }
/// <summary>
/// Use builtin Div
/// </summary>
[Parameter] public bool UseBuiltinDiv { get; set; } = true;
/// <summary>
/// Decode only Pdf417 format
/// </summary>
[Parameter]
public bool Pdf417Only { get; set; }
/// <summary>
/// Decode Once or Decode Continuously, default is Once
/// </summary>
[Parameter]
public bool Decodeonce { get; set; } = true;
/// <summary>
/// Decode All Formats, performance is poor, you can set options.formats to customize specify the encoding formats. The default is false
/// </summary>
[Parameter]
public bool DecodeAllFormats { get; set; }
/// <summary>
/// ZXingOptions
/// </summary>
[Parameter]
public ZXingOptions? Options { get; set; }
/// <summary>
///
/// </summary>
public ElementReference Element { get; set; }
/// <summary>
/// Device ID
/// </summary>
[Parameter]
public string? DeviceID { get; set; }
/// <summary>
/// Save the last used device ID to be called automatically next time
/// </summary>
[Parameter]
public bool SaveDeviceID { get; set; } = true;
// To prevent making JavaScript interop calls during prerendering
protected override async Task OnAfterRenderAsync(bool firstRender)
{
try
{
if (!firstRender) return;
Storage = new StorageService(JS);
module = await JS.InvokeAsync<IJSObjectReference>("import", "./_content/EgwCoreLib.Razor/BarcodeReader.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
Instance = DotNetObjectReference.Create(this);
if (Options == null)
{
Options = new ZXingOptions()
{
Pdf417 = Pdf417Only,
Decodeonce = Decodeonce,
DecodeAllFormats = DecodeAllFormats,
//TRY_HARDER = true
};
}
try
{
if (SaveDeviceID) DeviceID = await Storage.GetValue("CamsDeviceID", DeviceID);
}
catch (Exception)
{
}
await module.InvokeVoidAsync("init", Instance, Element, Element.Id, Options, DeviceID);
}
catch (Exception e)
{
if (OnError != null) await OnError.Invoke(e.Message);
}
}
public async Task Start()
{
await module!.InvokeVoidAsync("start", Element.Id);
}
public async Task Stop()
{
await module!.InvokeVoidAsync("stop", Element.Id);
}
public async Task Reload()
{
await module!.InvokeVoidAsync("reload", Element.Id);
}
[JSInvokable]
public async Task GetResult(string val) => await ScanResult.InvokeAsync(val);
[JSInvokable]
public async Task CloseScan() => await Close.InvokeAsync();
[JSInvokable]
public async Task GetError(string err)
{
if (OnError != null) await OnError.Invoke(err);
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
await module!.InvokeVoidAsync("destroy", Element.Id);
Instance?.Dispose();
if (module is not null)
{
await module.DisposeAsync();
}
}
/// <summary>
/// 选择摄像头回调方法
/// </summary>
/// <param name="base64encodedstring"></param>
/// <returns></returns>
[JSInvokable]
public async Task SelectDeviceID(string deviceID, string deviceName)
{
try
{
if (SaveDeviceID)
{
await Storage.SetValue("CamsDeviceID", deviceID);
await Storage.SetValue("CamsDeviceName", deviceName);
}
}
catch
{
}
}
#region StorageService
private class StorageService
{
private readonly IJSRuntime JSRuntime;
public StorageService(IJSRuntime jsRuntime)
{
JSRuntime = jsRuntime;
}
public async Task SetValue<TValue>(string key, TValue value)
{
await JSRuntime.InvokeVoidAsync("eval", $"localStorage.setItem('{key}', '{value}')");
}
public async Task<TValue?> GetValue<TValue>(string key, TValue? def)
{
try
{
var cValue = await JSRuntime.InvokeAsync<TValue>("eval", $"localStorage.getItem('{key}');");
return cValue ?? def;
}
catch
{
var cValue = await JSRuntime.InvokeAsync<string>("eval", $"localStorage.getItem('{key}');");
if (cValue == null)
return def;
var newValue = GetValueI<TValue>(cValue);
return newValue ?? def;
}
}
public static T? GetValueI<T>(string value)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T?)converter.ConvertFrom(value);
}
return default;
//return (T)Convert.ChangeType(value, typeof(T));
}
public async Task RemoveValue(string key)
{
await JSRuntime.InvokeVoidAsync("eval", $"localStorage.removeItem('{key}')");
}
}
#endregion
}
}
+317
View File
@@ -0,0 +1,317 @@
import './lib/zxing/zxing.min.js';
let codeReader = null;
let id = null;
let supportsVibrate = false;
let opt = null;
let inst = null;
let selectedDeviceId = null;
let deviceID = null;
let element = null;
let debug = false;
export function vibrate() {
if (supportsVibrate) navigator.vibrate(1000);
}
export function init(instance, ele, elementid, options, deviceid) {
console.log('init' + elementid);
inst = instance;
opt = options;
id = elementid;
deviceID = deviceid;
element = ele;
debug = options.debug;
supportsVibrate = "vibrate" in navigator;
let startButton = element.querySelector("[data-action=startButton]");
let resetButton = element.querySelector("[data-action=resetButton]");
let closeButton = element.querySelector("[data-action=closeButton]");
if (startButton) startButton.addEventListener('click', () => {
start(elementid);
})
if (resetButton) resetButton.addEventListener('click', () => {
stop(elementid);
if (debug) console.log('Reset.')
})
if (closeButton) closeButton.addEventListener('click', () => {
stop(elementid);
if (debug) console.log('closeButton.')
instance.invokeMethodAsync("CloseScan");
})
load(elementid);
}
export function reload(elementid) {
load(elementid);
}
function genHints(opt) {
const hints = new Map();
if (opt.TRY_HARDER) {
hints.set(ZXing.DecodeHintType.TRY_HARDER, opt.TRY_HARDER);
}
if (opt.ASSUME_CODE_39_CHECK_DIGIT) {
hints.set(ZXing.DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT, opt.ASSUME_CODE_39_CHECK_DIGIT);
}
if (opt.ASSUME_GS1) {
hints.set(ZXing.DecodeHintType.ASSUME_GS1, opt.ASSUME_GS1);
}
if (opt.CHARACTER_SET) {
hints.set(ZXing.DecodeHintType.CHARACTER_SET, opt.CHARACTER_SET);
}
if (opt.OTHER) {
hints.set(ZXing.DecodeHintType.OTHER, opt.OTHER);
}
if (opt.PURE_BARCODE) {
hints.set(ZXing.DecodeHintType.PURE_BARCODE, opt.PURE_BARCODE);
}
if (opt.RETURN_CODABAR_START_END) {
hints.set(ZXing.DecodeHintType.RETURN_CODABAR_START_END, opt.RETURN_CODABAR_START_END);
}
if (opt.TRY_HARDER) {
hints.set(ZXing.DecodeHintType.TRY_HARDER, opt.TRY_HARDER);
}
return hints;
}
export function load(elementid) {
if (id == elementid) {
const sourceSelect = element.querySelector("[data-action=sourceSelect]");
const sourceSelectPanel = element.querySelector("[data-action=sourceSelectPanel]");
const hints = genHints(opt);
if (opt.pdf417) {
codeReader = new ZXing.BrowserPDF417Reader(hints);
if (debug) console.log('ZXing code PDF417 reader initialized')
} else if (opt.decodeAllFormats) {
const formats = opt.formats;
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, formats);
codeReader = new ZXing.BrowserMultiFormatReader(hints)
if (debug) console.log('ZXing code reader initialized with all formats')
} else {
codeReader = new ZXing.BrowserMultiFormatReader(hints)
if (debug) console.log('ZXing code reader initialized')
}
codeReader.timeBetweenDecodingAttempts = opt.timeBetweenDecodingAttempts;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices
.getUserMedia({ audio: false, video: true })
.then(() => {
codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
if (deviceID != null) {
selectedDeviceId = deviceID
} else if (videoInputDevices.length > 1) {
selectedDeviceId = videoInputDevices[1].deviceId
} else {
selectedDeviceId = videoInputDevices[0].deviceId
}
if (debug) console.log('videoInputDevices:' + videoInputDevices.length);
if (videoInputDevices.length > 1) {
sourceSelect.innerHTML = '';
videoInputDevices.forEach((device) => {
const sourceOption = document.createElement('option');
if (device.label === '') {
sourceOption.text = 'Camera' + (sourceSelect.length + 1);
} else {
sourceOption.text = device.label
}
sourceOption.value = device.deviceId
if (selectedDeviceId != null && device.deviceId == selectedDeviceId) {
sourceOption.selected = true
}
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
inst.invokeMethodAsync('SelectDeviceID', selectedDeviceId, sourceSelect.options[sourceSelect.selectedIndex].text);
codeReader.reset();
start(elementid);
}
sourceSelectPanel.style.display = 'block'
}
start(elementid);
})
.catch((err) => {
console.log(err)
inst.invokeMethodAsync("GetError", err + '');
})
})
.catch((err) => {
console.error(`An error occurred: ${err}`);
inst.invokeMethodAsync('GetError', `An error occurred: ${err}`);
});
}
}
}
export function start(elementid) {
if (undefined !== codeReader && null !== codeReader && id == elementid) {
if (opt.decodeonce) {
codeReader.decodeOnceFromVideoDevice(selectedDeviceId, 'video').then((result) => {
if (debug) console.log(result)
vibrate();
if (debug) console.log('autostop');
codeReader.reset();
return inst.invokeMethodAsync("GetResult", result.text);
}).catch((err) => {
if (err && !(err instanceof ZXing.NotFoundException)) {
console.log(err)
inst.invokeMethodAsync("GetError", err + '');
}
})
} else {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
if (debug) console.log(result)
vibrate();
if (debug) console.log('None-stop');
inst.invokeMethodAsync("GetResult", result.text);
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.log(err)
inst.invokeMethodAsync("GetError", err + '');
}
})
}
var x = `decodeContinuously`;
if (opt.decodeonce) x = `decodeOnce`;
if (debug) console.log(`Started ` + x + ` decode from camera with id ${selectedDeviceId}`)
if (debug) console.log(id, 'start');
}
}
export function stop(elementid) {
if (undefined !== codeReader && null !== codeReader && id == elementid) {
codeReader.reset();
if (debug) console.log(id, 'stop');
}
}
export function QRCodeSvg(instance, input, element, tobase64, size = 300) {
const codeWriter = new ZXing.BrowserQRCodeSvgWriter()
if (debug) console.log('ZXing code writer initialized')
if (tobase64) {
const elementTemp = document.createElement('elementTemp');
codeWriter.writeToDom(elementTemp, input, size, size)
let svgElement = elementTemp.firstChild
const svgData = (new XMLSerializer()).serializeToString(svgElement)
//const blob = new Blob([svgData])
instance.invokeMethodAsync("GetQRCode", svgData);
} else {
codeWriter.writeToDom(element.querySelector("[data-action=result]"), input, size, size)
}
}
export function DecodeFormImage(instance, element, options, data) {
var codeReaderImage = null;
const hints = genHints(options);
if (options.pdf417) {
codeReaderImage = new ZXing.BrowserPDF417Reader(hints);
if (debug) console.log('ZXing code PDF417 reader initialized')
} else if (options.decodeAllFormats) {
const formats = options.formats;
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, formats);
codeReaderImage = new ZXing.BrowserMultiFormatReader(hints)
if (debug) console.log('ZXing code reader initialized with all formats')
} else {
codeReaderImage = new ZXing.BrowserMultiFormatReader(hints)
if (debug) console.log('ZXing code reader initialized')
}
if (debug) console.log('ZXing code reader initialized')
if (data != null) {
codeReaderImage.decodeFromImageUrl(data).then(result => {
if (result) {
vibrate();
if (debug) console.log(result.text);
instance.invokeMethodAsync('GetResult', result.text)
}
}).catch((err) => {
if (err) {
console.log(err)
instance.invokeMethodAsync('GetError', err.message)
}
})
}
else {
const resetFile = () => {
let file = element.querySelector('[type="file"]')
if (file) {
file.removeEventListener('change', scanImageHandler)
file.remove()
}
file = document.createElement('input')
file.setAttribute('type', 'file')
file.setAttribute('hidden', 'true')
file.setAttribute('accept', 'image/*')
//file.setAttribute('capture', 'true')
element.append(file)
file.addEventListener('change', scanImageHandler)
codeReaderImage.file = file
return file
}
const scanImageHandler = () => {
const files = codeReaderImage.file.files
if (files.length === 0) {
return
}
const reader = new FileReader()
reader.onloadend = e => {
codeReaderImage.decodeFromImageUrl(e.target.result).then(result => {
if (result) {
vibrate();
if (debug) console.log(result.text);
instance.invokeMethodAsync('GetResult', result.text)
} else {
instance.invokeMethodAsync('GetError', "no valid barcode detected")
}
}).catch((err) => {
if (err) {
console.log(err)
instance.invokeMethodAsync('GetError', err.message)
}
})
}
reader.readAsDataURL(files[0])
}
let file = resetFile()
file.click()
}
}
export function destroy(elementid) {
if (undefined !== codeReader && null !== codeReader && id == elementid) {
codeReader.reset();
codeReader = null;
//id = null;
id = null;
opt = null;
inst = null;
selectedDeviceId = null;
deviceID = null;
element = null;
if (debug) console.log(id, 'destroy');
}
}
-1
View File
@@ -1,5 +1,4 @@
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
+30 -9
View File
@@ -8,10 +8,13 @@ namespace EgwCoreLib.Razor
#region Public Properties
[Parameter]
public string BackColor { get; set; } = "";
public bool AddSlash { get; set; } = false;
[Parameter]
public string TextColor { get; set; } = "";
public int AnimationTime { get; set; } = 0;
[Parameter]
public string BackColor { get; set; } = "";
[Parameter]
public string ChartLabel { get; set; } = "";
@@ -20,7 +23,10 @@ namespace EgwCoreLib.Razor
public string[]? Data { get; set; }
[Parameter]
public string Id { get; set; } = "MyHist";
public string GridColor { get; set; } = "";
[Parameter]
public string Id { get; set; } = "000";
[Parameter]
public string[]? Labels { get; set; }
@@ -29,10 +35,7 @@ namespace EgwCoreLib.Razor
public string LineColor { get; set; } = "";
[Parameter]
public string GridColor { get; set; } = "";
[Parameter]
public int AnimationTime { get; set; } = 0;
public string TextColor { get; set; } = "";
#endregion Public Properties
@@ -40,6 +43,13 @@ namespace EgwCoreLib.Razor
protected override async Task OnAfterRenderAsync(bool firstRender)
{
string jsPath = "./_content/EgwCoreLib.Razor/ChartHist.razor.js";
if (AddSlash)
{
jsPath = "/." + jsPath;
}
module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", jsPath);
await Task.Delay(50);
await renderChart();
}
@@ -59,7 +69,8 @@ namespace EgwCoreLib.Razor
type = "bar",
options = new
{
responsive = true,
Responsive = true,
MaintainAspectRatio = false,
scales = new
{
yAxes = new
@@ -109,7 +120,8 @@ namespace EgwCoreLib.Razor
},
data = new
{
datasets = new[]{
datasets = new[]
{
new
{
data = Data,
@@ -128,5 +140,14 @@ namespace EgwCoreLib.Razor
}
#endregion Protected Methods
#region Private Properties
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
private IJSObjectReference module { get; set; } = null!;
#endregion Private Properties
}
}
+11
View File
@@ -0,0 +1,11 @@
///Setup del chart desiderato con id univoco
window.setup = (id, config) => {
var ctx = document.getElementById(id);
if (window['histChart' + id] instanceof Chart) {
window['histChart' + id].destroy();
window['histChart' + id] = new Chart(ctx, config);
}
else {
window['histChart' + id] = new Chart(ctx, config);
}
}
+4
View File
@@ -0,0 +1,4 @@
@using Microsoft.JSInterop
<canvas id="@Id"></canvas>
+131
View File
@@ -0,0 +1,131 @@
using EgwCoreLib.Razor.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Reflection.Emit;
namespace EgwCoreLib.Razor
{
public partial class ChartMultiLine
{
#region Public Properties
[Parameter]
public bool AddSlash { get; set; } = false;
[Parameter]
public int AnimationTime { get; set; } = 0;
[Parameter]
public List<chartJsData.chartJsDataSetXY> DataSets { get; set; } = null!;
[Parameter]
public string GridColor { get; set; } = "";
[Parameter]
public string Id { get; set; } = "myMLP";
[Parameter]
public List<string> ChartLabels { get; set; } = new List<string>();
[Parameter]
public string TextColor { get; set; } = "";
#endregion Public Properties
#region Protected Methods
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
string jsPath = "./_content/EgwCoreLib.Razor/ChartMultiLine.razor.js";
if (AddSlash)
{
jsPath = "/." + jsPath;
}
module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", jsPath);
await Task.Delay(250);
await renderChart();
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
List<dynamic> dynData = new List<dynamic>();
foreach (var item in DataSets)
{
dynData.Add(new
{
data = item.valY,
label = item.label,
borderColor = item.borderColor,
backgroundColor = item.backgroundColor,
lineTension = item.lineTension,
stepped = item.stepped,
fill = item.fill
});
}
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
var config = new
{
type = "line",
options = new
{
Responsive = true,
MaintainAspectRatio = false,
plugins = new
{
legend = new
{
display = true,
labels = new
{
color = TextColor,
},
},
},
Animation = new
{
Duration = AnimationTime
},
},
data = new
{
datasets = dynData,
labels = ChartLabels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
#endregion Protected Methods
#region Private Properties
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
private IJSObjectReference module { get; set; } = null!;
#endregion Private Properties
}
}
+12
View File
@@ -0,0 +1,12 @@
///Setup del chart desiderato con id univoco
window.setup = (id, config) => {
var ctx = document.getElementById(id);
if (window['mlChart' + id] instanceof Chart) {
window['mlChart' + id].destroy();
window['mlChart' + id] = new Chart(ctx, config);
}
else {
window['mlChart' + id] = new Chart(ctx, config);
}
}
-1
View File
@@ -1,5 +1,4 @@
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
+36 -24
View File
@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
using EgwCoreLib.Razor.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace EgwCoreLib.Razor
{
@@ -14,28 +8,33 @@ namespace EgwCoreLib.Razor
{
#region Public Properties
[Parameter]
public bool AddSlash { get; set; } = false;
[Parameter]
public int AnimationTime { get; set; } = 0;
[Parameter]
public string BackColor { get; set; } = "";
[Parameter]
public string TextColor { get; set; } = "";
[Parameter]
public string GridColor { get; set; } = "";
[Parameter]
public string ChartLabel { get; set; } = "";
[Parameter]
public List<chartJsData.chartJsTSerie> DataTS { get; set; } = null!;
[Parameter]
public string GridColor { get; set; } = "";
[Parameter]
public string Id { get; set; } = "MyTs";
[Parameter]
public string LineColor { get; set; } = "";
[Parameter]
public string TextColor { get; set; } = "";
#endregion Public Properties
#region Protected Methods
@@ -43,27 +42,30 @@ namespace EgwCoreLib.Razor
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name = "firstRender"></param>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
string jsPath = "./_content/EgwCoreLib.Razor/ChartHist.razor.js";
if (AddSlash)
{
jsPath = "/." + jsPath;
}
module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", jsPath);
await Task.Delay(50);
await renderChart();
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name = "firstRender"></param>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
@@ -73,7 +75,8 @@ namespace EgwCoreLib.Razor
type = "line",
options = new
{
responsive = true,
Responsive = true,
MaintainAspectRatio = false,
scales = new
{
yAxes = new
@@ -141,5 +144,14 @@ namespace EgwCoreLib.Razor
}
#endregion Protected Methods
#region Private Properties
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
private IJSObjectReference module { get; set; } = null!;
#endregion Private Properties
}
}
+12
View File
@@ -0,0 +1,12 @@
///Setup del chart desiderato con id univoco
window.setup = (id, config) => {
var ctx = document.getElementById(id);
if (window['tsChart' + id] instanceof Chart) {
window['tsChart' + id].destroy();
window['tsChart' + id] = new Chart(ctx, config);
}
else {
window['tsChart' + id] = new Chart(ctx, config);
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
<svg viewBox="0 0 200 200" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="@innRad" fill="none" stroke="rgba(189, 195, 199, 0.5)" stroke-width="@sWidth" />
<circle cx="100" cy="100" r="@innRad" fill="none" stroke="@strokeColorVal" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@innRad * 6.28 * @valInner / @maxVal) calc(@innRad * 6.28 * (@maxVal - @valInner) / @maxVal)" />
<circle cx="100" cy="100" r="@innRad" fill="none" stroke="@StrokeColorVal" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@innRad * 6.28 * @valInner / @maxVal) calc(@innRad * 6.28 * (@maxVal - @valInner) / @maxVal)" />
@if (ShowCircleBtn)
{
<defs>
@@ -18,7 +18,7 @@
@if (showOuter)
{
<circle cx="100" cy="100" r="@outRad" fill=none stroke="rgba(189, 195, 199, 0.5)" class="bg-opacity-25" stroke-width="@sWidth" />
<circle cx="100" cy="100" r="@outRad" fill=none stroke="@strokeColorVal" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@outRad * 6.28 * @valOuter / @maxVal) calc(@outRad * 6.28 * (@maxVal - @valOuter) / @maxVal)" />
<circle cx="100" cy="100" r="@outRad" fill=none stroke="@StrokeColorValOuter" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@outRad * 6.28 * @valOuter / @maxVal) calc(@outRad * 6.28 * (@maxVal - @valOuter) / @maxVal)" />
}
<g transform="translate(100,100)">
<text id="TitleElem" style="@StyleTitolo" x="0" y="0">@Titolo</text>
+3 -1
View File
@@ -18,7 +18,9 @@ namespace EgwCoreLib.Razor
[Parameter]
public string StyleTesto { get; set; } = "font-size: 1em; fill: gray;";
[Parameter]
public string strokeColorVal { get; set; } = "#00FF66";
public string StrokeColorVal { get; set; } = "#00FF66";
[Parameter]
public string StrokeColorValOuter { get; set; } = "#00FF66";
/// <summary>
/// Indica se mostrare o meno il btn centrale
/// </summary>
+36
View File
@@ -0,0 +1,36 @@
<svg viewBox="0 0 200 200" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="@innRad" fill="none" stroke="rgba(189, 195, 199, 0.5)" stroke-width="@sWidth" />
@foreach (var item in ListInner)
{
<circle cx="100" cy="100" r="@innRad" fill="none" stroke="@item.Color" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@innRad * 6.2832 * @item.Value / @maxVal) calc(@innRad * 6.2832 * (@maxVal - @item.Value) / @maxVal)" />
}
@if (ShowCircleBtn)
{
<defs>
<radialGradient id="RadialGrad2">
<stop offset="0%" stop-color="#000000" />
<stop offset="80%" stop-color="#151515" />
<stop offset="90%" stop-color="#444444" />
<stop offset="100%" stop-color="#878787" />
</radialGradient>
</defs>
<circle cx="100" cy="100" r="@(innRad-sWidth)" fill="url(#RadialGrad2)" fill-opacity="0.5">
</circle>
}
@if (showOuter)
{
<circle cx="100" cy="100" r="@outRad" fill=none stroke="rgba(189, 195, 199, 0.5)" class="bg-opacity-25" stroke-width="@sWidth" />
@foreach (var item in ListOuter)
{
<circle cx="100" cy="100" r="@outRad" fill="none" stroke="@item.Color" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@outRad * 6.2832 * @item.Value / @maxVal) calc(@outRad * 6.2832 * (@maxVal - @item.Value) / @maxVal)" />
}
@* <circle cx="100" cy="100" r="@outRad" fill=none stroke="@StrokeColorValOuter" stroke-width="@sWidth" stroke-linecap="round" transform="rotate(-90,100,100)" stroke-dasharray="calc(@outRad * 6.28 * @valOuter / @maxVal) calc(@outRad * 6.28 * (@maxVal - @valOuter) / @maxVal)" /> *@
}
<g transform="translate(100,100)">
<text id="TitleElem" style="@StyleTitolo" x="0" y="0">@Titolo</text>
<text x="0" y="30" style="@StyleTesto">@Testo</text>
</g>
</svg>
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace EgwCoreLib.Razor
{
public partial class CircleGaugeMulti
{
[Parameter]
public string Titolo { get; set; } = "Titolo";
[Parameter]
public string Testo { get; set; } = "Testo";
[Parameter]
public string StyleTitolo { get; set; } = "font-size: 3em; font-weight:bold; fill: white;";
[Parameter]
public string StyleTesto { get; set; } = "font-size: 1em; fill: gray;";
[Parameter]
public List<CircSegm> ListInner { get; set; } = new List<CircSegm>();
[Parameter]
public List<CircSegm> ListOuter { get; set; } = new List<CircSegm>();
/// <summary>
/// Indica se mostrare o meno il btn centrale
/// </summary>
[Parameter]
public bool ShowCircleBtn { get; set; } = false;
/// <summary>
/// Valore MASSIMO da rappresentare (=100%)
/// </summary>
[Parameter]
public int maxVal { get; set; } = 0;
/// <summary>
/// Spessore dei cerchi da disegnare
/// </summary>
[Parameter]
public int sWidth { get; set; } = 10;
/// <summary>
/// Raggio cerchio interno (0..100)
/// </summary>
[Parameter]
public int innRad { get; set; } = 70;
/// <summary>
/// Raggio cerchio esterno (0..100)
/// </summary>
[Parameter]
public int outRad { get; set; } = 85;
private bool showOuter
{
get => ListOuter.Count > 0;
}
protected string calcDash(int currRad, int currVal)
{
string answ = $"{currRad * 6.2832 * currVal / maxVal:N0} {currRad * 6.2832 * (maxVal - currVal) / maxVal:N0}";
return answ;
}
/// <summary>
/// Parametri per disegno segmento circolare
/// </summary>
public class CircSegm
{
public int Value { get; set; } = 0;
public string Color { get; set; } = "#00FF66";
}
}
}
@@ -0,0 +1,7 @@
/* FIX per tyesto dentro SVG: https://www.fabiofranchino.com/blog/how-to-align-svg-text/ */
text {
text-anchor: middle;
/* align center */
dominant-baseline: middle;
/* vertical alignment fix */
}
@@ -0,0 +1,6 @@
/* FIX per tyesto dentro SVG: https://www.fabiofranchino.com/blog/how-to-align-svg-text/ */
text {
text-anchor: middle; /* align center */
dominant-baseline: middle; /* vertical alignment fix */
}
+1
View File
@@ -0,0 +1 @@
text{text-anchor:middle;dominant-baseline:middle;}
+29
View File
@@ -12,5 +12,34 @@
public decimal x { get; set; }
public decimal y { get; set; }
}
public class chartJsDataSetXY
{
public string label { get; set; } = "DataSet00";
public string borderColor { get; set; } = "blue";
public string backgroundColor { get; set; } = "aqua";
public double lineTension { get; set; } = 0;
public bool stepped { get; set; } = false;
public string fill { get; set; } = "false";
public List<chartJsXY> data { get; set; } = new List<chartJsXY>();
public string[] valX
{
get => data.Select(val => $"{val.x}").ToArray();
}
public string[] valY
{
get => data.Select(val => $"{val.y}").ToArray();
}
}
public class chartJsDataSetTS
{
public string label { get; set; } = "DataSet00";
public string borderColor { get; set; } = "blue";
public string backgroundColor { get; set; } = "aqua";
public double lineTension { get; set; } = 0;
public bool stepped { get; set; } = false;
public List<chartJsTSerie> data { get; set; } = new List<chartJsTSerie>();
}
}
}
+8 -6
View File
@@ -16,8 +16,8 @@
Doughnut
}
//[Parameter]
public string Id { get; set; } = "myChart";
[Parameter]
public string Id { get; set; } = "000";
[Parameter]
public ChartType Type { get; set; }
@@ -53,16 +53,18 @@
Options = new
{
Responsive = true,
MaintainAspectRatio = false
},
Data = new
{
Datasets = new[]
{
new { Data = Data, BackgroundColor = BackgroundColor.Select(x=>x.color), borderColor = BackgroundColor.Select(x=>x.border), borderWidth= 0, offset= 1, borderRadius = 0
}
},
new { Data = Data, BackgroundColor = BackgroundColor.Select(x=>x.color), borderColor = BackgroundColor.Select(x=>x.border), borderWidth= 0, offset= 1, borderRadius = 0 }
},
Labels = Labels
}
},
Responsive = true,
MaintainAspectRatio = false
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
+4 -4
View File
@@ -1,12 +1,12 @@
///Setup del chart desiderato con id univoco
window.setup = (id, config) => {
var ctx = document.getElementById(id);
if (window['myChart'] instanceof Chart) {
window['myChart'].destroy();
window['myChart'] = new Chart(ctx, config);
if (window['myChart' + id] instanceof Chart) {
window['myChart' + id].destroy();
window['myChart' + id] = new Chart(ctx, config);
}
else {
window['myChart'] = new Chart(ctx, config);
window['myChart' + id] = new Chart(ctx, config);
}
}
+15
View File
@@ -29,10 +29,25 @@
</ItemGroup>
<ItemGroup>
<None Remove="ChartHist.razor.js" />
<None Remove="ChartTS - Copy.razor.js" />
<None Remove="ChartTS.razor.js" />
<None Remove="Doughnut.razor.js" />
</ItemGroup>
<ItemGroup>
<Content Include="ChartMultiLine.razor.js">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="ChartTS.razor.js">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="ChartHist.razor.js">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Doughnut.razor.js">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
+81 -5
View File
@@ -1,6 +1,82 @@
<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>
@if (DisplaySize == CtrlSize.Small)
{
<div class="@DisplayCss p-1 m-1">
<div class="w-100 d-flex justify-content-around text-center my-1 py-1">
<div class="d-flex text-center">
<div class="mx-1 text-nowrap">
<b>@Title</b>
</div>
@if (DisplayMode == SpinMode.Normal)
{
<i class="fas fa-spinner fa-spin"></i>
}
else if (DisplayMode == SpinMode.Growl)
{
<div class="spinner-grow" role="status" style="width: 1.3rem; height: 1.3rem;">
<span class="visually-hidden">Loading...</span>
</div>
}
else
{
<div class="modalOrd-content-small text-center">
<div class="loader">
<span class="load"></span>
</div>
</div>
}
</div>
</div>
</div>
</div>
}
else if (DisplaySize == CtrlSize.Normal)
{
<div class="@DisplayCss d-flex justify-content-around p-1 m-1">
<div class="w-100 text-center my-1 py-1">
<h3>@Title</h3>
@if (DisplayMode == SpinMode.Normal)
{
<i class="fas fa-spinner fa-spin fa-3x"></i>
}
else if (DisplayMode == SpinMode.Growl)
{
<div class="spinner-grow" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
}
else
{
<div class="modalOrd-content text-center">
<div class="loader">
<span class="load"></span>
</div>
</div>
}
</div>
</div>
}
else if (DisplaySize == CtrlSize.Large)
{
<div class="@DisplayCss d-flex justify-content-around p-1 m-1">
<div class="w-100 text-center my-2 py-2">
<h1>@Title</h1>
@if (DisplayMode == SpinMode.Normal)
{
<i class="fas fa-spinner fa-spin fa-5x"></i>
}
else if (DisplayMode == SpinMode.Growl)
{
<div class="spinner-grow" role="status" style="width: 5rem; height: 5rem;">
<span class="visually-hidden">Loading...</span>
</div>
}
else
{
<div class="modalOrd-content-large text-center">
<div class="loader">
<span class="load"></span>
</div>
</div>
}
</div>
</div>
}
+56
View File
@@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Components;
namespace EgwCoreLib.Razor
{
public partial class LoadingData
{
#region Public Enums
public enum CtrlSize
{
Normal,
Small,
Large
}
public enum SpinMode
{
Normal,
Growl,
BounceLine
}
#endregion Public Enums
#region Public Properties
/// <summary>
/// Modalità display principale
/// default: alert alert-primary
/// </summary>
[Parameter]
public string DisplayCss { get; set; } = "alert alert-primary";
/// <summary>
/// Modalità animazione
/// default: Normal
/// </summary>
[Parameter]
public SpinMode DisplayMode { get; set; } = SpinMode.Normal;
/// <summary>
/// Dimensione display
/// default: Normal
/// </summary>
[Parameter]
public CtrlSize DisplaySize { get; set; } = CtrlSize.Normal;
/// <summary>
/// Titolo da mostrare nel pannello
/// </summary>
[Parameter]
public string Title { get; set; } = "loading data";
#endregion Public Properties
}
}
+126
View File
@@ -0,0 +1,126 @@
.modalOrd {
position: relative;
z-index: 9999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: #000000;
background-color: rgba(0, 0, 0, 0.6);
}
.loader {
width: 5rem;
position: relative;
}
.loader-text {
position: relative;
top: 0;
padding: 0;
margin: 0;
color: #C8B6FF;
animation: text_713 3.5s ease both infinite;
font-size: 0.8rem;
letter-spacing: 1px;
}
.load {
background-color: #9A79FF;
border-radius: 3rem;
display: block;
height: 1rem;
width: 1rem;
bottom: 0;
position: relative;
transform: translateX(64px);
animation: loading_713 3.5s ease both infinite;
}
.load::before {
position: relative;
content: "";
width: 100%;
height: 100%;
background-color: #D1C2FF;
border-radius: inherit;
animation: loading2_713 3.5s ease both infinite;
}
@keyframes text_713 {
0% {
letter-spacing: 1px;
transform: translateX(0px);
}
40% {
letter-spacing: 2px;
transform: translateX(26px);
}
80% {
letter-spacing: 1px;
transform: translateX(32px);
}
90% {
letter-spacing: 2px;
transform: translateX(0px);
}
100% {
letter-spacing: 1px;
transform: translateX(0px);
}
}
@keyframes loading_713 {
0% {
width: 16px;
transform: translateX(0px);
}
40% {
width: 100%;
transform: translateX(0px);
}
80% {
width: 16px;
transform: translateX(64px);
}
90% {
width: 100%;
transform: translateX(0px);
}
100% {
width: 16px;
transform: translateX(0px);
}
}
@keyframes loading2_713 {
0% {
transform: translateX(0px);
width: 16px;
}
40% {
transform: translateX(0%);
width: 80%;
}
80% {
width: 100%;
transform: translateX(0px);
}
90% {
width: 80%;
transform: translateX(15px);
}
100% {
transform: translateX(0px);
width: 16px;
}
}
/* Modal Content/Box */
.modalOrd-content-small {
margin: 0.4rem auto;
width: 50%;
}
.modalOrd-content {
margin: 1.4rem auto;
padding-left: 20%;
width: 50%;
}
.modalOrd-content-large {
margin: 2.4rem auto;
padding-left: 20%;
width: 50%;
}
+147
View File
@@ -0,0 +1,147 @@
.modalOrd {
position: relative;
z-index: 9999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.6);
}
.loader {
width: 5rem;
position: relative;
}
.loader-text {
position: relative;
top: 0;
padding: 0;
margin: 0;
color: #C8B6FF;
animation: text_713 3.5s ease both infinite;
font-size: .8rem;
letter-spacing: 1px;
}
.load {
background-color: #9A79FF;
border-radius: 3rem;
display: block;
height: 1rem;
width: 1rem;
bottom: 0;
position: relative;
transform: translateX(64px);
animation: loading_713 3.5s ease both infinite;
}
.load::before {
position: relative;
content: "";
width: 100%;
height: 100%;
background-color: #D1C2FF;
border-radius: inherit;
animation: loading2_713 3.5s ease both infinite;
}
@keyframes text_713 {
0% {
letter-spacing: 1px;
transform: translateX(0px);
}
40% {
letter-spacing: 2px;
transform: translateX(26px);
}
80% {
letter-spacing: 1px;
transform: translateX(32px);
}
90% {
letter-spacing: 2px;
transform: translateX(0px);
}
100% {
letter-spacing: 1px;
transform: translateX(0px);
}
}
@keyframes loading_713 {
0% {
width: 16px;
transform: translateX(0px);
}
40% {
width: 100%;
transform: translateX(0px);
}
80% {
width: 16px;
transform: translateX(64px);
}
90% {
width: 100%;
transform: translateX(0px);
}
100% {
width: 16px;
transform: translateX(0px);
}
}
@keyframes loading2_713 {
0% {
transform: translateX(0px);
width: 16px;
}
40% {
transform: translateX(0%);
width: 80%;
}
80% {
width: 100%;
transform: translateX(0px);
}
90% {
width: 80%;
transform: translateX(15px);
}
100% {
transform: translateX(0px);
width: 16px;
}
}
/* Modal Content/Box */
.modalOrd-content-small {
margin: 0.4rem auto;
width: 50%;
}
.modalOrd-content {
margin: 1.4rem auto;
padding-left: 20%;
width: 50%;
}
.modalOrd-content-large {
margin: 2.4rem auto;
padding-left: 20%;
width: 50%;
}
+1
View File
@@ -0,0 +1 @@
.modalOrd{position:relative;z-index:9999;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,.6);}.loader{width:5rem;position:relative;}.loader-text{position:relative;top:0;padding:0;margin:0;color:#c8b6ff;animation:text_713 3.5s ease both infinite;font-size:.8rem;letter-spacing:1px;}.load{background-color:#9a79ff;border-radius:3rem;display:block;height:1rem;width:1rem;bottom:0;position:relative;transform:translateX(64px);animation:loading_713 3.5s ease both infinite;}.load::before{position:relative;content:"";width:100%;height:100%;background-color:#d1c2ff;border-radius:inherit;animation:loading2_713 3.5s ease both infinite;}@keyframes text_713{0%{letter-spacing:1px;transform:translateX(0);}40%{letter-spacing:2px;transform:translateX(26px);}80%{letter-spacing:1px;transform:translateX(32px);}90%{letter-spacing:2px;transform:translateX(0);}100%{letter-spacing:1px;transform:translateX(0);}}@keyframes loading_713{0%{width:16px;transform:translateX(0);}40%{width:100%;transform:translateX(0);}80%{width:16px;transform:translateX(64px);}90%{width:100%;transform:translateX(0);}100%{width:16px;transform:translateX(0);}}@keyframes loading2_713{0%{transform:translateX(0);width:16px;}40%{transform:translateX(0%);width:80%;}80%{width:100%;transform:translateX(0);}90%{width:80%;transform:translateX(15px);}100%{transform:translateX(0);width:16px;}}.modalOrd-content-small{margin:.4rem auto;width:50%;}.modalOrd-content{margin:1.4rem auto;padding-left:20%;width:50%;}.modalOrd-content-large{margin:2.4rem auto;padding-left:20%;width:50%;}
-14
View File
@@ -1,14 +0,0 @@
<div class="row p-3 m-2">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<div class="row">
<div class="col-6 text-end">
<div class="spinner-grow" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="col-6">
<h3>loading data</h3>
</div>
</div>
</div>
</div>
-6
View File
@@ -1,6 +0,0 @@
<div class="row p-2 m-2">
<div class="col-12 text-center mt-2 py-2 alert alert-primary">
<b>loading data</b>
<i class="fas fa-spinner fa-spin fa-2x"></i>
</div>
</div>
+4 -3
View File
@@ -16,7 +16,7 @@ namespace EgwCoreLib.Razor
public double maxVal { get; set; } = 100;
[Parameter]
public int redLim { get; set; } = 10;
public double redLim { get; set; } = 10;
[Parameter]
public bool showAct { get; set; } = true;
@@ -28,7 +28,7 @@ namespace EgwCoreLib.Razor
public bool singleLine { get; set; } = false;
[Parameter]
public int yelLim { get; set; } = 20;
public double yelLim { get; set; } = 20;
#endregion Public Properties
@@ -76,6 +76,8 @@ namespace EgwCoreLib.Razor
private int percWidthNum { get => (int)(100 * currVal / maxVal); }
private int redLimNum { get => (int)(100 * redLim / maxVal); }
private string textStyle
{
get => $"text-{currStyle}";
@@ -87,7 +89,6 @@ namespace EgwCoreLib.Razor
}
private int yelLimNum { get => (int)(100 * yelLim / maxVal); }
private int redLimNum { get => (int)(100 * redLim / maxVal); }
#endregion Private Properties
}
+32
View File
@@ -0,0 +1,32 @@
@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="@modalDialogCss rounded shadow">
<div class="modal-content">
<div class="@ModalCss text-center">
<div class="card-header">
@if (!string.IsNullOrEmpty(Title))
{
<b>@Title</b>
}
</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>
</div>
</div>
</dialog>
}
+233
View File
@@ -0,0 +1,233 @@
using Microsoft.AspNetCore.Components;
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;
set
{
actVal = value;
startVal = value;
isLoading = actVal < MaxVal;
}
}
/// <summary>
/// Dimensioni attese modale
/// default: ModalSize.Medium
/// </summary>
[Parameter]
public ModalSize DisplaySize { get; set; } = ModalSize.Medium;
/// <summary>
/// Tempo atteso per prossimo step
/// default: 10000
/// </summary>
[Parameter]
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>
/// Limite per anticipo slowdown (% della durata di ExpTimeMSec)
/// </summary>
[Parameter]
public double SlowLimit { get; set; } = 0.5;
/// <summary>
/// Numero di secondi prima (rispetto valore ExpTimeMsec) da cui iniziare rallentamento
/// </summary>
private int slowWindowMSec
{
get => (int)(ExpTimeMSec * SlowLimit);
}
/// <summary>
/// Titolo da mostrare (se "" NON lo mostra)
/// </summary>
[Parameter]
public string Title { get; set; } = "Progress";
#endregion Public Properties
#region Public Methods
public void Dispose()
{
uiTimer?.Dispose();
}
#endregion Public Methods
#region Protected Properties
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
protected override async Task OnParametersSetAsync()
{
// salvo valori aggiornamento...
if (ExpTimeMSec > 0)
{
lastUpdate = DateTime.Now;
nextUpdate = lastUpdate.AddMilliseconds(ExpTimeMSec);
await RefreshDisplay();
}
if (isLoading)
{
uiTimer?.Dispose();
uiTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(RefreshInterval));
RunTimer();
}
else
{
uiTimer = null;
}
}
#endregion Protected Methods
#region Private Fields
private PeriodicTimer? uiTimer = null;
#endregion Private Fields
#region Private Properties
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;
#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 (uiTimer != null && await uiTimer.WaitForNextTickAsync())
{
if (isLoading)
{
DateTime adesso = DateTime.Now;
if (nextUpdate <= adesso.AddMilliseconds(slowWindowMSec))
{
nextUpdate = adesso.AddMilliseconds(RefreshInterval*2);
}
// calcolo delta ms...
var numMs = adesso.Subtract(lastUpdate).TotalMilliseconds;
var denMs = nextUpdate.Subtract(lastUpdate).TotalMilliseconds;
denMs = denMs > 0 ? denMs : 1;
// aggiorno display...
actVal = startVal + (NextVal - startVal) * (numMs / denMs);
await RefreshDisplay();
}
}
}
#endregion Private Methods
}
}
+4
View File
@@ -22,5 +22,9 @@
{
"outputFile": "CalWeekColumn.razor.css",
"inputFile": "CalWeekColumn.razor.less"
},
{
"outputFile": "LoadingData.razor.css",
"inputFile": "LoadingData.razor.less"
}
]
File diff suppressed because one or more lines are too long
+5
View File
@@ -114,6 +114,11 @@
#region Public Methods
public Periodo Clone()
{
return new Periodo(this.Inizio, this.Fine);
}
public override bool Equals(object? obj)
{
if (obj == null)
+189
View File
@@ -0,0 +1,189 @@
// **********************************
// Densen Informatica 中讯科技
// 作者:Alex Chow
// e-mail:zhouchuanglin@gmail.com
// **********************************
using System.Text.Json.Serialization;
namespace ZXingBlazor.Components;
/// <summary>
/// ZXing 选项类
/// </summary>
/// <remarks>https://zxing.github.io/zxing/apidocs/com/google/zxing/DecodeHintType.htm</remarks>
public class ZXingOptions
{
/// <summary>
/// 只解码 Pdf417 格式 / decode only Pdf417 format
/// </summary>
public bool Pdf417 { get; set; }
/// <summary>
/// 单次|连续解码,默认单次 / Decode Once or Decode Continuously, default is Once
/// </summary>
public bool Decodeonce { get; set; } = true;
/// <summary>
/// Time Between Decoding Attempts
/// </summary>
public int TimeBetweenDecodingAttempts { get; set; } = 10;
/// <summary>
/// 解码所有编码形式,性能较差, 开启后可用 options.formats 指定编码形式.默认为 false | Decodde All Formats, performance is poor, you can set options.formats to customize specify the encoding formats. The default is false
/// </summary>
public bool DecodeAllFormats { get; set; }
/// <summary>
/// 已知图像是几种可能的格式之一。
/// </summary>
public List<BarcodeFormat> formats { get; set; } = new List<BarcodeFormat>() {
BarcodeFormat.AZTEC ,
BarcodeFormat.CODABAR,
BarcodeFormat.CODE_39,
BarcodeFormat.CODE_93,
BarcodeFormat.CODE_128,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.EAN_8,
BarcodeFormat.EAN_13,
BarcodeFormat.ITF,
BarcodeFormat.MAXICODE,
BarcodeFormat.PDF_417,
BarcodeFormat.QR_CODE,
BarcodeFormat.RSS_14,
BarcodeFormat.RSS_EXPANDED,
BarcodeFormat.UPC_A,
BarcodeFormat.UPC_E,
BarcodeFormat.UPC_EAN_EXTENSION,
};
public bool Debug { get; set; }
///// <summary>
///// 如果为 true,尝试解码为倒置图像。所有配置的解码器都被简单地用倒置图像第二次调用
///// </summary>
//[JsonPropertyName("ALSO_INVERTED")]
//public bool ALSO_INVERTED { get; set; }
/// <summary>
/// EAN 或 UPC 条形码允许的扩展长度, 默认为 2.
/// </summary>
[JsonPropertyName("ALLOWED_EAN_EXTENSIONS")]
public int[]? ALLOWED_EAN_EXTENSIONS { get; set; } //= new int[] { 2 };
/// <summary>
/// 允许的编码数据长度——拒绝任何其他长度
/// </summary>
[JsonPropertyName("ALLOWED_LENGTHS")]
public int[]? ALLOWED_LENGTHS { get; set; }
/// <summary>
/// 假设 Code 39 代码使用校验位。
/// </summary>
[JsonPropertyName("ASSUME_CODE_39_CHECK_DIGIT")]
public bool? ASSUME_CODE_39_CHECK_DIGIT { get; set; }
/// <summary>
/// 假设条形码正在作为 GS1 条形码进行处理,并根据需要修改行为
/// </summary>
[JsonPropertyName("ASSUME_GS1")]
public bool? ASSUME_GS1 { get; set; }
/// <summary>
/// 指定解码时使用的字符编码(如果适用)
/// </summary>
[JsonPropertyName("CHARACTER_SET")]
public string? CHARACTER_SET { get; set; }
///// <summary>
///// ResultPoint 当发现可能的情况时,需要通过回调通知调用者, 映射到一个ResultPointCallback
///// </summary>
//public object NEED_RESULT_POINT_CALLBACK { get; set; }
/// <summary>
/// 未指定的、特定于应用程序的提示。
/// </summary>
[JsonPropertyName("OTHER")]
public object? OTHER { get; set; }
/// <summary>
/// 图像是条形码的纯单色图像。
/// </summary>
[JsonPropertyName("PURE_BARCODE")]
public bool? PURE_BARCODE { get; set; }
/// <summary>
/// 如果为 true,则返回 Codabar 条形码中的开始和结束数字,而不是剥离它们
/// <remark>如果为 true,则返回 Codabar 条形码中的开始和结束数字,而不是剥离它们。它们是字母,而其余的是数字。默认情况下,它们会被剥离,但这会导致它们不会被剥离</remark>
/// </summary>
[JsonPropertyName("RETURN_CODABAR_START_END")]
public bool? RETURN_CODABAR_START_END { get; set; }
/// <summary>
/// 花更多的时间尝试寻找条形码;优化准确性,而不是速度
/// </summary>
[JsonPropertyName("TRY_HARDER")]
public bool? TRY_HARDER { get; set; }
}
/**
* Enumerates barcode formats known to this package. Please keep alphabetized.
*
* @author Sean Owen
*/
public enum BarcodeFormat
{
/** Aztec 2D barcode format. */
AZTEC,
/** CODABAR 1D format. */
CODABAR,
/** Code 39 1D format. */
CODE_39,
/** Code 93 1D format. */
CODE_93,
/** Code 128 1D format. */
CODE_128,
/** Data Matrix 2D barcode format. */
DATA_MATRIX,
/** EAN-8 1D format. */
EAN_8,
/** EAN-13 1D format. */
EAN_13,
/** ITF (Interleaved Two of Five) 1D format. */
ITF,
/** MaxiCode 2D barcode format. */
MAXICODE,
/** PDF417 format. */
PDF_417,
/** QR Code 2D barcode format. */
QR_CODE,
/** RSS 14 */
RSS_14,
/** RSS EXPANDED */
RSS_EXPANDED,
/** UPC-A 1D format. */
UPC_A,
/** UPC-E 1D format. */
UPC_E,
/** UPC/EAN extension format. Not a stand-alone format. */
UPC_EAN_EXTENSION
}