【问题标题】:Create a line chart with individual lines for each day of the week?为一周中的每一天创建一个带有单独线条的折线图?
【发布时间】:2012-02-11 02:43:33
【问题描述】:

我在数据库表中有以下数据, :日期、小时(从 1 到 24)和温度。

我想创建一个折线图,在 x 轴上显示从 1 到 24 的小时数,在 Y 轴上显示温度。

现在棘手的部分是我想为每个日期设置不同的颜色线。因此,如果日期是 2012-01-15,那么我有一条从 1 到 24 的红线,显示温度的变化。如果日期是 2012-01-14,那么蓝色也是从 1 到 24。

明确地说,我想在一张图表中包含多个日期。

这是我的一些代码

        SqlConnection conn2 = new SqlConnection(@"connectionString");
        conn2.Open();

        SqlCommand cmd2 = new SqlCommand();
        cmd2.Connection = conn2;
        cmd2.CommandText = "SELECT * FROM observation WHERE day BETWEEN @fromDate AND @toDate ORDER BY day ASC, hour ASC ";
        cmd2.Parameters.AddWithValue("fromDate", dateTimePicker2.Value.Date);
        cmd2.Parameters.AddWithValue("toDate", dateTimePicker3.Value.Date);



        SqlDataReader reader = cmd2.ExecuteReader();
        DataSet ds = new DataSet();
        DataTable dt = new DataTable("dateRange");
        dt.Columns.Add("day");
        dt.Columns.Add("hour");
        dt.Columns.Add("temp");

        DataRow dr = dt.NewRow();
        int counter = 0;

        while (reader.Read())
        {
            if (reader[1].ToString() != dt.TableName)
            {
                if (dt.Rows.Count != 0 && dt.TableName != "dateRange")
                {
                    dt.AcceptChanges();
                    ds.Tables.Add(dt);
                    counter++;
                }
                dt = new DataTable(reader[1].ToString());
                dt.Columns.Add("day"):                    
                dt.Columns.Add("hour");
                dt.Columns.Add("temp");

            }
            dr = dt.NewRow();
            dr[0] = reader[2];
            dr[1] = reader[3];
            dt.Rows.Add(dr);
        }
        if (dt.Rows.Count != 0)
        {
            dt.AcceptChanges();
            ds.Tables.Add(dt);
        }
        else
        {
            lblError.Visible = false;
        }

        for (int i = 0; i < counter; i++)
        {
            chart1.Series[i].Name = i.ToString();
            chart1.Series[i].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            chart1.Series[i].BorderWidth = 5;
            if (i % 2 == 0)
            {
                chart1.Series[i].Color = Color.Red;
            }
            else
            {
                chart1.Series[i].Color = Color.Green;
            }

            chart1.DataSource = ds.Tables[i];
            chart1.Series[i].XValueMember = "hour";
            chart1.Series[i].YValueMembers = "temp";
        }

        chart1.Legends[0].Alignment = StringAlignment.Center;
        chart1.Legends[0].Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;

        chart1.DataBind();
        chart1.Visible = true;

        cmd2.Connection.Close();

谢谢!

【问题讨论】:

  • 您遇到问题的部分是什么?从数据库中提取数据;创建图表;为不同的日期制定不同的颜色;在一个图表中显示多条线?如果您可以发布一些您已经开始使用的代码,您可以期待简短而简洁的答案。还是您正在寻找粗略的指导方针?
  • @Jonno 我现在遇到的麻烦是在 x 轴上保持 1 到 24 的同时显示多行。我试图在一个 DataSet 中创建多个表,但是无法指示要使用哪个表....我不确定如何创建多行,那会是多个系列吗?
  • @Jonno。我添加了我拥有的代码。我知道这很混乱:S 任何帮助将不胜感激

标签: c# winforms visual-studio-2010 charts


【解决方案1】:

为了创建多条线,您必须创建多个系列,但我不确定您在这里使用的图表类型是关于图表的非常好的教程

http://www.4guysfromrolla.com/articles/072209-1.aspx

Chart1.Series[0].Points.FindMinByValue().Color = Color.Red; 这应该会改变每个点的颜色。

