Line Chart using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Collections.ObjectModel; using MindFusion.Charting; using Brush = MindFusion.Drawing.Brush; using SolidBrush = MindFusion.Drawing.SolidBrush; using System.IO; using MfgControl.AdvancedHMI.Drivers.Common; using System.Diagnostics; namespace DateTimeSeries //ChartTest Rev1.8 10-14-24 Workig on X-Axis Range and ToolTip { public partial class MainForm : Form { private StreamWriter fileWriter; // Create an instance of the Modbus client //private ModbusClient ModbusClient; private Timer logFileReaderTimer; Timer myTimer = new Timer(); Random random = new Random(); private string filename; // This should hold the actual file path MyDateTimeSeries series1; private Timer timer = new Timer(); // Class-level variable private string filePath; Timer timer1 = new Timer(); Timer timer2 = new Timer(); Timer timer3 = new Timer(); private double xAxisMaxValue = 183; // Default value private object currentTime; // Declare variables for YMax and values within the selected time span double YMax = 0; List valuesWithinTimeSpan = new List(); int selectedTimeSpan = 0; // Initialize selectedTimeSpan based on default or initial checkbox state // Declare YMin and YMax as class-level variables private double YMin = 0; private DateTime lastDataPointTime; double minYValue = 0; // Default minimum Y-axis value double maxYValue = 100; // Default maximum Y-axis value private double defaultMinYValue = 0; // Set your default minimum Y-axis value private double defaultMaxYValue = 300; // Set your default maximum Y-axis value bool enableAutoScroll = true; // Flag to control auto-scrolling behavior private double? xAxisRange; private Timer axisMonitorTimer; private double? previousMin = null; private double? previousMax = null; public MainForm() { InitializeComponent(); InitializeFileWriter(); InitializeChart(); // Add this new method to initialize the chart with correct X-axis bounds timer.Interval = 1000; // 1 second timer.Tick += new EventHandler(Timer_Tick); timer1.Interval = 1000; // 1000 milliseconds = 1 second timer1.Tick += new EventHandler(Timer1_Tick); // Event handler for the Tick event timer2.Interval = 1000; // 1000 milliseconds = 1 second timer2.Tick += new EventHandler(Timer2_Tick); // Event handler for the Tick event timer3.Interval = 1000; // 1000 milliseconds = 1 second timer3.Tick += new EventHandler(Timer3_Tick); // Event handler for the Tick event // Sets the timer interval to half a seconds. myTimer.Interval = 1000; myTimer.Tick += new EventHandler(TimerEventProcessor); // Start a timer to update chart values every second when basicButton1 is LightGreen logFileReaderTimer = new Timer(); logFileReaderTimer.Interval = 1000; logFileReaderTimer.Tick += LogFileReaderTimer_Tick; checkBox1.CheckedChanged += AdjustChartSettings; checkBox2.CheckedChanged += AdjustChartSettings; checkBox3.CheckedChanged += AdjustChartSettings; checkBox4.CheckedChanged += AdjustChartSettings; // Subscribe to the CheckedChanged event for each checkbox checkBox1.CheckedChanged += CheckBox_CheckedChanged; checkBox2.CheckedChanged += CheckBox_CheckedChanged; checkBox3.CheckedChanged += CheckBox_CheckedChanged; checkBox4.CheckedChanged += CheckBox_CheckedChanged; checkBox5.CheckedChanged += CheckBox1_CheckedChanged; checkBox6.CheckedChanged += CheckBox1_CheckedChanged; // Then set the default value to the X-axis. lineChart.XAxis.MaxValue = xAxisMaxValue; // create sample data ObservableCollection data = new ObservableCollection(); series1 = new MyDateTimeSeries(DateTime.Now, DateTime.Now, DateTime.Now.AddMinutes(1)); //series1.DateTimeFormat = DateTimeFormat.ShortTime; series1.DateTimeFormat = DateTimeFormat.CustomDateTime; series1.CustomDateTimeFormat = "hh:mm:ss"; //how many values will be added before a time stamp is rendered at the axis series1.LabelInterval = 10; series1.MinValue = 0; series1.MaxValue = 183; //series1.Title = "Server 1"; series1.SupportedLabels = LabelKinds.XAxisLabel; //series2 = new MyDateTimeSeries(DateTime.Now, DateTime.Now, DateTime.Now.AddMinutes(1)); //series2.DateTimeFormat = DateTimeFormat.LongTime; //series2.LabelInterval = 10; //series2.MinValue = 0; //series2.MaxValue = 120; //series2.Title = "Server 2"; //series2.SupportedLabels = LabelKinds.None; // setup chart lineChart.Series.Add(series1); //lineChart.Series.Add(series2); lineChart.Title = "Real-time Server Load"; lineChart.ShowXCoordinates = false; lineChart.ShowLegendTitle = false; lineChart.ShowLegend = false; lineChart.LayoutPanel.Margin = new Margins(0, 0, 20, 0); lineChart.ShowYRangeSelector = true; lineChart.XAxis.Title = ""; lineChart.XAxis.MinValue = 0; lineChart.XAxis.MaxValue = 183; // set the time span of the chart area (60= 30 sec 120 = 1min) lineChart.XAxis.Interval = 10; lineChart.YAxis.MinValue = 0; lineChart.YAxis.MaxValue = 100; lineChart.YAxis.Interval = 10; lineChart.YAxis.Title = ""; lineChart.XAxisLabelRotationAngle = 90; btnIncreaseRange.Click += BtnIncreaseRange_Click; btnDecreaseRange.Click += BtnDecreaseRange_Click; List brushes = new List() { new SolidBrush(Color.FromArgb(206, 0, 0)), new SolidBrush(Color.FromArgb(90, 121, 165)), new SolidBrush(Color.FromArgb(0, 52, 102)) }; List thicknesses = new List() { 2 }; PerSeriesStyle style = new PerSeriesStyle(brushes, brushes, thicknesses, null); lineChart.Plot.SeriesStyle = style; lineChart.Theme.PlotBackground = new SolidBrush(Color.White); lineChart.Theme.GridLineColor = Color.LightGray; lineChart.Theme.GridLineStyle = System.Drawing.Drawing2D.DashStyle.Dash; //lineChart.TitleMargin = new Margins(10); lineChart.GridType = GridType.Crossed; // Event handlers for CheckBoxes' CheckedChanged event checkBox1.CheckedChanged += (sender, e) => { if (checkBox1.Checked) { selectedTimeSpan = 1; // Update selectedTimeSpan value accordingly } }; checkBox2.CheckedChanged += (sender, e) => { if (checkBox2.Checked) { selectedTimeSpan = 2; // Update selectedTimeSpan value accordingly } }; checkBox3.CheckedChanged += (sender, e) => { if (checkBox3.Checked) { selectedTimeSpan = 3; // Update selectedTimeSpan value accordingly } }; checkBox4.CheckedChanged += (sender, e) => { if (checkBox4.Checked) { selectedTimeSpan = 4; // Update selectedTimeSpan value accordingly } }; // Initialize the axis monitor timer axisMonitorTimer = new Timer(); axisMonitorTimer.Interval = 1000; // Check every 1 second axisMonitorTimer.Tick += AxisMonitorTimer_Tick; axisMonitorTimer.Start(); // Start monitoring the X-axis range } private void InitializeChart() { // Initial setup for the chart lastDataPointTime = DateTime.Now; // Initialize last data point time to current time // Set the X-axis bounds to show data within a specified time span UpdateXAxisBounds(lastDataPointTime); } void UpdateXAxisBounds(DateTime newDataPointTime) { // Calculate the time span that fits within the visible chart area (e.g., 1 minute) TimeSpan visibleTimeSpan = TimeSpan.FromMinutes(1); // Convert the DateTime to a numerical value compatible with the X-axis bounds (assuming Unix timestamp) double lastDataPointUnixTime = (newDataPointTime - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; // Adjust the X-axis bounds to keep the latest data points within the visible range lineChart.XAxis.MinValue = lastDataPointUnixTime - visibleTimeSpan.TotalSeconds; lineChart.XAxis.MaxValue = lastDataPointUnixTime; } private void MainForm_Load(object sender, EventArgs e) { // Attach the KeyDown event handler to the lineChart control //lineChart.KeyDown += lineChart_KeyDown; lineChart.KeyDown += MainForm_KeyDown; // Attach the KeyUp event handler to the lineChart control //lineChart.KeyUp += lineChart_KeyUp; lineChart.KeyDown += MainForm_KeyUp; } // Function to update YMax and track values within the time span // Update Y axis range based on incoming data void UpdateYAxisRange(double newDataPoint) { if (newDataPoint > YMax) { YMax = newDataPoint; } double margin = 20; // Margin for spacing between YMin and lowest data point double newValue = newDataPoint - margin; if (newValue < YMin || YMin == 0) { YMin = newValue; } // Calculate a dynamic interval based on the range between YMin and YMax double range = YMax - YMin; double maxGridLines = 20; // Maximum number of grid lines you want double minInterval = 5; // Minimum interval to prevent dense grid lines initially // Calculate a suitable interval with a minimum specified value double interval = Math.Max(range / maxGridLines, minInterval); lineChart.YAxis.Interval = Math.Ceiling(interval); // Update the Y-axis interval double newMaxY = YMax + 100; if (newMaxY > lineChart.YAxis.MaxValue) { lineChart.YAxis.MaxValue = newMaxY; } if (YMin < lineChart.YAxis.MinValue) { lineChart.YAxis.MinValue = YMin; } } // Callback that simulates new data coming in void MainForm_KeyDown(object sender, KeyEventArgs e) { // Disable UpdateYAxisRange on Timer3 timer3.Tick -= UpdateYAxisRange; if (e.KeyCode == Keys.A && e.Shift) lineChart.YAxis.MaxValue += 50; if (e.KeyCode == Keys.Z && e.Shift) lineChart.YAxis.MaxValue -= 50; } void MainForm_KeyUp(object sender, KeyEventArgs e) { // Disable UpdateYAxisRange on Timer3 timer3.Tick -= UpdateYAxisRange; if (e.KeyCode == Keys.S && e.Shift) lineChart.YAxis.MinValue += 50; if (e.KeyCode == Keys.X && e.Shift) lineChart.YAxis.MinValue -= 50; } private void upbut1_Click(object sender, EventArgs e) { if (sender is Button clickedButton && clickedButton.Name == "upbut1") { timer3.Enabled = false; // Disable Timer3 } KeyEventArgs aShiftKey = new KeyEventArgs(Keys.A | Keys.Shift); MainForm_KeyDown(this, aShiftKey); } private void UpdateYAxisRange(object sender, EventArgs e) { throw new NotImplementedException(); } private void downbut1_Click(object sender, EventArgs e) { if (sender is Button clickedButton && clickedButton.Name == "downbut1") { timer3.Enabled = false; // Disable Timer3 } KeyEventArgs zShiftKey = new KeyEventArgs(Keys.Z | Keys.Shift); MainForm_KeyDown(this, zShiftKey); } private void upbut2_Click(object sender, EventArgs e) { if (sender is Button clickedButton && clickedButton.Name == "upbut2") { timer3.Enabled = false; // Disable Timer3 } KeyEventArgs sShiftKey = new KeyEventArgs(Keys.S | Keys.Shift); MainForm_KeyUp(this, sShiftKey); } private void downbut2_Click(object sender, EventArgs e) { if (sender is Button clickedButton && clickedButton.Name == "downbut2") { timer3.Enabled = false; // Disable Timer3 } KeyEventArgs xShiftKey = new KeyEventArgs(Keys.X | Keys.Shift); MainForm_KeyUp(this, xShiftKey); } private void Timer_Tick(object sender, EventArgs e) { // Copy the text from label3 to label43 label44.Text = label43.Text; // Start Time label45.Text = label3.Text; // Start PSI label46.Text = label40.Text; // End Time label47.Text = label2.Text; // End PSI // Assuming label2 and label3 contain numeric values represented as strings if (double.TryParse(label2.Text, out double valueLabel2) && double.TryParse(label3.Text, out double valueLabel3)) { // Perform the subtraction double result = valueLabel3 - valueLabel2; // Update label48 with the result of subtracting label3 from label2 label48.Text = result.ToString(); } else { // Handle the case where the text in label2 or label3 is not a valid number //MessageBox.Show("Invalid numeric value in label2 or label3.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void Timer2_Tick(object sender, EventArgs e) { timer2.Tick += new EventHandler(upbut1_Click); timer2.Tick += new EventHandler(downbut1_Click); timer2.Tick += new EventHandler(upbut2_Click); timer2.Tick += new EventHandler(downbut2_Click); } private void Timer3_Tick(object sender, EventArgs e) { if (double.TryParse(label2.Text, out double label2Val)) { UpdateYAxisRange(label2Val); } else { Console.WriteLine("Failed to convert label2 text to double."); } if (series1.Size > 1) { double currVal = series1.GetValue(series1.Size - 1, 0); if (currVal > lineChart.XAxis.MaxValue) { double span = currVal - series1.GetValue(series1.Size - 2, 0); lineChart.XAxis.MinValue += span; lineChart.XAxis.MaxValue += span; } //lineChart.ChartPanel.InvalidateLayout(); } } // This is the method to run when the timer is raised. private void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { if (double.TryParse(label2.Text, out double label2Val)) { series1.addValue(label2Val); } else { Console.WriteLine("Failed to convert label2 text to double."); } if (series1.Size > 1) { double currVal = series1.GetValue(series1.Size - 1, 0); if (currVal > lineChart.XAxis.MaxValue) { double span = currVal - series1.GetValue(series1.Size - 2, 0); lineChart.XAxis.MinValue += span; lineChart.XAxis.MaxValue += span; } lineChart.ChartPanel.InvalidateLayout(); } } private void Timer1_Tick(object sender, EventArgs e) { string currentTime = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"); // Remove the file extension from the FileName string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(basicDataLogger1.FileName); // Construct the new file name without the extension string newFileName = fileNameWithoutExtension; // Construct the new file name //string newFileName = basicDataLogger1.FileName; string labelValue = basicLabel1.Text; string line = $"{currentTime} {newFileName} {labelValue}"; // Write the line to the file if (fileWriter != null) { fileWriter.WriteLine(line); fileWriter.Flush(); // Ensure the data is written immediately } } private void LogFileReaderTimer_Tick(object sender, EventArgs e) { try { string lastColumnValue = GetLastColumnValueFromLogFile(Path.Combine(basicDataLogger1.FileFolder, basicDataLogger1.FileName)); string timestampValue = GetTimestampFromLogFile(Path.Combine(basicDataLogger1.FileFolder, basicDataLogger1.FileName)); if (!string.IsNullOrEmpty(lastColumnValue) && !string.IsNullOrEmpty(timestampValue)) { label2.Text = lastColumnValue; // Update label2 with the value of the last column label40.Text = timestampValue; // Update label40 with the timestamp value // Update label3 based on the checkbox selection UpdateLabel3BasedOnCheckBoxes(lastColumnValue); } } catch (IOException) { // Handle the exception accordingly MessageBox.Show("Error accessing the file. Please try again later.", "File Access Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private string GetLastColumnValueFromLogFile(string filePath) { string lastColumnValue = string.Empty; using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader streamReader = new StreamReader(fileStream)) { string line; string lastLine = string.Empty; while ((line = streamReader.ReadLine()) != null) { lastLine = line; } if (!string.IsNullOrEmpty(lastLine)) { var columns = lastLine.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); // Update to dynamically set the last column value if (columns.Length >= 1) { lastColumnValue = columns[columns.Length - 1]; // Get the value of the last column } } } } return lastColumnValue; } private string GetTimestampFromLogFile(string filePath) { string timestampValue = string.Empty; using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader streamReader = new StreamReader(fileStream)) { string line; string lastLine = string.Empty; while ((line = streamReader.ReadLine()) != null) { lastLine = line; } if (!string.IsNullOrEmpty(lastLine)) { var columns = lastLine.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); // Update to get the value of the timestamp (assuming it's the value at index 1) if (columns.Length >= 2) { timestampValue = columns[1]; } } } } return timestampValue; } private void UpdateLabel3BasedOnCheckBoxes(string lastColumnValue) { if (checkBox1.Checked) { UpdateLabelWithColumnValue(lastColumnValue, 183); } else if (checkBox2.Checked) { UpdateLabelWithColumnValue(lastColumnValue, 300); } else if (checkBox3.Checked) { UpdateLabelWithColumnValue(lastColumnValue, 600); } else if (checkBox4.Checked) { UpdateLabelWithColumnValue(lastColumnValue, 900); } } private void UpdateLabelWithColumnValue(string lastColumnValue, int linesToRead) { List lines = ReadFileLines(Path.Combine(basicDataLogger1.FileFolder, basicDataLogger1.FileName)); if (linesToRead >= 0 && linesToRead < lines.Count) { string[] columns = lines[lines.Count - linesToRead].Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (columns.Length >= 4) { //label3.Text = columns[3]; // Update label3 with the value of the specified column label3.Text = columns[columns.Length - 1]; label43.Text = columns[1]; // Update label43 with the Time Value } } } private void basicButton1_Click(object sender, EventArgs e) { //lineChart.Series.Clear(); // Check if at least one checkbox is selected if (!checkBox1.Checked && !checkBox2.Checked && !checkBox3.Checked && !checkBox4.Checked && !checkBox5.Checked && !checkBox6.Checked) { MessageBox.Show("Please select one 'Set Chart Time Span' CheckBox and\none 'Set Test Requirements' CheckBox option before proceeding.", "Selection Required", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // Also check if either checkBox5 or checkBox6 is selected if (!checkBox5.Checked && !checkBox6.Checked) { MessageBox.Show("Please select one 'Set Chart Time Span' CheckBox and\none 'Set Test Requirements' CheckBox option before proceeding.", "Selection Required", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // Disable checkboxes to prevent changes while processing ToggleCheckBoxesEnabled(false); statusLabel.Text = "No Errors"; using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"; saveFileDialog.RestoreDirectory = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { basicDataLogger1.FileFolder = Path.GetDirectoryName(saveFileDialog.FileName); basicDataLogger1.FileName = Path.GetFileName(saveFileDialog.FileName); fileWriter = new StreamWriter(Path.Combine(basicDataLogger1.FileFolder, basicDataLogger1.FileName)); basicDataLogger1.EnableLogging = true; label35.Text = Path.Combine(basicDataLogger1.FileFolder, basicDataLogger1.FileName); basicDataLogger1.DataChanged += BasicDataLogger1_DataChanged; basicButton1.BackColor = Color.LightGreen; basicButton2.BackColor = Color.LightSalmon; // Read the text from textBox4 string textBoxValue = textBox4.Text; // Display the value in label53 label53.Text = textBoxValue; // Gray out textBox4 initially textBox4.Enabled = false; logFileReaderTimer.Start(); myTimer.Start(); // Start the Timer timer.Start(); timer1.Start(); timer2.Start(); timer3.Start(); } } // Action for basicButton1 click ToggleCheckBoxesEnabled(false); // Disable checkboxes // Explicitly manage the state when basicButton1 is clicked StartTrending(); // Your method that starts the trending actio settingsPanel.Visible = false; // Ensures the panel and all its child controls are hid } private void basicButton2_Click(object sender, EventArgs e) { // Stop logging basicDataLogger1.EnableLogging = false; // Close and dispose of the StreamWriter if (fileWriter != null) { fileWriter.Close(); fileWriter.Dispose(); fileWriter = null; // Reset the reference to indicate it's no longer in use } // Re-enable checkboxes to allow new selections ToggleCheckBoxesEnabled(true); basicButton2.BackColor = SystemColors.Control; // Change basicButton1 color to its default color basicButton1.BackColor = SystemColors.Control;// Ensure to stop the log file reader timer when logging stops // Stop the timers if (timer != null) timer.Stop(); if (timer1 != null) timer1.Stop(); if (timer2 != null) timer2.Stop(); if (timer3 != null) timer3.Stop(); if (myTimer != null) myTimer.Stop(); if (logFileReaderTimer != null) logFileReaderTimer.Stop(); // Explicitly manage the state when button2 is clicked StopTrending(); // Your method that stops the trending actio // Allow textBox4 to be edited after basicButton2 is clicked textBox4.Enabled = true; } private void button3_Click_1(object sender, EventArgs e) { // Clear the statusLabel text statusLabel.Text = "No Errors"; } private void AdjustChartSettings(object sender, EventArgs e) { // Check which checkbox is checked and adjust the value accordingly if (checkBox1.Checked) { xAxisRange = 183; lineChart.XAxis.Interval = 10; // Adjust grid lines as needed series1.LabelInterval = 5; //series2.LabelInterval = 5; } else if (checkBox2.Checked) { xAxisRange = 600; lineChart.XAxis.Interval = 20; // Adjust for a larger range series1.LabelInterval = 5; //series2.LabelInterval = 5; } else if (checkBox3.Checked) { xAxisRange = 1200; lineChart.XAxis.Interval = 30; // Further adjustment series1.LabelInterval = 15; //series2.LabelInterval = 15; } else if (checkBox4.Checked) { xAxisRange = 1800; lineChart.XAxis.Interval = 60; // And adjust accordingly series1.LabelInterval = 15; //series2.LabelInterval = 15; } // Apply the modified max value to the chart lineChart.XAxis.MaxValue = lineChart.XAxis.MinValue + xAxisRange; // Refresh the chart if needed lineChart.Invalidate(); } // This method will be called when the 'Increase Range' button is clicked private void BtnIncreaseRange_Click(object sender, EventArgs e) { AdjustXAxisRange(true); // True means we're increasing the range } // This method will be called when the 'Decrease Range' button is clicked private void BtnDecreaseRange_Click(object sender, EventArgs e) { AdjustXAxisRange(false); // False means we're decreasing the range } // Method to adjust the x-axis range private void AdjustXAxisRange(bool increase) { // Parse the input from the textbox, default to 1 minute if invalid or empty int minutesToAdjust; if (!int.TryParse(txtXAxisRangeInput.Text, out minutesToAdjust)) { minutesToAdjust = 1; // Default adjustment is 1 minute } // Calculate the number of seconds based on the minutes to adjust double secondsToAdjust = minutesToAdjust * 60; // Use the null-coalescing operator (??) to provide a default value in case the value is null double currentMax = lineChart.XAxis.MaxValue ?? 0; // If MaxValue is null, it defaults to 0 double currentMin = lineChart.XAxis.MinValue ?? 0; // If MinValue is null, it defaults to 0 // Increase or decrease the range if (increase) { lineChart.XAxis.MaxValue = currentMax + secondsToAdjust; lineChart.XAxis.MinValue = currentMin + secondsToAdjust; } else { // Ensure we don't decrease below a reasonable limit lineChart.XAxis.MaxValue = Math.Max(currentMax - secondsToAdjust, secondsToAdjust); lineChart.XAxis.MinValue = Math.Max(currentMin - secondsToAdjust, 0); } // Refresh the chart to reflect the updated range lineChart.Invalidate(); } private List ReadFileLines(string filePath) { List lines = new List(); using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs)) { string line; while ((line = sr.ReadLine()) != null) { lines.Add(line); } } } return lines; } private void lineChart_DataItemClicked(object sender, HitResult e) { } private void ToggleCheckBoxesEnabled(bool enabled) { checkBox1.Enabled = enabled; checkBox2.Enabled = enabled; checkBox3.Enabled = enabled; checkBox4.Enabled = enabled; checkBox5.Enabled = enabled; checkBox6.Enabled = enabled; // Optionally adjust the color to visually indicate disabled state further Color color = enabled ? SystemColors.ControlText : SystemColors.GrayText; checkBox1.ForeColor = color; checkBox2.ForeColor = color; checkBox3.ForeColor = color; checkBox4.ForeColor = color; checkBox5.ForeColor = color; checkBox6.ForeColor = color; } private void CheckBox_CheckedChanged(object sender, EventArgs e) { // Cast the sender to a checkbox System.Windows.Forms.CheckBox changedCheckbox = sender as System.Windows.Forms.CheckBox; if (changedCheckbox != null && changedCheckbox.Checked) { // Uncheck all checkboxes except the one that was just checked foreach (var checkbox in new[] { checkBox1, checkBox2, checkBox3, checkBox4 }) { if (checkbox != changedCheckbox) { checkbox.Checked = false; } } } UpdaDurationLabel(); UpdateChartTitle(); } private void CheckBox1_CheckedChanged(object sender, EventArgs e) { // Cast the sender to a checkbox System.Windows.Forms.CheckBox changedCheckbox = sender as System.Windows.Forms.CheckBox; if (changedCheckbox != null && changedCheckbox.Checked) { // Uncheck all checkboxes except the one that was just checked foreach (var checkbox in new[] { checkBox5, checkBox6}) { if (checkbox != changedCheckbox) { checkbox.Checked = false; } } } UpdaDurationLabel(); UpdateChartTitle(); } private void UpdaDurationLabel() { if (checkBox1.Checked & checkBox5.Checked) { label49.Text = "1 Minute Test with 2 % Requrement"; } if (checkBox1.Checked & checkBox6.Checked) { label49.Text = "1 Minute Test with 3 % Requrement"; } else if (checkBox2.Checked & checkBox5.Checked) { label49.Text = "5 Minute Test with 2 % Requrement"; } else if (checkBox2.Checked & checkBox6.Checked) { label49.Text = "5 Minute Test with 3 % Requrement"; } else if (checkBox3.Checked & checkBox5.Checked) { label49.Text = "10 Minute Test Test with 2 % Requrement"; } else if (checkBox3.Checked & checkBox6.Checked) { label49.Text = "10 Minute Test Test with 3 % Requrement"; } else if (checkBox4.Checked & checkBox5.Checked) { label49.Text = "15 Minute Test with 2 % Requrement"; } else if (checkBox4.Checked & checkBox6.Checked) { label49.Text = "15 Minute Test with 3 % Requrement"; } } private void UpdateChartTitle() { // Construct the title with the contents of textBox1, textBox2, textBox7, textBox25, and textBox26 string combinedText = $"{textBox1.Text} {textBox2.Text} {textBox7.Text} {textBox5.Text} {textBox25.Text}"; // Check if textBox26 is not empty to include "Section" and its content in the title if (!string.IsNullOrEmpty(textBox26.Text)) { combinedText += " Section " + textBox26.Text; } lineChart.Title = combinedText; // Assuming you need to refresh/re-render the chart to show the title update lineChart.Invalidate(); // Use Invalidate(), Refresh(), or a similar method as necessary // Adjust chart title font size double fontSize = 16; // Set the font size to 14 (adjust as needed) lineChart.TitleFontSize = fontSize; } // Example methods to start/stop trending and manage UI elements accordingly private void StartTrending() { basicButton2.BackColor = Color.LightSalmon; ToggleCheckBoxesEnabled(false); MessageBox.Show("Click on Stop Trending Button to Stop Trending or \nTo Reset", "Action Required", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void StopTrending() { basicButton2.BackColor = SystemColors.Control; ToggleCheckBoxesEnabled(true); } // Method to update Modbus TCP settings private void UpdateModbusTCPSettings() { // Set Modbus TCP settings based on user input modbusTCPCom1.IPAddress = ipAddressTextBox.Text; modbusTCPCom1.TcpipPort = ushort.Parse(portTextBox.Text); modbusTCPCom1.MaxReadGroupSize = int.Parse(textBox19.Text); // Update MaxReadGroupSize modbusTCPCom1.SwapWords = true; // Enable SwapWords modbusTCPCom1.SwapBytes = true; // Enable SwapBytes // Update other settings as needed // ... } private void modbusTCPCom1_DataReceived(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) { } private void label2_Click(object sender, EventArgs e) { } private void label3_Click(object sender, EventArgs e) { } private void checkBox1_CheckedChanged(object sender, EventArgs e) { } private void label26_Click(object sender, EventArgs e) { } private void checkBox3_CheckedChanged(object sender, EventArgs e) { } private void ApplySettingsButton_Click_1(object sender, EventArgs e) { // Get user input from text boxes string ipAddress = ipAddressTextBox.Text; ushort port; int PLCAddressValue; // Try parsing port value if (!ushort.TryParse(portTextBox.Text, out port)) { MessageBox.Show("Invalid port number. Please enter a valid port number."); return; } // Try parsing Address value if (!int.TryParse(textBox19.Text, out PLCAddressValue)) { MessageBox.Show("Invalid Address number. Please enter a valid Address number."); return; } // Update Modbus TCP settings modbusTCPCom1.IPAddress = ipAddress; modbusTCPCom1.TcpipPort = port; // Update other settings as needed // ... UpdateModbusTCPSettings(); // Adjust PLC address value to read the next register as well int incrementedValue = PLCAddressValue + 1; if (checkBox8.Checked && checkBox7.Checked) { // Both checkboxes are checked basicLabel1.PLCAddressValue = textBox19.Text; } else if (checkBox8.Checked) { // Only checkBox8 is checked basicLabel1.PLCAddressValue = "," + incrementedValue.ToString(); } else if (checkBox7.Checked) { // Only checkBox7 is checked basicLabel1.PLCAddressValue = "F" + textBox19.Text; } else { // Neither checkbox is checked basicLabel1.PLCAddressValue = "F" + "," + incrementedValue.ToString(); } } private void settingsButton_Click(object sender, EventArgs e) { settingsPanel.Visible = true; // Replace 'settingsPanel' with the actual name of your Panel or GroupBox } private void doneButton_Click(object sender, EventArgs e) { settingsPanel.Visible = false; // Ensures the panel and all its child controls are hidden } private void BasicDataLogger1_DataChanged(object sender, PlcComEventArgs e) { throw new NotImplementedException(); } private void basicDataLogger1_DataChanged_1(object sender, PlcComEventArgs e) { // Run the method to update the chart with the last value when data changes //UpdateChartWithLastValue(); } private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { Graphics myGraphics = CreateGraphics(); var bitmap = new Bitmap(Width, Height * 2, myGraphics); // Doubling the height DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height)); e.Graphics.DrawImage(bitmap, 15, 50); // Specify the width and height of the print window } private void printPreviewDialog1_Load(object sender, EventArgs e) { } private void printBut_Click(object sender, EventArgs e) { // Show the print dialog if (printDialog1.ShowDialog() == DialogResult.OK) { // Set the printer settings from the PrintDialog printDocument1.PrinterSettings = printDialog1.PrinterSettings; // Set the print orientation to Landscape printDocument1.DefaultPageSettings.Landscape = true; // Print the document printDocument1.Print(); } } private void InitializeFileWriter() { //throw new NotImplementedException(); } private void panel1_Paint(object sender, PaintEventArgs e) { } private void ApplyValuesToYAxis() { lineChart.YAxis.MinValue = minYValue; lineChart.YAxis.MaxValue = maxYValue; } private void ResetChart() { // Reset Y-axis values to default or adjust them based on data in the chart minYValue = 0; // Reset to default or adjust as needed maxYValue = 100; // Reset to default or adjust as needed ApplyValuesToYAxis(); } void lineChart_KeyDown(object sender, KeyEventArgs e) { if (enableAutoScroll && e.KeyCode == Keys.Shift) { // Increase Y-axis values for vertical scrolling maxYValue += 10; // Adjust as needed minYValue += 10; // Adjust as needed // Apply the updated Y-axis values to the lineChart ApplyValuesToYAxis(); } } void lineChart_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Shift) { // Modify Y-axis values when Shift key is released (if needed) } } private void checkBox9_CheckedChanged(object sender, EventArgs e) { enableAutoScroll = checkBox9.Checked; // Update the flag based on checkbox state } private void label44_Click(object sender, EventArgs e) { } private void enablebut_Click(object sender, EventArgs e) { timer3.Enabled = true; if (enablebut.Enabled) { timer3.Tick += Timer3_Tick; //myTimer.Enabled = false; // Disable Timer3 ResetChart(); } else { timer3.Tick -= Timer3_Tick; } } private void ipAddressTextBox_TextChanged(object sender, EventArgs e) { } void AdjustXAxisGridLines() { // Get the current visible range (MaxValue - MinValue) in seconds double visibleRange = (lineChart.XAxis.MaxValue ?? 0) - (lineChart.XAxis.MinValue ?? 0); // Define different intervals based on the visible time span if (visibleRange <= 183) // 1 minute or less { lineChart.XAxis.Interval = 10; // Set interval to 10 seconds } else if (visibleRange <= 600) // 10 minutes or less { lineChart.XAxis.Interval = 60; // Set interval to 1 minute } else if (visibleRange <= 3600) // 1 hour or less { lineChart.XAxis.Interval = 300; // Set interval to 5 minutes } else if (visibleRange <= 7200) // 2 hours or less { lineChart.XAxis.Interval = 600; // Set interval to 10 minutes } else { lineChart.XAxis.Interval = 1800; // Set interval to 30 minutes for larger time spans } } private void basicButton3_Click(object sender, EventArgs e) { // Call this method after adjusting the X-axis range in your button click events AdjustXAxisGridLines(); } private void AxisMonitorTimer_Tick(object sender, EventArgs e) { // Get current X-axis MinValue and MaxValue double? currentMin = lineChart.XAxis.MinValue; double? currentMax = lineChart.XAxis.MaxValue; // Check if the X-axis range has changed if (currentMin != previousMin || currentMax != previousMax) { // X-axis range changed, update the text box UpdateTimeSpanInTextBox(currentMin, currentMax); // Store the current values as the previous ones for future comparison previousMin = currentMin; previousMax = currentMax; } } // Method to calculate and update the time span in the text box private void UpdateTimeSpanInTextBox(double? currentMin, double? currentMax) { if (currentMin.HasValue && currentMax.HasValue) { // Assuming the X-axis values are in seconds (Unix timestamps) DateTime minTime = DateTimeOffset.FromUnixTimeSeconds((long)currentMin.Value).UtcDateTime; DateTime maxTime = DateTimeOffset.FromUnixTimeSeconds((long)currentMax.Value).UtcDateTime; // Calculate the time span TimeSpan timeSpan = maxTime - minTime; // Update the text box (assuming you have a textBox named textBoxTimeSpan) textBoxTimeSpan.Text = $"Time Span: {timeSpan.TotalMinutes} minutes"; } } } class YTooltip : Series { public LabelKinds SupportedLabels => series.SupportedLabels | LabelKinds.ToolTip; public string GetLabel(int index, LabelKinds kind) { if (kind == LabelKinds.ToolTip) return series.GetValue(index, 1).ToString(); return series.GetLabel(index, kind); } public YTooltip(Series series) { Debug.Assert(series.Dimensions >= 2); this.series = series; } public int Size => series.Size; public int Dimensions => series.Dimensions; public string Title => series.Title; public double GetValue(int index, int dimension) { return series.GetValue(index, dimension); } public bool IsEmphasized(int index) { return series.IsEmphasized(index); } public bool IsSorted(int dimension) { return false; } public event EventHandler DataChanged; Series series; } public class Sample { public Sample(string line) { var parts = line.Split(new char[] { ' ' }, StringSplitOptions.None); //Date = DateTime.Parse(parts[0]); Time = TimeSpan.Parse(parts[1]); //Label = parts[2]; Value = double.Parse(parts[3]); } public DateTime Date { get; set; } public TimeSpan Time { get; set; } public string Label { get; set; } public double Value { get; set; } } public class Pressure : Series { public Pressure(IList Records) { values = Records; } public double GetValue(int index, int dimension) { if (dimension == 0) return values[index].Time.TotalSeconds; else return values[index].Value; } public string GetLabel(int index, LabelKinds kind) { if (kind == LabelKinds.ToolTip) return values[index].Label; return null; } public bool IsSorted(int dimension) { return false; } public bool IsEmphasized(int index) { return false; } public int Size { get { return values.Count; } } public int Dimensions { get { return 3; } } public string Title { get { return "test"; } } public LabelKinds SupportedLabels { get { return LabelKinds.InnerLabel | LabelKinds.ToolTip; } } public event EventHandler DataChanged; public IList Values { get { return values; } } IList values; public void Append(Sample sample) { values.Add(sample); DataChanged.Invoke(this, EventArgs.Empty); } } }