【问题标题】:Drawing a chart from a datatable从数据表中绘制图表
【发布时间】:2015-11-07 21:34:19
【问题描述】:

我正在尝试绘制一个包含多个系列的图表。它的数据来自数据库,通过DataAdapter 进入DataTable,就像这样;

public DataTable deaths_per_reason_per_year(string farmerid)
 {
     dt = new DataTable();
     try
     {
         conn.Open();  // (select formatted to fit SO lines)
         SqlCommand cmd = new SqlCommand("SELECT DATEPART(yyyy, DeathDate) AS 'Year',   
              Reason,   
              COUNT(DeathID) AS 'Number of Deaths' FROM [Farmstat_V1.0].[dbo].[Death] 
              WHERE FarmerID = '" + farmerid + "' 
              GROUP BY  Reason, YEAR(DeathDate);", conn);
         SqlDataReader reader = cmd.ExecuteReader();
         dt.Load(reader);
     }
     catch (Exception)
     {
         throw;
     }
     finally
     {
         conn.Close();
     }
     return dt;
 }

这给了我以下输出;

当我尝试将 DataTable 分配给表单上的图表时,使用这个;

StatsDataAccess sda = new StatsDataAccess();

chart1.DataSource = sda.deaths_per_reason_per_year(FarmerID);
chart1.Series["Series1"].XValueMember = "Year";
chart1.Series["Series1"].YValueMembers = "Number of Deaths";
chart1.Series["Series2"].XValueMember = "Reason";
chart1.Series["Series2"].YValueMembers = "Number of Deaths";
chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
chart1.Series["Series1"].IsValueShownAsLabel = true;
chart1.DataBind();

我得到一个看起来像这样的绘制图形,我已经通过图表的属性窗格在其中添加了系列;

但我想要一个看起来像这样的输出;

我试过用谷歌搜索但没有成功。有人可以帮我吗? 我会非常感激。 谢谢

【问题讨论】:

    标签: c# charts datatable


    【解决方案1】:

    最明显的问题是关于 x 值的数据类型。

    所有 X 值在内部都是 double 类型。

    简介

    • 如果您在 X 值中添加带有数字的 DataPoints,则它们将按预期进行处理和存储
    • 如果您将 DataPointsDateTime X 值相加,它们也会被转换为双精度值(通过 OLE 自动化日期转换)

    但是如果你添加了不能转换为数字的类型,比如字符串,事情就会变得很奇怪。 内部 X 值都是0,因为除了标签显示 字符串之外,它们还能是什么。

    显示的DataPoints 被视为 X 值为 0、1、2、3...,并且这些点以良好且相等的间距显示。

    对于许多新手来说,这看起来不错,但他们从不知道他们实际上已经失去了 X 值。

    当尝试使用数字格式或尝试使用 X 值进行计算时,就会出现问题。

    您的问题

    您的“问题”是您的 selectDATEPART 函数传递整数,所以您做对了,事实上您做得太好了,无法解决问题..

    听起来很好确实是..

    ..但是Chart 尝试使用Auto 设置显示许多项目,虽然它们通常工作正常,但在这里它们却不能,因为它们试图从x = 0 开始图表当然,2014-2016 的三个实际值会被挤压到无法识别的右侧。

    解决方法很简单:设置显示最小值:

    chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 2014;
    

    一切都很好。您可能想从 Points 中的 x 值计算该值,而且,万岁,您可以,因为您拥有它们..

    这是最好的方法,只要您的系列具有有意义的 X 值数字。

    不幸的是,第二个系列似乎没有那个..

    丑陋的替代方法是将年份转换为字符串,但是,除非你真的必须这样做,否则不要这样做!

    解决缩放问题后,您的代码的另一个大问题变得可见:

    您的数据映射有误。

    比较数据表和所需的输出,您的数据绑定根本不会映射到这样的图表。

    解决方案:您应该将数据拆分到与reasons 一样多的单独来源,即与Series 绑定。

    我将为每个reason 创建一个单独的DataViews,每个DataTable 都基于相同的Filter(原因='reason1'..),然后将每个DataView 绑定到一个Series.

    在我的脑海中,这就是它的样子:

    DataTable DT = yourTable;
    
    DataView dv1 = new DataView(DT);
    DataView dv2 = new DataView(DT);
    ..
    dv1.RowFilter = "reason=='Sold'";
    dv2.RowFilter = "reason=='Other'";
    ..
    yourSeries1.Points.DataBind(dv1, "year", "deathcount", "");
    ..
    

    现在所有Series DataPoints都以相同的方式绑定,所有Series都显示并且缩放是固定的。

    【讨论】:

    • 我按照你说的做了,但这是新的结果; link
    • 我没有谷歌驱动器密码。请使用可免费访问的网站或将其添加到问题中!
    • 对不起,我的错。试试this 一个。
    • 嗯,这有点好,不是吗。但系列 2 不见了。我想最简单的解决方案是选择 usgly 替代方案;我会更新答案。
    • 请不要考虑我想要的输出,x 轴上的年份以及不同颜色或系列的原因。所以我想我需要在图表上显示 4 个系列。就像我问题中的最后一张图片一样
    猜你喜欢
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多