Загрузка данных


using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace FunctionTabulator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeCustomUI();
        }

        // Настройка начального состояния элементов
        private void InitializeCustomUI()
        {
            // Настройка ComboBox для типов графиков
            cmbChartType.Items.AddRange(new object[] { "Line", "Point", "Spline", "Step Line" });
            cmbChartType.SelectedIndex = 0; // По умолчанию Line

            // Настройка Chart
            chart1.Series.Clear();
            chart1.ChartAreas.Clear();
            chart1.ChartAreas.Add(new ChartArea("MainArea"));
            chart1.Series.Add(new Series("FuncSeries"));
            chart1.Series["FuncSeries"].ChartType = SeriesChartType.Line;
            chart1.Series["FuncSeries"].BorderWidth = 2;
            
            // Настройка DataGridView
            dataGridView1.AllowUserToAddRows = false;
            dataGridView1.ReadOnly = true;
        }

        // Функция y = sqrt(x^3). 
        // ВНИМАНИЕ: Корень из отрицательного числа в действительных числах не существует.
        // Для x < 0 функция не определена (возвращаем NaN).
        private double CalculateFunction(double x)
        {
            if (x < 0) return double.NaN; // Или Math.Sqrt(Math.Pow(x, 3)) если нужны комплексные числа, но для графика NaN лучше
            return Math.Sqrt(Math.Pow(x, 3));
        }

        // Кнопка "Выполнить расчёт"
        private void btnCalculate_Click(object sender, EventArgs e)
        {
            if (!ValidateInputs()) return;

            double a = double.Parse(txtA.Text);
            double b = double.Parse(txtB.Text);
            double h = double.Parse(txtH.Text);

            dataGridView1.Rows.Clear();
            chart1.Series["FuncSeries"].Points.Clear();

            // Проверка на корректность шага
            if (h <= 0)
            {
                MessageBox.Show("Шаг должен быть больше нуля!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Табулирование
            for (double x = a; x <= b + 1e-9; x += h)
            {
                double y = CalculateFunction(x);

                // Добавление в таблицу
                dataGridView1.Rows.Add(Math.Round(x, 4), double.IsNaN(y) ? "Не опр." : Math.Round(y, 4).ToString());

                // Добавление на график (только если значение определено)
                if (!double.IsNaN(y))
                {
                    chart1.Series["FuncSeries"].Points.AddXY(x, y);
                }
            }
        }

        // Проверка полей ввода
        private bool ValidateInputs()
        {
            if (string.IsNullOrWhiteSpace(txtA.Text) || string.IsNullOrWhiteSpace(txtB.Text) || string.IsNullOrWhiteSpace(txtH.Text))
            {
                MessageBox.Show("Заполните все поля!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }

            if (!double.TryParse(txtA.Text, out _) || !double.TryParse(txtB.Text, out _) || !double.TryParse(txtH.Text, out _))
            {
                MessageBox.Show("Неверный формат чисел! Используйте точку или запятую.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        // Кнопка "Очистить всё"
        private void btnClear_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            chart1.Series["FuncSeries"].Points.Clear();
        }

        // Изменение типа графика в ComboBox
        private void cmbChartType_SelectedIndexChanged(object sender, EventArgs e)
        {
            string selected = cmbChartType.SelectedItem.ToString();
            switch (selected)
            {
                case "Line":
                    chart1.Series["FuncSeries"].ChartType = SeriesChartType.Line;
                    break;
                case "Point":
                    chart1.Series["FuncSeries"].ChartType = SeriesChartType.Point;
                    break;
                case "Spline":
                    chart1.Series["FuncSeries"].ChartType = SeriesChartType.Spline;
                    break;
                case "Step Line":
                    chart1.Series["FuncSeries"].ChartType = SeriesChartType.StepLine;
                    break;
            }
        }

        // Меню: Сохранить как (CSV)
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (dataGridView1.Rows.Count == 0)
            {
                MessageBox.Show("Таблица пуста! Нечего сохранять.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Filter = "CSV файлы (*.csv)|*.csv";
                sfd.Title = "Сохранить расчёты";
                sfd.DefaultExt = "csv";

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        using (StreamWriter sw = new StreamWriter(sfd.FileName))
                        {
                            // Заголовки
                            sw.WriteLine("X;Y");
                            
                            // Данные
                            foreach (DataGridViewRow row in dataGridView1.Rows)
                            {
                                if (row.Cells[0].Value != null)
                                {
                                    sw.WriteLine($"{row.Cells[0].Value};{row.Cells[1].Value}");
                                }
                            }
                        }
                        MessageBox.Show("Файл успешно сохранён!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Ошибка при сохранении: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        // Меню: Загрузить данные (CSV)
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "CSV файлы (*.csv)|*.csv";
                ofd.Title = "Загрузить данные";

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        string[] lines = File.ReadAllLines(ofd.FileName);
                        
                        // Проверка структуры файла
                        if (lines.Length < 2 || !lines[0].Contains(";"))
                        {
                            MessageBox.Show("Некорректный формат файла!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }

                        dataGridView1.Rows.Clear();
                        chart1.Series["FuncSeries"].Points.Clear();

                        // Пропускаем первую строку (заголовки)
                        for (int i = 1; i < lines.Length; i++)
                        {
                            string[] parts = lines[i].Split(';');
                            
                            // Проверка структуры строки
                            if (parts.Length != 2)
                            {
                                MessageBox.Show("Некорректный формат файла!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return;
                            }

                            // Проверка формата чисел
                            if (!double.TryParse(parts[0], out double x) || !double.TryParse(parts[1], out double y))
                            {
                                MessageBox.Show("Неверный формат входных данных!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return;
                            }

                            // Добавляем в таблицу
                            dataGridView1.Rows.Add(x, y);
                            
                            // Добавляем на график
                            chart1.Series["FuncSeries"].Points.AddXY(x, y);
                        }

                        MessageBox.Show("Данные успешно загружены!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("Некорректный формат файла!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
    }
}