C# Visual Studio Chart не может обрабатывать даты в XValue

Вопрос или проблема

Моя диаграмма в Microsoft Forms, использующая Visual Studio, не может показать даты в правильном формате. Когда вы вводите целые числа, всё работает отлично, но числа, отформатированные как даты, не отображаются.

Это моя таблица в SQLite с pd_data в виде целых чисел.

CREATE TABLE producao(
pd_pr_codigo INTEGER,
pd_data INTEGER,
pd_codigo INTEGER,
pd_qtd_produzida REAL,
PRIMARY KEY (pd_pr_codigo, pd_codigo, pd_data)
FOREIGN KEY (pd_pr_codigo) REFERENCES produtos(pr_codigo)

Это мой код:

        private void BtProdBlocos_Click(object sender, EventArgs e)
        {
            try
            {
                string sql = "SELECT pd_data, pd_qtd_produzida FROM producao";
                SqliteParameter[] emptyparameter = new SqliteParameter[]{ };
                chart1.DataSource = Funcoes.Cursor(sql, emptyparameter);

                chart1.Series["Producao"].XValueMember = "pd_data"; 
                chart1.Series["Producao"].YValueMembers = "pd_qtd_produzida";

                chart1.DataBind();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

И вот график, значения по оси X — целые числа, соответствующие датам 2024/10/22 и 2024/10/23.

Теперь, используя pd_data как текст и задавая даты в формате дд/мм/гггг в SQL:

CREATE TABLE producao(
pd_pr_codigo INTEGER,
pd_data TEXT,
pd_codigo INTEGER,
pd_qtd_produzida REAL,
PRIMARY KEY (pd_pr_codigo, pd_codigo, pd_data)
FOREIGN KEY (pd_pr_codigo) REFERENCES produtos(pr_codigo)

С теми же датами и тем же кодом, отображается только 1 дата, и что бы я ни делал, ничего не меняется. Я. НЕ. УДАЛСЯ. УСТАНОВИТЬ.

Столбцы таблицы, показывающие даты, есть.

Я отладил код и пришел к выводу, что все даты приходят, но по какой-то причине не отображаются правильно на диаграмме. Также Funcoes.cursor — это соединение с базой данных. Я отправляю SQL-запрос через эту функцию, и она возвращает все значения.

ИЗМЕНЕНИЕ: Мне удалось найти решение. Значение X должно быть типа datetime в C#, чтобы оно было верно понято. Поскольку SQLite не имеет родного типа datetime, решением было перенести оба значения в DataTable и внутри него преобразовать значения pd_data и pd_qtd_quantidade в datetime и double соответственно. В коде я также отформатировал ось X, чтобы отображать под углом 45 градусов для лучшей читаемости, и она будет показывать только первые и последние значения в качестве опциональных. Единственное, что я не смог изменить, это то, что если между датами есть разрыв, программа его заполняет (например: с 10/11/2024 по 10/13/2024, диаграмма добавит 10/12/2024 между ними, даже без значения Y), что мне не понравилось, и я хотел бы это изменить, хотя еще не нашел решения. Надеюсь, это поможет и другим!

Вот код:

    private void BtProdBlocos_Click(object sender, EventArgs e)
    {
        string comandosql = "SELECT pd_data, pd_qtd_produzida FROM producao";
        SqliteParameter[] parametrovazio = new SqliteParameter[] { };
        DataTable dataTable = Funcoes.Cursor(comandosql, parametrovazio);
    
        // Проверяем, имеет ли диаграмма правильные серии
        if (chart1.Series.Count == 0)
        {
            chart1.Series.Add("Producao");
        }
    
        // Конфигурируем серию
        chart1.Series["Producao"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
        chart1.Series["Producao"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
    
        // Очищаем предыдущие данные (если есть)
        chart1.Series["Producao"].Points.Clear();
    
        // Добавляем точки на диаграмму
        foreach (DataRow row in dataTable.Rows)
        {
            DateTime data = Convert.ToDateTime(row["pd_data"]);
            double quantidadeProduzida = Convert.ToDouble(row["pd_qtd_produzida"]);
    
            // Добавляем точку (дата, количество) в серию
            chart1.Series["Producao"].Points.AddXY(data, quantidadeProduzida);
        }
    
        // Устанавливаем формат меток оси X, чтобы отображались только день и месяц
        chart1.ChartAreas[0].AxisX.LabelStyle.Format = "dd/MM/yyyy";
    
        // Устанавливаем угол меток на оси X
        chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
    
        // Устанавливаем интервал для меток оси X (в данном случае установлен на 1 день)
        chart1.ChartAreas[0].AxisX.Interval = 1;
        chart1.ChartAreas[0].AxisX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Days;
    
        // Опционально: принудительно устанавливаем границы оси X, чтобы она начиналась и заканчивалась в точных датах
        chart1.ChartAreas[0].AxisX.Minimum = chart1.Series["Producao"].Points[0].XValue;
        chart1.ChartAreas[0].AxisX.Maximum = chart1.Series["Producao"].Points[chart1.Series["Producao"].Points.Count - 1].XValue;
    
        // Обновляем диаграмму
        chart1.Invalidate();
    }

Ответ или решение

Конечно! Вот полный ответ на ваш вопрос о работе с датами в диаграмме C# в Visual Studio и решения проблемы отображения дат корректно.

Проблема

Ваша диаграмма, используемая в приложении Windows Forms, не может обрабатывать даты, когда они представлены в виде целых чисел или строк. Вместо этого вы наблюдаете только частичное отображение данных или неправильную интерпретацию оси X.

Решение

Для правильной обработки дат в диаграмме вам необходимо убедиться в следующих вещах:

  1. Тип даты в C#: Так как SQLite не имеет родного типа данных для даты, вы можете преобразовать ваши даты, сохраненные как текст (например, в формате "dd/MM/yyyy"), в объект DateTime в C#.

  2. Настройка оси X: Установите XValueType для серии диаграммы в ChartValueType.DateTime, чтобы диаграмма понимала, что по оси X у вас даты.

  3. Очистка точек графика: Перед добавлением новых точек в серию диаграммы обязательно очистите предыдущие данные.

  4. Форматирование оси X: Убедитесь, что у вас правильно установлен формат даты для меток оси X, и установите угол наклона меток для улучшения читаемости.

  5. Обработка пробелов в датах: Чтобы избежать автоматического заполнения промежутков дат, вы можете использовать дополнительные проверки перед добавлением точек в серию диаграммы.

Полный пример кода

Вот полный код, который вы можете использовать для решения вашей проблемы:

private void BtProdBlocos_Click(object sender, EventArgs e)
{
    try
    {
        string sql = "SELECT pd_data, pd_qtd_produzida FROM producao";
        SqliteParameter[] emptyparameter = new SqliteParameter[] { };
        DataTable dataTable = Funcoes.Cursor(sql, emptyparameter);

        // Проверка наличия серий в графике
        if (chart1.Series.Count == 0)
        {
            chart1.Series.Add("Producao");
        }

        // Настройка серии
        chart1.Series["Producao"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
        chart1.Series["Producao"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;

        // Очистка предыдущих данных
        chart1.Series["Producao"].Points.Clear();

        // Добавление точек в график
        foreach (DataRow row in dataTable.Rows)
        {
            DateTime data = Convert.ToDateTime(row["pd_data"]);
            double quantidadeProduzida = Convert.ToDouble(row["pd_qtd_produzida"]);

            // Добавить точку (дата, количество) в серию
            chart1.Series["Producao"].Points.AddXY(data, quantidadeProduzida);
        }

        // Настройка формата меток оси X
        chart1.ChartAreas[0].AxisX.LabelStyle.Format = "dd/MM/yyyy";
        chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;

        // Установка интервала меток по оси X
        chart1.ChartAreas[0].AxisX.Interval = 1;
        chart1.ChartAreas[0].AxisX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Days;

        // Настройка границ оси X
        if (chart1.Series["Producao"].Points.Count > 0)
        {
            chart1.ChartAreas[0].AxisX.Minimum = chart1.Series["Producao"].Points[0].XValue;
            chart1.ChartAreas[0].AxisX.Maximum = chart1.Series["Producao"].Points[chart1.Series["Producao"].Points.Count - 1].XValue;
        }

        // Обновление графика
        chart1.Invalidate();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Заключение

После внесения перечисленных изменений ваше приложение должно правильно обрабатывать даты на диаграмме, позволяет отображать информацию в нужном формате и избегать автоматической подстановки промежуточных дат. Если у вас есть дополнительные вопросы или необходима помощь с конкретной частью кода, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...