360 lines
10 KiB
C#
360 lines
10 KiB
C#
using SteamWare;
|
|
using System;
|
|
using System.Web.UI;
|
|
using System.Web.UI.DataVisualization.Charting;
|
|
using System.Web.UI.WebControls;
|
|
|
|
namespace MP_SITE.WebUserControls
|
|
{
|
|
public partial class mod_sequencerTempiCiclo : System.Web.UI.UserControl
|
|
{
|
|
#region proprietà
|
|
|
|
protected int _timeSplits = 10;
|
|
protected double _minVal = 0.5;
|
|
/// <summary>
|
|
/// totale in minuti da plottare
|
|
/// </summary>
|
|
protected double totale = 1;
|
|
/// <summary>
|
|
/// valore minimo da plottare
|
|
/// </summary>
|
|
public double min2plot { get; set; }
|
|
/// <summary>
|
|
/// titolo del grafico
|
|
/// </summary>
|
|
public string titolo { get; set; }
|
|
/// <summary>
|
|
/// larghezza totale del grafico
|
|
/// </summary>
|
|
public int larghezza { get; set; }
|
|
/// <summary>
|
|
/// numero dei segmenti del grafico
|
|
/// </summary>
|
|
public int numSplit { get; set; }
|
|
/// <summary>
|
|
/// % minuma nel periodo per dire che sia verde
|
|
/// </summary>
|
|
public double minVal { get; set; }
|
|
/// <summary>
|
|
/// definisce se plottare "reversed" (ovvero i valori "minimi" sono con barre + alte dei massimi, come se vosse apssare da tempo a velocità...)
|
|
/// </summary>
|
|
public bool plotReversed { get; set; }
|
|
/// <summary>
|
|
/// altezza max grafico
|
|
/// </summary>
|
|
public int graphHeight { get; set; }
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// caricamento pagina
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
protected void Page_Load(object sender, EventArgs e)
|
|
{
|
|
if (!Page.IsPostBack)
|
|
{
|
|
// setup valori
|
|
min2plot = 0.0;
|
|
titolo = "TempiCiclo";
|
|
doUpdate();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// disegna la tabella
|
|
/// </summary>
|
|
protected void plottaGrafico()
|
|
{
|
|
// a seconda del numero di eventi da plottare decido la procedura...
|
|
DataLayer_generic.serieTimeValDataTable dati = _grafico.serieDati;
|
|
try
|
|
{
|
|
// è la somma dei minuti totali dall'inizio alla fine...
|
|
totale = _grafico.intervallo.fine.Subtract(_grafico.intervallo.inizio).TotalMinutes;
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
plottaDettaglio(dati);
|
|
}
|
|
|
|
/// <summary>
|
|
/// popola il sequencer degli stati riportando tutti i singoli valori
|
|
/// </summary>
|
|
/// <param name="dati"></param>
|
|
/// <returns></returns>
|
|
private void plottaDettaglio(DataLayer_generic.serieTimeValDataTable dati)
|
|
{
|
|
// definizioni x chart
|
|
Chart1.Width = larghezza;
|
|
Chart1.AntiAliasing = System.Web.UI.DataVisualization.Charting.AntiAliasingStyles.All;
|
|
Chart1.Height = graphHeight;
|
|
// definizione intervallo asse Y (che qui è anche asse X...
|
|
Chart1.ChartAreas["TempiCiclo"].AxisX.Minimum = _grafico.intervallo.inizio.ToOADate();
|
|
Chart1.ChartAreas["TempiCiclo"].AxisX.Maximum = _grafico.intervallo.fine.ToOADate();
|
|
LabelStyle lbst = new LabelStyle();
|
|
lbst.Format = "HH:mm";
|
|
Chart1.ChartAreas["TempiCiclo"].AxisX.LabelStyle = lbst;
|
|
|
|
// definizioni x chart area tempi ciclo
|
|
Chart1.ChartAreas["TempiCiclo"].AxisY.Enabled = System.Web.UI.DataVisualization.Charting.AxisEnabled.False;
|
|
Chart1.ChartAreas["TempiCiclo"].AxisY.IsLogarithmic = false;
|
|
Chart1.ChartAreas["TempiCiclo"].AxisY.IsReversed = true;
|
|
|
|
|
|
string tipo_A = "";
|
|
string tipo_B = "";
|
|
decimal ratioTC;
|
|
decimal deltaValori = grafico.maxVal - grafico.minVal;
|
|
foreach (DataLayer_generic.serieTimeValRow riga in _grafico.serieDati)
|
|
{
|
|
|
|
ratioTC = riga.valore;
|
|
|
|
// a seconda del tipo aggiungo all'una o all'altra serie...
|
|
if (grafico.palletChange)
|
|
{
|
|
// controllo per inizializzare i 2 tipi...
|
|
if (tipo_A == "")
|
|
{
|
|
tipo_A = riga.tipo;
|
|
if (Chart1.Series.Count < 1)
|
|
{
|
|
Chart1.Series.Add(tipo_A);
|
|
}
|
|
}
|
|
else if (tipo_B == "" && riga.tipo != tipo_A)
|
|
{
|
|
tipo_B = riga.tipo;
|
|
if (Chart1.Series.Count < 2)
|
|
{
|
|
// provo ad aggiungere nuova...
|
|
try
|
|
{
|
|
Chart1.Series.Add(tipo_B);
|
|
}
|
|
// ... sennò aggiungo vecchia serie
|
|
catch
|
|
{
|
|
Chart1.Series.Add(tipo_A);
|
|
}
|
|
}
|
|
}
|
|
// definisco colori
|
|
if (riga.tipo == tipo_A)
|
|
{
|
|
try
|
|
{
|
|
Chart1.Series[tipo_A].Points.AddXY(riga.DataEnd, ratioTC);
|
|
}
|
|
catch
|
|
{
|
|
Chart1.Series[0].Points.AddXY(riga.DataEnd, ratioTC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
Chart1.Series[tipo_B].Points.AddXY(riga.DataEnd, ratioTC);
|
|
}
|
|
catch
|
|
{
|
|
Chart1.Series[1].Points.AddXY(riga.DataEnd, ratioTC);
|
|
}
|
|
}
|
|
}
|
|
else // unica serie
|
|
{
|
|
if (tipo_A == "")
|
|
{
|
|
tipo_A = riga.tipo;
|
|
if (Chart1.Series.Count < 1)
|
|
{
|
|
Chart1.Series.Add(tipo_A);
|
|
}
|
|
}
|
|
Chart1.Series[tipo_A].Points.AddXY(riga.DataEnd, ratioTC);
|
|
}
|
|
}
|
|
|
|
if (Chart1.Series.Count > 0)
|
|
{
|
|
// disegno plot nuovo...
|
|
try
|
|
{
|
|
Chart1.Series[tipo_A].XValueType = ChartValueType.DateTime;
|
|
Chart1.Series[tipo_A].ChartType = SeriesChartType.FastPoint;
|
|
}
|
|
catch
|
|
{
|
|
Chart1.Series[0].XValueType = ChartValueType.DateTime;
|
|
Chart1.Series[0].ChartType = SeriesChartType.FastPoint;
|
|
}
|
|
if (Chart1.Series.Count > 1)
|
|
{
|
|
try
|
|
{
|
|
Chart1.Series[tipo_B].XValueType = ChartValueType.DateTime;
|
|
Chart1.Series[tipo_B].ChartType = SeriesChartType.FastPoint;
|
|
}
|
|
catch
|
|
{
|
|
Chart1.Series[1].XValueType = ChartValueType.DateTime;
|
|
Chart1.Series[1].ChartType = SeriesChartType.FastPoint;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// calcola il rapporto tr ail valore e le grandezze reali dato masismo, intervallo, apdding, plot regolare o reversed...
|
|
/// </summary>
|
|
/// <param name="valore"></param>
|
|
/// <param name="maxVal"></param>
|
|
/// <param name="deltaValori"></param>
|
|
/// <param name="plotReversed"></param>
|
|
/// <returns></returns>
|
|
protected decimal calcolaRatio(decimal valore, decimal maxVal, decimal deltaValori, bool plotReversed, decimal padding)
|
|
{
|
|
decimal answ = 0;
|
|
if (plotReversed)
|
|
{
|
|
answ = (padding + ((1 - 2 * padding) * ((maxVal - valore) / (deltaValori))));
|
|
}
|
|
else
|
|
{
|
|
answ = (padding + ((1 - 2 * padding) * ((valore - maxVal) / (deltaValori))));
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// intercetta richiesta di zoom e zoomma sul giorno in esame...
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void lnkb_Click(object sender, EventArgs e)
|
|
{
|
|
LinkButton lnk = (LinkButton)sender;
|
|
// calcolo il giorno...
|
|
memLayer.ML.setSessionVal("dataZoom", lnk.CommandArgument.ToString());
|
|
if (eh_richiestaZoom != null)
|
|
{
|
|
eh_richiestaZoom(this, new EventArgs());
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// popola il sequencer degli stati raggruppando perché troppi valori secondo MEDIA ARMONICA
|
|
/// </summary>
|
|
/// <param name="dati"></param>
|
|
/// <returns></returns>
|
|
private void plottaGruppiMediaArmonica(DataLayer_generic.serieTimeValDataTable dati)
|
|
{
|
|
// creo oggetto x contenere i dati "mediati"
|
|
DataLayer_generic.serieTimeValDataTable datiGrouped = new DataLayer_generic.serieTimeValDataTable();
|
|
// calcolo il val minimo da plottare (come ampiezza)
|
|
decimal ampiezzaMin = (decimal)totale / numSplit;
|
|
// setup valori iniziali
|
|
decimal valoreCurr = (decimal)0.0;
|
|
decimal valoreMedio = (decimal)1.0;
|
|
DateTime timeRaggiunto = _grafico.intervallo.inizio;
|
|
decimal ampiezzaCurr = (decimal)0.0;
|
|
decimal ampiezzaMedia = (decimal)0.0;
|
|
string label = "";
|
|
// ciclo x tutti i record
|
|
foreach (DataLayer_generic.serieTimeValRow riga in dati)
|
|
{
|
|
// calcolo nuova ampiezza
|
|
ampiezzaCurr = (decimal)riga.DataEnd.Subtract(riga.DataStart).TotalMinutes;
|
|
//...e calcolo nuovo valore medio...
|
|
valoreCurr = riga.valore;
|
|
// calcolo media armonica
|
|
valoreMedio = ((ampiezzaCurr + ampiezzaMedia) / (ampiezzaMedia / valoreMedio + ampiezzaCurr / valoreCurr));
|
|
ampiezzaMedia = ampiezzaCurr + ampiezzaMedia;
|
|
// se supero il limite aggiungo in tabella, sennò proseguo...
|
|
if (ampiezzaMedia > ampiezzaMin)
|
|
{
|
|
label = string.Format("TC: {0} min/pz", valoreMedio);
|
|
datiGrouped.AddserieTimeValRow(timeRaggiunto, riga.DataEnd, valoreMedio, label, "TC");
|
|
// resetto
|
|
timeRaggiunto = riga.DataEnd;
|
|
ampiezzaMedia = (decimal)0.0;
|
|
valoreMedio = (decimal)1.0;
|
|
}
|
|
}
|
|
_grafico.palletChange = false;
|
|
plottaDettaglio(datiGrouped);
|
|
}
|
|
/// <summary>
|
|
/// restituisce true se ci sono dati...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected bool datiPresenti()
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
int numCelle = grafico.serieDati.Rows.Count;
|
|
answ = (numCelle > 0);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// oggetto protected
|
|
/// </summary>
|
|
protected objTempiCiclo _grafico;
|
|
/// <summary>
|
|
/// elemento grafico da plottare
|
|
/// </summary>
|
|
public objTempiCiclo grafico
|
|
{
|
|
get
|
|
{
|
|
return _grafico;
|
|
}
|
|
set
|
|
{
|
|
_grafico = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// aggiorna il controllo
|
|
/// </summary>
|
|
public void doUpdate()
|
|
{
|
|
if (datiPresenti())
|
|
{
|
|
plottaGrafico();
|
|
}
|
|
else
|
|
{
|
|
// non plotto
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// evento di richeista zoom sui dati
|
|
/// </summary>
|
|
public event EventHandler eh_richiestaZoom;
|
|
/// <summary>
|
|
/// evento di click x zoom
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
protected void Chart1_Click(object sender, ImageMapEventArgs e)
|
|
{
|
|
// alzo evento
|
|
if (eh_richiestaZoom != null)
|
|
{
|
|
eh_richiestaZoom(this, new EventArgs());
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
} |