Загрузка данных
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);
}
}
}
}
}
}