using DnsClient.Protocol; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MP.Data.DbModels; using MP.Data.Services; using MP.Stats.Data; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MP.Stats.Pages { public partial class TrendAnalysis { #region Public Methods public void Dispose() { MServ.EA_SearchUpdated -= OnSeachUpdated; PlotRecords.Clear(); SearchRecords.Clear(); } public async void OnSeachUpdated() { await InvokeAsync(() => { Task task = UpdateData(); StateHasChanged(); }); } #endregion Public Methods #region Protected Fields protected string CodFluxSel = "*"; protected string fileName = "TrendAnalysis.csv"; protected List ListMacchine = new List(); protected int SelCount = 0; protected int TotalCount = 0; #endregion Protected Fields #region Protected Enums protected enum ResolutionLevel { Low, Med, High, Custom } #endregion Protected Enums #region Protected Properties protected List CodFluxList { get; set; } = new List() { "Energy", "Parameter" }; [Inject] protected IJSRuntime JSRuntime { get; set; } /// /// Verifica validità selezione macchine /// protected bool MaccSelValid { get => currFilter.MaccSelValid; } /// /// Numero max di punti da mostrare /// protected int MaxPoints { get => _maxPoints; set { if ((_maxPoints != value)) { _maxPoints = value; FiltData(); } } } [Inject] protected Data.MessageService MServ { get; set; } [Inject] protected NavigationManager NavManager { get; set; } protected ResolutionLevel ReqRes { get => _reqRes; set { if (_reqRes != value) { _reqRes = value; if (value < ResolutionLevel.Custom) { int numSel = currFilter.ListIdxMaccSel.Count; // verifico selcount valido... che sia almeno MaxDisp/ if (SelCount == 0) { SelCount = TotalCount * numSel / NumMacc; } switch (value) { case ResolutionLevel.Low: MaxPoints = NumPoint(SelCount, numSel, 32, 32); break; case ResolutionLevel.Med: MaxPoints = NumPoint(SelCount, numSel, 8, 128); break; case ResolutionLevel.High: MaxPoints = NumPoint(SelCount, numSel, 1, 512); break; default: break; } } } } } [Inject] protected MpStatsService StatService { get; set; } [Inject] protected TranslateSrv TradService { get; set; } #endregion Protected Properties #region Protected Methods protected async Task DoFilter(SelectData newFilter) { SearchRecords = null; currFilter = newFilter; await ReloadData(); } protected override async Task OnInitializedAsync() { isLoading = true; MServ.ShowSearch = false; MServ.PageName = "Trend Analisys"; MServ.PageIcon = "fa-solid fa-arrow-trend-up"; MServ.EA_SearchUpdated += OnSeachUpdated; await LoadConfData(); await ReloadData(); isLoading = false; } protected async Task ResetFilter(SelectData newFilter) { SearchRecords = null; PlotRecords = null; currFilter = SelectData.Init(5, 7); await ReloadData(); } /// /// Salvataggio codflux /// /// /// protected async Task SetCodFlux(string newCodFlux) { CodFluxSel = newCodFlux; await ReloadData(); } /// /// Traduzione lemma richeisto (lingua default="IT") /// /// /// protected string Traduci(string Lemma) { return TradService.Traduci(Lemma); } protected async Task UpdateData() { await ReloadData(); } #endregion Protected Methods #region Private Fields private int _maxPoints = 256; private ResolutionLevel _reqRes = ResolutionLevel.Med; private List ConfigList; private int MaxDisplay = 10; private int NumMacc = 0; private List PlotRecords = new List(); /// /// Dizionario liste valori da mostrare /// private Dictionary> SearchRecords = new Dictionary>(); #endregion Private Fields #region Private Properties private SelectData currFilter { get { return MServ.EnergyTrend_Filter; } set { MServ.EnergyTrend_Filter = value; } } private bool isLoading { get; set; } = false; #endregion Private Properties #region Private Methods private string confVal(string chiave) { string answ = ""; if (ConfigList != null && ConfigList.Count > 0) { var searchRec = ConfigList.First(x => x.Chiave == chiave); if (searchRec != null) { answ = searchRec.Valore; } } return answ; } /// /// Effettua filtro/downsample dei dati /// private void FiltData() { // in primis suddivido in un dizionario x ogni macchina... if (PlotRecords != null) { PlotRecords.Clear(); // = new List(); } else { PlotRecords = new List(); } // per ogni valore recupero timeserie downsampled fino al num max di quelle ottenibili... int numAdd = 0; SelCount = 0; var listSel = currFilter.ListIdxMaccSel; foreach (var item in SearchRecords) { // verifico se sia tra le macchine selezionate... if (listSel.Contains(item.Key)) { numAdd++; SelCount += item.Value.Count; // ora effettuo deduplica valori per tenere un subset minore ed evitare problemi visualizzazione... PlotRecords.AddRange(TimeSeriesUtils.DownsampleFluxModels(item.Value, MaxPoints)); // verifico comunque superamento limite amcchine if (numAdd >= MaxDisplay) { return; } } } } private async Task LoadConfData() { ConfigList = await StatService.ConfigGetAll(); int.TryParse(confVal("STATS_TrendMaxSelect"), out MaxDisplay); CodFluxList = await StatService.FluxTypeList(); ListMacchine = await StatService.MachineList(true); } /// /// Calcola num punti dato /// /// Numero totale valori /// Numero partizioni (oggetti da disegnare insieme) /// Fattore di scala richiesto /// Fattore di scala (=valore minimo garantito) /// private int NumPoint(int selCount, int numSel, int factor, double scale) { int calcVal = (int)Math.Round((double)(selCount * scale) / numSel / factor / (double)scale); return calcVal > scale ? calcVal : (int)scale; } private async Task ReloadData() { isLoading = true; NumMacc = ListMacchine.Count; // ciclo caricando info x ogni macchina selezionata... if (SearchRecords != null) { SearchRecords.Clear(); } else { SearchRecords = new Dictionary>(); } if (currFilter.ListIdxMaccSel != null && currFilter.ListIdxMaccSel.Count > 0) { var lastIdx = currFilter.IdxMacchina; foreach (var idxMacc in currFilter.ListIdxMaccSel) { currFilter.IdxMacchina = idxMacc; List tempRec = await StatService.FluxLogRawData(currFilter, CodFluxSel, MServ.SearchVal); SearchRecords.Add(idxMacc, tempRec); tempRec = null; } currFilter.IdxMacchina = lastIdx; } TotalCount = SearchRecords.Count; FiltData(); isLoading = false; } /// /// Elimina da dict macchina indicata /// /// private async Task RemoveMachine(string idxMacc) { // in primis se contiene spazio --> prendo prima aprte che è idxMacc... if (idxMacc.Contains(" ")) { var sVals = idxMacc.Split(' '); idxMacc = sVals[0]; } if (SearchRecords.ContainsKey(idxMacc)) { currFilter.ListIdxMaccSel.Remove(idxMacc); SearchRecords.Remove(idxMacc); GC.Collect(); await ReloadData(); } } #endregion Private Methods } }