我试图根据以下数据表在C#中动态创建条形图(这将改变,因此需要动态创建)。
这是我目前正在阅读的数据表: (未来的人:这些图像包含工作内容,我不想被解雇,所以我删除它们= O)
顶部表格是我添加系列(s24,s26,s27)数据的地方。第二个表格是我缩小它的地方并添加“Total”系列。
所以这是我试图绘制的列:
配置 - 这是我想要获得我的个人系列的地方:即:s24,s26,s27等。 HRC_Count - 这是我想要绘制的实际值 HRC_Description和HRC - 这些是Y轴的标签 Total_HRC_Count - 这是我的“Total”系列(图表上的黑条)
//get distinct Configs (to be added as Series in chart)
//this creates a dataview to parse for the series in the chart
DataView view = new DataView(dt);
DataTable distinctValues = new DataTable();
distinctValues = view.ToTable(true, "Config");
DataView dv = new DataView(distinctValues);
dv.Sort = "Config ASC";
DataTable dt_temp = new DataTable();
dt_temp = dv.ToTable();
distinctValues = dt_temp;
GraphDataNew(distinctValues);
然后我调用GraphDataNew并解析该系列的数据视图:
private void GraphDataNew(DataTable dt_distinct)
{
chart_new.Series.Clear();
foreach (DataRow row in dt_distinct.Rows)
{
string s = row["Config"].ToString();
chart_new.Series.Add(s);
chart_new.Series[s].ChartType = SeriesChartType.Bar;
chart_new.Series[s].IsValueShownAsLabel = true;
chart_new.Series[s].Sort(PointSortOrder.Ascending, "X");
chart_new.Series[s].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
chart_new.Series[s].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
}
所以现在我设置了系列(配置),现在我添加了实际数据:
DataView dv = new DataView(dt);
dv.Sort = "HRC_Description ASC, Config ASC"; // sort by description first, then config second
string HRC_Description = "";
string Config = "";
double HRC_Count = 0;
DataTable dt_temp = new DataTable();
dt_temp = dv.ToTable();
// add actual data
//loop through dt_temp and add datapoints and custom labels to chart
for (int x = 0; x < dt_temp.Rows.Count; x++)
{
HRC_Description = (dt_temp.Rows[x]["HRC_Description"].ToString().Trim());
Config = dt_temp.Rows[x]["Config"].ToString().Trim();
HRC_Count = Double.Parse(dt_temp.Rows[x]["HRC_Count"].ToString().Trim());
chart_new.Series[Config].Points.AddXY(HRC_Description, HRC_Count);
int y = chart_new.Series[Config].Points.Count;
chart_new.Series[Config].Points[y - 1].AxisLabel = HRC_Description;
}
然后我添加“Total”系列栏:
if (1==1) // fake condition for this question
{
chart_new.Series.Add("Total");
chart_new.Series["Total"].ChartType = SeriesChartType.Bar;
chart_new.Series["Total"].Color = Color.Black;
chart_new.Series["Total"].IsValueShownAsLabel = true;
chart_new.Series["Total"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
chart_new.Series["Total"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
DataView view1 = new DataView(dt_temp);
DataTable distinctValues1 = view1.ToTable(true, "HRC_Description", "Total_HRC_Count");
dt_temp = distinctValues1;
double Total_HRC_Count = 0;
for (int x = 0; x < dt_temp.Rows.Count; x++)
{
HRC_Description = (dt_temp.Rows[x]["HRC_Description"].ToString().Trim());
Total_HRC_Count = Double.Parse(dt_temp.Rows[x]["Total_HRC_Count"].ToString().Trim());
chart_new.Series["Total"].Points.AddXY(HRC_Description, Total_HRC_Count);
}
}
这是图表的样子: [![示例图表] [2]] [2]
但是,正如您在附图中看到的那样,我的数据全部关闭。有10个HRC_Description,但只有9个出现,一个重复。最重要的是,似乎每当我有超过2个系列时,数据就会混淆。有没有人有什么提示我可以做些什么来解决这个问题?这让我疯狂!谢谢!
答案 0 :(得分:1)
我无法完全分析您的数据,但我可以给您一个提示,这有助于解决您的问题:
我看到您添加了字符串的数据点作为 x值。
这没关系(好吧,不,不是真的)但是实际添加的数据点的x值确实是不是字符串而是 double 和它们都包含0
。
字符串只进入标签,而不是x值! (因此值丢失)
但是要将各个系列中的点组合在一起需要一些标准,并且因为x值不起作用(即使它们看起来确实如此),而是使用点的位置。哪些位置来自位置,即来自您添加的点的顺序和数字。
因此,只有这些栏会被组合在一起,这些栏被添加到相同的位置,并且因为没有真正的位置,所以添加它们的顺序就是重要的。
因此,在添加积分时,您需要确保始终使用相同的订单并永远不会留空点。如果系列中缺少值,则需要添加空虚拟点(设置其DataPoint.IsEmpty=true
)
容易出错..!
您可以通过检查每个系列中的数据点数来检查这是否是原因。如果它们不完全相同,这就是问题。
这是一个例子:注意第二个,黄色和第三个红色系列都是缺失的值,但是黄色的只是如何关闭;特别注意最后一点!
private void button17_Click(object sender, EventArgs e)
{
chart3.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
chart3.Series.Clear();
Series s1 = chart3.Series.Add("S1");
Series s2 = chart3.Series.Add("S2");
Series s3 = chart3.Series.Add("S3");
Random R = new Random(42);
s1.ChartType = SeriesChartType.Bar;
s2.ChartType = SeriesChartType.Bar;
s3.ChartType = SeriesChartType.Bar;
for (int i = 0; i < 10; i++)
{
// this series is complete..:
s1.Points.AddXY(i + "", R.Next(100));
int r = R.Next(5);
// this series misses some points..:
if (r==0) s2.Points.AddXY(i + "", R.Next(100));
// this series inserts empty points and so misses no points.:
if (r == 0) s3.Points.AddXY(i + "", R.Next(100));
else { int p = s3.Points.AddXY(i + "", R.Next(100)); s3.Points[p].IsEmpty = true; }
}
// now add a value at "10" for all series..;
s1.Points.AddXY("10", 100);
s2.Points.AddXY("10", 100);
s3.Points.AddXY("10", 100);
}