using SteamWare; using System; using System.Web.UI.DataVisualization.Charting; using System.Web.UI.WebControls; namespace MoonPro.WebUserControls { public partial class mod_sequencerStati : System.Web.UI.UserControl { /// /// dati x grafico sequencer /// public objSequencer datiSequencer { get { return _grafico; } set { _grafico = value; } } public resoconti _resoconti; protected objSequencer _grafico; protected double _min2plot = 0.0; protected string _titolo = "Sequencer"; protected int _larghezza = 100; protected int _timeSplits = 10; /// /// totale in minuti da plottare /// protected double totale = 1; /// /// numero dei segmenti del grafico /// public int numSplit { get; set; } protected double _minVerde = 0.5; protected double _minRosso = 0.5; protected double _minSpento = 0.5; /// /// altezza max grafico /// public int graphHeight { get; set; } /// /// identificativo /// public string identificativo { get; set; } protected void Page_Load(object sender, EventArgs e) { doUpdate(); } /// /// disegna la tabella /// protected void plottaGrafico() { // a seconda del numero di eventi da plottare decido la procedura... DataLayer_generic.serieDatiDataTable dati = _grafico.serieDati; try { // è la somma dei minuti totali dall'inizio alla fine... totale = ((TimeSpan)_grafico.intervallo.fine.Subtract(_grafico.intervallo.inizio)).TotalMinutes; } catch { } int numCelle = dati.Rows.Count; if (numCelle <= numSplit) // se ho eventi <= _num split.... { plottaDettaglio(dati); } else // altrimenti raggruppo! { plottaGruppi(dati); } } /// /// popola il sequencer degli stati riportando tutti i singoli valori /// /// /// private void plottaDettaglio(DataLayer_generic.serieDatiDataTable dati) { // nuovo plotting Chart1.Width = larghezza; Chart1.AntiAliasing = AntiAliasingStyles.All; Chart1.Height = graphHeight; // definizione intervallo asse Y (che qui è anche asse X...) Chart1.ChartAreas["Sequencer"].AxisY.Minimum = datiSequencer.intervallo.inizio.ToOADate(); Chart1.ChartAreas["Sequencer"].AxisY.Maximum = datiSequencer.intervallo.fine.ToOADate(); //Chart1.ChartAreas["Sequencer"].AxisY.IntervalType = DateTimeIntervalType.Auto; Chart1.ChartAreas["Sequencer"].AxisY.LabelAutoFitStyle = LabelAutoFitStyles.None; LabelStyle lbst = new LabelStyle(); lbst.Format = "dd/MM HH:mm"; lbst.Font = new System.Drawing.Font("Arial", 7.5f); Chart1.ChartAreas["Sequencer"].AxisY.LabelStyle = lbst; // definizioni x chart area sequencer (tipo valori e nascondere asse) Chart1.Series["SeqV"].XValueType = ChartValueType.Int32; Chart1.Series["SeqV"].YValueType = ChartValueType.DateTime; Chart1.ChartAreas["Sequencer"].AxisX.Enabled = AxisEnabled.False; // per impostare grafici allineati Chart1.Series["SeqV"]["DrawSideBySide"] = "false"; // colori e stile 3D Chart1.Series["SeqV"].Color = System.Drawing.Color.LimeGreen; Chart1.Series["SeqV"]["DrawingStyle"] = "Cylinder"; Chart1.Series["SeqR"].Color = System.Drawing.Color.OrangeRed; Chart1.Series["SeqR"]["DrawingStyle"] = "Cylinder"; Chart1.Series["SeqG"].Color = System.Drawing.Color.Yellow; Chart1.Series["SeqG"]["DrawingStyle"] = "Cylinder"; Chart1.Series["SeqB"].Color = System.Drawing.Color.Blue; Chart1.Series["SeqB"]["DrawingStyle"] = "Cylinder"; Chart1.Series["SeqS"].Color = System.Drawing.Color.Gray; Chart1.Series["SeqS"]["DrawingStyle"] = "Cylinder"; // imposto tipo grafico Chart1.Series["SeqV"].ChartType = SeriesChartType.RangeBar; Chart1.Series["SeqR"].ChartType = SeriesChartType.RangeBar; Chart1.Series["SeqG"].ChartType = SeriesChartType.RangeBar; Chart1.Series["SeqB"].ChartType = SeriesChartType.RangeBar; Chart1.Series["SeqS"].ChartType = SeriesChartType.RangeBar; // impostazione larghezza relativa grafico Chart1.Series["SeqV"]["PointWidth"] = "2.0"; Chart1.Series["SeqR"]["PointWidth"] = "2.0"; Chart1.Series["SeqG"]["PointWidth"] = "2.0"; Chart1.Series["SeqB"]["PointWidth"] = "2.0"; Chart1.Series["SeqS"]["PointWidth"] = "2.0"; int tipo = 1; DateTime inizio, fine; double valore = 0; //DataLayer_generic.serieDatiRow rigaPrec = (DataLayer_generic.serieDatiRow)datiSequencer.serieDati[0]; //foreach (DataLayer_generic.serieDatiRow riga in datiSequencer.serieDati) DataLayer_generic.serieDatiRow rigaPrec = (DataLayer_generic.serieDatiRow)dati[0]; string codV = memLayer.ML.confReadString("codV"); string codG = memLayer.ML.confReadString("codG"); string codR = memLayer.ML.confReadString("codR"); string codB = memLayer.ML.confReadString("codB"); string codS = memLayer.ML.confReadString("codS"); foreach (DataLayer_generic.serieDatiRow riga in dati) { if (riga.valore > 0) { if ((rigaPrec.colore == riga.colore) && (rigaPrec.label == riga.label)) { valore += riga.valore; } else if (valore > 0) { inizio = rigaPrec.timeData; fine = rigaPrec.timeData.AddMinutes(valore); accodaDati(ref tipo, ref inizio, ref fine, rigaPrec, codV, codG, codR, codB, codS); // reset valore e colore... valore = riga.valore; rigaPrec = riga; } else { valore = riga.valore; rigaPrec = riga; } } } // aggiungo la riga precedente eventualmente non finita... inizio = rigaPrec.timeData; fine = rigaPrec.timeData.AddMinutes(rigaPrec.valore); accodaDati(ref tipo, ref inizio, ref fine, rigaPrec, codV, codG, codR, codB, codS); // aggiungo ultimo dato che è stato escluso rigaPrec = (DataLayer_generic.serieDatiRow)dati[dati.Rows.Count - 1]; inizio = rigaPrec.timeData; fine = rigaPrec.timeData.AddMinutes(rigaPrec.valore); accodaDati(ref tipo, ref inizio, ref fine, rigaPrec, codV, codG, codR, codB, codS); } /// /// accoda i dati alla serie corretta /// /// /// /// /// /// /// /// /// /// private void accodaDati(ref int tipo, ref DateTime inizio, ref DateTime fine, DataLayer_generic.serieDatiRow rigaPrec, string codV, string codG, string codR, string codB, string codS) { switch (rigaPrec.colore) { case "sVe": tipo = 1; Chart1.Series["SeqV"].Points.AddXY(tipo, inizio, fine); // aggiungo tooltip Chart1.Series["SeqV"].Points[Chart1.Series["SeqV"].Points.Count - 1].ToolTip = string.Format("{2} | {0:dd/MM HH:mm:ss} -->{1:dd/MM HH:mm:ss}", inizio, fine, codV); Chart1.Series["SeqV"].Points[Chart1.Series["SeqV"].Points.Count - 1].PostBackValue = inizio.ToString(); break; case "sGi": tipo = 1; Chart1.Series["SeqG"].Points.AddXY(tipo, inizio, fine); // aggiungo tooltip Chart1.Series["SeqG"].Points[Chart1.Series["SeqG"].Points.Count - 1].ToolTip = string.Format("{2} | {0:dd/MM HH:mm:ss} -->{1:dd/MM HH:mm:ss}", inizio, fine, codG); Chart1.Series["SeqG"].Points[Chart1.Series["SeqG"].Points.Count - 1].PostBackValue = inizio.ToString(); break; case "sRo": tipo = 1; Chart1.Series["SeqR"].Points.AddXY(tipo, inizio, fine); // aggiungo tooltip Chart1.Series["SeqR"].Points[Chart1.Series["SeqR"].Points.Count - 1].ToolTip = string.Format("{2} | {0:dd/MM HH:mm:ss} -->{1:dd/MM HH:mm:ss}", inizio, fine, codR); Chart1.Series["SeqR"].Points[Chart1.Series["SeqR"].Points.Count - 1].PostBackValue = inizio.ToString(); break; case "sBl": tipo = 1; Chart1.Series["SeqB"].Points.AddXY(tipo, inizio, fine); // aggiungo tooltip Chart1.Series["SeqB"].Points[Chart1.Series["SeqB"].Points.Count - 1].ToolTip = string.Format("{2} | {0:dd/MM HH:mm:ss} -->{1:dd/MM HH:mm:ss}", inizio, fine, codR); Chart1.Series["SeqB"].Points[Chart1.Series["SeqB"].Points.Count - 1].PostBackValue = inizio.ToString(); break; case "sGr": tipo = 1; Chart1.Series["SeqS"].Points.AddXY(tipo, inizio, fine); // aggiungo tooltip Chart1.Series["SeqS"].Points[Chart1.Series["SeqS"].Points.Count - 1].ToolTip = string.Format("{2} | {0:dd/MM HH:mm:ss} -->{1:dd/MM HH:mm:ss}", inizio, fine, codS); Chart1.Series["SeqS"].Points[Chart1.Series["SeqS"].Points.Count - 1].PostBackValue = inizio.ToString(); break; default: break; } } /// /// intercetta richiesta di zoom e zoomma sul giorno in esame... /// /// /// void lnkb_Click(object sender, EventArgs e) { LinkButton lnk = (LinkButton)sender; // calcolo il giorno... Session["dataZoom"] = lnk.CommandArgument.ToString();//Convert.ToDateTime if (eh_richiestaZoom != null) { eh_richiestaZoom(this, new EventArgs()); } } /// /// popola il sequencer degli stati raggruppando perché troppi valori /// /// /// private void plottaGruppi(DataLayer_generic.serieDatiDataTable dati) { DataLayer_generic.serieDatiDataTable datiGrouped = new DataLayer_generic.serieDatiDataTable(); TableRow r = new TableRow(); double valMin = totale / numSplit; double valRigaCum = 0.0; double valR = 0.0; double valG = 0.0; double valV = 0.0; double valB = 0.0; double valS = 0.0; DateTime _t_0 = new DateTime(9999, 1, 1); string _mostCodArticolo = ""; int _maxVal = 0; string colore; foreach (DataLayer_generic.serieDatiRow riga in dati) { // salvo prima data... if (riga.timeData < _t_0) { _t_0 = riga.timeData; } if (riga.valore > _maxVal) { _maxVal = Convert.ToInt32(riga.valore); _mostCodArticolo = riga.label; } valRigaCum = valRigaCum + riga.valore; // accumulo valori... switch (riga.colore) { case "sVe": valV = valV + riga.valore; break; case "sGi": valG = valG + riga.valore; break; case "sRo": valR = valR + riga.valore; break; case "sBl": valB = valB + riga.valore; break; case "sGr": valS = valS + riga.valore; break; } // se è maggiore plotto... if (valRigaCum >= valMin) { // determino il colore... if (valV / valRigaCum >= minVerde) { colore = "sVe"; valV = 0.0; } else if (valR / valRigaCum >= minRosso) { colore = "sRo"; valR = 0.0; } else if (valS / valRigaCum >= minSpento) { colore = "sGr"; valS = 0.0; } else if (valB / valRigaCum >= minSpento) { colore = "sBl"; valB = 0.0; } else { colore = "sGi"; valG = 0.0; } // salvo riga dati datiGrouped.AddserieDatiRow(valRigaCum, colore, _mostCodArticolo, _t_0); // reset dei contatori... valRigaCum = 0.0; _t_0 = new DateTime(9999, 1, 1); _mostCodArticolo = ""; _maxVal = 0; } } plottaDettaglio(datiGrouped); } /// /// restituisce true se ci sono dati... /// /// protected bool datiPresenti() { bool answ = false; try { int numCelle = datiSequencer.serieDati.Rows.Count; answ = (numCelle > 0); } catch { } return answ; } /// /// valore minimo da plottare /// public double min2plot { get { return _min2plot; } set { _min2plot = value; } } /// /// titolo del grafico /// public string titolo { get { return _titolo; } set { _titolo = value; } } /// /// larghezza totale del grafico (forzo a zero come minimo...) /// public int larghezza { get { return _larghezza; } set { if (value > 0) { _larghezza = value; } else { _larghezza = 0; } } } /// /// % minuma nel periodo per dire che sia verde /// public double minVerde { get { return _minVerde; } set { _minVerde = value; } } /// /// % minuma nel periodo per dire che sia rosso /// public double minRosso { get { return _minRosso; } set { _minRosso = value; } } /// /// % minuma nel periodo per dire che sia spento /// public double minSpento { get { return _minSpento; } set { _minSpento = value; } } /// /// aggiorna il controllo /// public void doUpdate() { if (datiPresenti()) { plottaGrafico(); } else { // non plotto } } /// /// evento di richeista zoom sui dati /// public event EventHandler eh_richiestaZoom; /// /// evento click su sequencer: zoom 2X /// /// /// protected void Chart1_Click(object sender, ImageMapEventArgs e) { // alzo evento if (eh_richiestaZoom != null) { ImageMapEventArgs evIM = (ImageMapEventArgs)e; // salvo in sessione memLayer.ML.setSessionVal("zoomCenter", e.PostBackValue); eh_richiestaZoom(this, new EventArgs()); } } } }