从数据表绘制图表

时间:2015-11-07 21:34:20

标签: c# charts datatable

我正在尝试绘制一个包含多个系列的图表。它的数据来自数据库,通过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 with the sql output

当我尝试将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();

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

output

但我希望输出看起来像这样;

actual output

我尝试过谷歌而没有成功。有人可以帮我这个吗? 我非常感激。 感谢

1 个答案:

答案 0 :(得分:1)

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

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

<强>简介

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

但是如果添加无法转换为数字的类型(如字符串),事情会变得奇怪。 内部 X值均为0,因为除了标签显示字符串外,还有什么其他内容。

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

许多新手看起来很好,他们从来不知道他们有效地<强>丢失了 X值。

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

您的问题

你的“问题”是你的select提供了来自DATEPART功能的整数,所以你做对了,事实上你做得太好了,无法解决这个问题。

听起来很完美而且 ..

..但Chart尝试使用Auto设置显示多个项目,而通常工作正常,此处他们没有,因为他们尝试启动图表在x = 0,当然2014-2016的三个实际值被挤到右边,无法识别。

解决方案很简单:将显示最小值设置为:

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

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

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

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

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

修复了缩放问题后,您的代码的另一个大问题变得可见:

您的数据映射错误。

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

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

我会为每个DataViews创建一个单独的reason,每个DataTable基于相同的Filter,但具有不同的DataView(reason ='reason1'..)和然后将每个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都以相同方式绑定,所有multiDexEnabled true都会显示,缩放也是固定的。