【讨论】:

  • 如果我创建了很多系列,我应该如何构建 DataSource 来提供这么多系列?
  • 如果您使用上面的示例并且根据您想要做的事情,我认为您不必使用很多系列,我不会绑定源我会使用 for-each 循环管理每个数字我可以管理外观并创建许多系列。
  • 我根据您的一些信息创建了一个解决方案。你可以在下面看到它。谢谢!
【解决方案2】:

我找到的一个解决方案是重新格式化我的数据源。我创建了一个 DataTable,第一列是 Hours,它从 1 到 24。以下列是我想要表示的每一天。

有两个查询。第一个是知道间隔中有多少天,并创建适当数量的列和系列。第二个查询是引入所有数据的查询。

代码如下:

        SqlConnection conn = new SqlConnection(connectionString);

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "SELECT day FROM observation WHERE day BETWEEN @from AND @to GROUP BY day";
        cmd.Parameters.AddWithValue("from", Convert.ToDateTime(dateFrom));
        cmd.Parameters.AddWithValue("to", Convert.ToDateTime(dateTo));
        cmd.Connection.Open();

        SqlDataReader rdr = cmd.ExecuteReader();

        DataTable dt = new DataTable("DATA");
        dt.Columns.Add("Hour");

        int days = 0;
        chart1.DataSource = dt;
        while (rdr.Read())
        {
            dt.Columns.Add(((DateTime)rdr[0]).ToString("yyyy-MM-dd"));

            if (days == 0)
            {
                chart1.Series[days].Name = ((DateTime)rdr[0]).ToString("yyyy-MM-dd");
            }
            else
            {
                chart1.Series.Add(((DateTime)rdr[0]).ToString("yyyy-MM-dd"));
            }
            chart1.Series[((DateTime)rdr[0]).ToString("yyyy-MM-dd")].XValueMember = "Hour";
            chart1.Series[((DateTime)rdr[0]).ToString("yyyy-MM-dd")].YValueMembers = ((DateTime)rdr[0]).ToString("yyyy-MM-dd");
            chart1.Series[((DateTime)rdr[0]).ToString("yyyy-MM-dd")].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            days++;
        }
        rdr.Close();

        DataRow dr = dt.NewRow();
        for (int i = 1; i < 25; i++)
        {
            dr = dt.NewRow();
            dr["Hour"] = i;
            dt.Rows.Add(dr);
        }

        cmd.CommandText = "SELECT * FROM observation WHERE day BETWEEN @from2 AND @to2 ORDER BY day ASC, hour ASC ";
        cmd.Parameters.AddWithValue("from2", Convert.ToDateTime(fromDate));
        cmd.Parameters.AddWithValue("to2", Convert.ToDateTime(toDate));

        rdr = cmd.ExecuteReader();
        while (rdr.Read())
        {
            dt.Rows[((int)(rdr[2]) - 1)][(((DateTime)rdr[1]).ToString("yyyy-MM-dd"))] = rdr[3];   
        }

        cmd.Connection.Close();
        rdr.Close();

        dataGridView1.DataSource = dt;

        chart1.DataBind();
        chart1.Visible = true;

【讨论】:

    【解决方案3】:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
    dtTest.Columns.Add("TimePoint", GetType(Integer))
    dtTest.Columns.Add("Speed", GetType(Integer))
    
    dtTest.Rows.Add(0, 0)
    dtTest.Rows.Add(1000, 50)
    dtTest.Rows.Add(2000, 50)
    dtTest.Rows.Add(3000, 0)
    
    With Chart1.ChartAreas(0)
      .AxisX.Minimum = 0
      .AxisX.Maximum = 3000
      .AxisY.Minimum = 0
      .AxisY.Maximum = 60
      .AxisY.Interval = 10
      .AxisX.Title = "Elapsed Time (ms)"
      .AxisY.Title = "Speed (km/hr)"
    End With
    End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        With Chart1.Series(0)
          .Points.DataBind(dtTest.DefaultView, "TimePoint", "Speed", Nothing)
          .ChartType = DataVisualization.Charting.SeriesChartType.Line
          .BorderWidth = 4
        End With
    End Sub
    

    【讨论】:

    • 感谢您发布答案!虽然代码 sn-p 可以回答这个问题,但添加一些附加信息仍然很棒,比如解释等..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    相关资源
    最近更新 更多