using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Xml; using EFCDesk.Classes; using System.Windows.Media.Media3D; namespace EFCDesk.Forms { public partial class FormAvanceAPI : Form { private readonly (string Label, float Value, Color Color)[] _data; private int? _hoveredIndex = null; static float totalPedimentos = 0; static float totalPendientes = 0; static float totalProcesando = 0; static float totalProcesados = 0; public FormAvanceAPI() { InitializeComponent(); ConsultarDatosAPI(); _data = new[] { ("Pendientes", totalPendientes, Color.FromArgb(46, 134, 222)), ("Procesados", totalProcesados, Color.FromArgb(231, 76, 60)), ("Procesando", totalProcesando, Color.FromArgb(39, 174, 96)) }; this.Text = "Gráfico Interactivo"; this.Size = new Size(800, 600); this.DoubleBuffered = true; this.Paint += OnPaint; this.MouseMove += OnMouseMove; } private void ConsultarDatosAPI() { try { var config = ConfiguracionJSON.LoadFromJson(); string cryptUser = General.CodificarBase64(config.idUsuarioExp.ToString()); dynamic root = config.Consulta(config.DominioExp + "/api/avance/" + cryptUser); if (root is XmlElement) { XmlNodeList nodes = root.SelectNodes("/xml/Resultado"); if (root.InnerText != "" && root.InnerText != "Error") { foreach (XmlNode node in nodes) { totalPedimentos = float.Parse(node["totalPedimentos"].InnerText); totalPendientes = float.Parse(node["totalPendientes"].InnerText); totalProcesando = float.Parse(node["totalProcesando"].InnerText); totalProcesados = float.Parse(node["totalProcesados"].InnerText); } } } } catch (Exception ex) { string errores = ""; string sNombreClase = System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType?.Name; string currentMethod = System.Reflection.MethodBase.GetCurrentMethod().Name; //MyClass.LogErrores(ex, sNombreClase, currentMethod); } } private void OnMouseMove(object sender, MouseEventArgs e) { var rect = new Rectangle(50, 50, 400, 400); if (!rect.Contains(e.Location)) { if (_hoveredIndex.HasValue) { _hoveredIndex = null; this.Invalidate(); } return; } float total = _data.Sum(item => item.Value); float startAngle = 0f; for (int i = 0; i < _data.Length; i++) { float sweepAngle = 360f * (_data[i].Value / total); using (var path = new GraphicsPath()) { path.AddPie(rect, startAngle, sweepAngle); if (path.IsVisible(e.Location)) { if (_hoveredIndex != i) { _hoveredIndex = i; this.Invalidate(); } return; } } startAngle += sweepAngle; } if (_hoveredIndex.HasValue) { _hoveredIndex = null; this.Invalidate(); } } private void OnPaint(object sender, PaintEventArgs e) { var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; var rect = new Rectangle(50, 50, 400, 400); float total = _data.Sum(item => item.Value); float startAngle = 0f; // Dibujar el gráfico de pastel for (int i = 0; i < _data.Length; i++) { float sweepAngle = 360f * (_data[i].Value / total); var color = _hoveredIndex == i ? ControlPaint.Light(_data[i].Color, 0.3f) : _data[i].Color; using (var brush = new SolidBrush(color)) { g.FillPie(brush, rect, startAngle, sweepAngle); g.DrawPie(Pens.Black, rect, startAngle, sweepAngle); } startAngle += sweepAngle; } // Dibujar leyenda mejorada DrawLegend(g); // Mostrar tooltip si hay elemento hover if (_hoveredIndex.HasValue) { var item = _data[_hoveredIndex.Value]; var text = $"{item.Label}\n{item.Value}% ({item.Value / total:P0})"; using (var font = new Font("Arial", 12, FontStyle.Bold)) using (var brush = new SolidBrush(Color.FromArgb(220, Color.Black))) { var size = g.MeasureString(text, font); var tooltipRect = new Rectangle( rect.Right + 20, rect.Top + (_hoveredIndex.Value * 40), (int)size.Width + 20, (int)size.Height + 10); g.FillRectangle(brush, tooltipRect); g.DrawRectangle(Pens.Gray, tooltipRect); g.DrawString(text, font, Brushes.White, tooltipRect.X + 10, tooltipRect.Y + 5); } } } private void DrawLegend(Graphics g) { int x = 500; int y = 100; const int boxSize = 20; const int spacing = 30; using (var font = new Font("Arial", 12)) using (var boldFont = new Font("Arial", 12, FontStyle.Bold)) { for (int i = 0; i < _data.Length; i++) { var item = _data[i]; var currentFont = _hoveredIndex == i ? boldFont : font; // Cuadro de color using (var brush = new SolidBrush(item.Color)) { g.FillRectangle(brush, x, y, boxSize, boxSize); g.DrawRectangle(Pens.Black, x, y, boxSize, boxSize); } // Texto g.DrawString($"{item.Label}: {item.Value}%", currentFont, Brushes.Black, x + boxSize + 10, y); y += spacing; } } } private void button1_Click(object sender, EventArgs e) { } } }