using System.Windows; using System.Windows.Controls; using System.Windows.Media; using CommunityToolkit.Mvvm.ComponentModel; using System.Windows.Shapes; using LibS7Adv; using System.Runtime.Intrinsics; namespace CtrEditor.ObjetosSim { /// /// Interaction logic for ucTrace3.xaml /// public partial class osTrace3 : osBase, IosBase { private List _series1 = new List(); private List _series2 = new List(); private List _series3 = new List(); // Otros datos y métodos relevantes para la simulación public static string NombreClase() { return "Trace3"; } private string nombre = NombreClase(); public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); } [ObservableProperty] private Brush color_Serie_1; [ObservableProperty] private Brush color_Serie_2; [ObservableProperty] private Brush color_Serie_3; [ObservableProperty] float alto; [ObservableProperty] float ancho; [ObservableProperty] bool serie1_Tipo_Bool; [ObservableProperty] string tag_Serie1; [ObservableProperty] bool serie2_Tipo_Bool; [ObservableProperty] string tag_Serie2; [ObservableProperty] bool serie3_Tipo_Bool; [ObservableProperty] string tag_Serie3; [ObservableProperty] string titulo; [ObservableProperty] string descripcion_Serie_1; [ObservableProperty] string descripcion_Serie_2; [ObservableProperty] string descripcion_Serie_3; [ObservableProperty] float min_Serie_1; [ObservableProperty] float max_Serie_1; [ObservableProperty] float min_Serie_2; [ObservableProperty] float max_Serie_2; [ObservableProperty] float min_Serie_3; [ObservableProperty] float max_Serie_3; [ObservableProperty] float y_offset_1; [ObservableProperty] float y_offset_2; [ObservableProperty] float y_offset_3; [ObservableProperty] float max_Cantidad_Elementos; public osTrace3() { Alto = 3; Ancho = 5; Titulo = "Datos"; Max_Cantidad_Elementos = 10; Color_Serie_1 = Brushes.Black; Color_Serie_2 = Brushes.Red; Color_Serie_3 = Brushes.Blue; Max_Serie_1 = 2; Max_Serie_2 = 2; Max_Serie_3 = 2; Serie1_Tipo_Bool = true; Serie2_Tipo_Bool = true; Serie3_Tipo_Bool = true; } public override void UpdatePLCPrimerCiclo() { // Escribimos el valor actual al iniciar la conexion } public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) { float v1, v2, v3; base.UpdatePLC(plc, elapsedMilliseconds); if (Serie1_Tipo_Bool) v1 = LeerBitTag(Tag_Serie1) ? 0 : 1; else v1 = LeerWordTag(Tag_Serie1); if (Serie2_Tipo_Bool) v2 = LeerBitTag(Tag_Serie2) ? 0 : 1; else v2 = LeerWordTag(Tag_Serie2); if (Serie3_Tipo_Bool) v3 = LeerBitTag(Tag_Serie3) ? 0 : 1; else v3 = LeerWordTag(Tag_Serie3); AddData(v1, v2, v3); } public override void ucLoaded() { // El UserControl ya se ha cargado y podemos obtener las coordenadas para // crear el objeto de simulacion base.ucLoaded(); } public void AddData(float series1Value, float series2Value, float series3Value) { if (_series1.Count >= Max_Cantidad_Elementos) { _series1.RemoveAt(0); _series2.RemoveAt(0); _series3.RemoveAt(0); } _series1.Add(series1Value); _series2.Add(series2Value); _series3.Add(series3Value); DrawChart(); } private void DrawChart() { if (VisualRepresentation != null) if (VisualRepresentation is ucTrace3 uc) { uc.ChartCanvas.Children.Clear(); DrawSeries(uc.ChartCanvas, _series1, Brushes.Red, Min_Serie_1, Max_Serie_1, Y_offset_1); DrawSeries(uc.ChartCanvas, _series2, Brushes.Green, Min_Serie_2, Max_Serie_2, Y_offset_2); DrawSeries(uc.ChartCanvas, _series3, Brushes.Blue, Min_Serie_3, Max_Serie_3, Y_offset_3); } } private void DrawSeries(Canvas ChartCanvas, List series, Brush color, float minY, float maxY, float yoffset) { if (series.Count < 2) return; foreach (var value in series) { if (value < minY) minY = value; if (value > maxY) maxY = value; } if (minY == maxY) return; float canvasHeight = (float)ChartCanvas.ActualHeight; float canvasWidth = (float)ChartCanvas.ActualWidth; float scaleX = canvasWidth / Max_Cantidad_Elementos; float scaleY = canvasHeight / (maxY - minY + yoffset); int startIndex = 0; float lastX = 0; float lastY = canvasHeight - (series[startIndex] - minY + yoffset) * scaleY; while (startIndex < series.Count - 1) { // Buscar el próximo cambio en la serie int endIndex = startIndex + 1; while (endIndex < series.Count && series[endIndex] == series[startIndex]) { endIndex++; } // Dibujar la línea horizontal desde startIndex hasta endIndex - 1 float x1 = lastX; float y1 = lastY; float x2 = (endIndex - 1) * scaleX; float y2 = y1; var horizontalLine = new Line { Stroke = color, StrokeThickness = 0.4, X1 = x1, Y1 = y1, X2 = x2, Y2 = y2 }; ChartCanvas.Children.Add(horizontalLine); // Dibujar la línea vertical en endIndex - 1 si no es el último punto if (endIndex < series.Count) { float xVertical = x2; float yVerticalStart = y2; float yVerticalEnd = canvasHeight - (series[endIndex] - minY + yoffset) * scaleY; var verticalLine = new Line { Stroke = color, StrokeThickness = 0.4, X1 = xVertical, Y1 = yVerticalStart, X2 = xVertical, Y2 = yVerticalEnd }; ChartCanvas.Children.Add(verticalLine); // Actualizar la última posición dibujada lastX = xVertical; lastY = yVerticalEnd; } else { // Actualizar la última posición dibujada para la última línea horizontal lastX = x2; lastY = y2; } // Actualizar startIndex startIndex = endIndex; } } } public partial class ucTrace3 : UserControl, IDataContainer { public osBase? Datos { get; set; } public ucTrace3() { InitializeComponent(); this.Loaded += OnLoaded; this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } private void OnUnloaded(object sender, RoutedEventArgs e) { Datos?.ucUnLoaded(); } public void Resize(float width, float height) { if (Datos is osTrace3 datos) { datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width); datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height); } } public void Move(float LeftPixels, float TopPixels) { if (Datos != null) { Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); } } public void Rotate(float Angle) { } public void Highlight(bool State) { } public int ZIndex() { return 10; } } }