C# 图表控件:对于系列中的所有点,水平条形图的 X 值为 0
C# Chart control : X value of a horizontal bar chart is 0 for all points in the serie
我的应用程序中有一个水平堆叠的条形图,我正在尝试了解如何在用户单击条形图时获取 X 轴值。问题是当我在运行时查看值时,Y 值很好但 X 值都是 0。
Screen capture
在上图中,浅蓝色条来自 Series[0]
,代表 MTD 销售额,来自 Series[1]
的深蓝色条代表去年同月的销售额。我的目标是,当用户双击某个栏时,他将被带到该销售人员的详细销售报告。
我还没有尝试将我的图表切换为常规条形图,因为这是我最终需要的样子。但是我开始怀疑我在 XValue
字段中得到全 0 的原因是因为这个还是因为我使用字符串作为值的类型。
有没有人遇到过这个问题或知道如何解决这个问题?
Screen capture of points at runtime
您使用了 Bar
种图表类型之一。
与大多数普通类型相比,它们的 x 轴和 y 轴切换。
因此,为了获得沿 水平 轴的值 ,您实际上想要获取 y 值。
要获得双击数据点的 y 值,您可以像下面的代码那样执行 HitTest:
private void chart1_MouseDoubleClick(object sender, MouseEventArgs e)
{
var hit = chart1.HitTest(e.X, e.Y, ChartElementType.DataPoint);
if (hit.PointIndex >= 0)
{
DataPoint dp = hit.Series.Points[hit.PointIndex];
Console.WriteLine(dp.YValues[0]);
}
}
但是请注意,在堆叠条形图中,值看起来是堆叠的,但每个点仍然只有自己的值。
如果您想获得 stacked/summed 向上值,您必须将以下所有点相加,包括被击中的点。 'Below' 这里表示点在同一个 x-slot 但在较低的系列中!
如果您将 x 值添加为字符串,您将无法使用它们,因为在这种情况下它们都将是 0
,如您在屏幕截图中所见。
但是由于您案例中的所有堆叠点都具有相同的 e.PointIndex
我们可以使用它来访问以下系列中的所有点..:[=22=]
..
int si = 0;
double vsum = 0;
Series s = null;
do
{
s = chart4.Series[si++];
vsum += s.Points[hit.PointIndex].YValues[0];
} while (hit.Series != s);
Console.WriteLine(vsum);
如果您真的想访问 x 值,您有两个选择:
您可以明确地将字符串添加到每个 DataPoint
的 AxisLabel
中。虽然 x 值仍将全部为 0
,但现在可以访问 AxisLabels
。
或者您可以将它们添加为数字,也许使用某种方案将字符串 map
转换为数字并返回,然后再次设置 AxisLabels
.
好的,所以我终于设法使用 Chart.Customize
事件在图表上放置了自定义标签。
这是我用于此图表的数据:
Vendeur | Total | idDepartement | idEmploye | TotalLastYear
Ghislain 5256.30 1 56 0.00
Kim 12568.42 1 1 74719.18
Philippe 17565.27 1 44 38454.85
我将 X 轴 XValueType
更改为 Double
,将 XValueMember
更改为 idEmploye。
Result
如您所见,在图表上显示员工 ID 对用户来说不是很友好。这是自定义事件有用的地方。
这是我的活动:
private void chart1_Customize(object sender, EventArgs e)
{
// Set X axis interval to 1, label will be centered (between 0.5 and 1.5)
chart1.ChartAreas[0].AxisX.Interval = 1;
double startOffset = 0.5;
double endOffset = 1.5;
chart1.ChartAreas[0].AxisX.CustomLabels.Clear();
// Cycle through chart Datapoints in first serie
foreach (System.Windows.Forms.DataVisualization.Charting.DataPoint pt in chart1.Series[0].Points)
{
// First get the dataset used for the chart (from its bindingsource)
DataSet dsSales = (DataSet)bsViewVentesParUtilisateurSignsMoisCourant.DataSource;
// Second get the datatable from that dataset based on the datamember
// property of the bindingsource
DataTable dtSales = (DataTable)dsSales.Tables[bsViewVentesParUtilisateurSignsMoisCourant.DataMember];
// Get a dataview and filter its result based on the current point's XValue
DataView dv = new DataView(dtSales);
dv.RowFilter = "idEmploye=" + pt.XValue.ToString();
// Get the "Salesperson" (or "Vendeur") column value from the first result
// (other rows will have the same value but row 0 is safe)
string firstname = dv.ToTable().Rows[0].Field<string>("Vendeur").ToString();
// Create new customlabel and add it to the X axis
CustomLabel salespersonLabel = new CustomLabel(startOffset, endOffset, firstname, 0, LabelMarkStyle.None);
chart1.ChartAreas[0].AxisX.CustomLabels.Add(salespersonLabel);
startOffset += 1;
endOffset += 1;
}
}
Final result
我对结果很满意。现在当我双击图表中的条形时,我可以从 X 值中获取员工 ID 并生成代码以获取该人在给定月份的详细销售报告。
我的应用程序中有一个水平堆叠的条形图,我正在尝试了解如何在用户单击条形图时获取 X 轴值。问题是当我在运行时查看值时,Y 值很好但 X 值都是 0。
Screen capture
在上图中,浅蓝色条来自 Series[0]
,代表 MTD 销售额,来自 Series[1]
的深蓝色条代表去年同月的销售额。我的目标是,当用户双击某个栏时,他将被带到该销售人员的详细销售报告。
我还没有尝试将我的图表切换为常规条形图,因为这是我最终需要的样子。但是我开始怀疑我在 XValue
字段中得到全 0 的原因是因为这个还是因为我使用字符串作为值的类型。
有没有人遇到过这个问题或知道如何解决这个问题?
Screen capture of points at runtime
您使用了 Bar
种图表类型之一。
与大多数普通类型相比,它们的 x 轴和 y 轴切换。
因此,为了获得沿 水平 轴的值 ,您实际上想要获取 y 值。
要获得双击数据点的 y 值,您可以像下面的代码那样执行 HitTest:
private void chart1_MouseDoubleClick(object sender, MouseEventArgs e)
{
var hit = chart1.HitTest(e.X, e.Y, ChartElementType.DataPoint);
if (hit.PointIndex >= 0)
{
DataPoint dp = hit.Series.Points[hit.PointIndex];
Console.WriteLine(dp.YValues[0]);
}
}
但是请注意,在堆叠条形图中,值看起来是堆叠的,但每个点仍然只有自己的值。
如果您想获得 stacked/summed 向上值,您必须将以下所有点相加,包括被击中的点。 'Below' 这里表示点在同一个 x-slot 但在较低的系列中!
如果您将 x 值添加为字符串,您将无法使用它们,因为在这种情况下它们都将是 0
,如您在屏幕截图中所见。
但是由于您案例中的所有堆叠点都具有相同的 e.PointIndex
我们可以使用它来访问以下系列中的所有点..:[=22=]
..
int si = 0;
double vsum = 0;
Series s = null;
do
{
s = chart4.Series[si++];
vsum += s.Points[hit.PointIndex].YValues[0];
} while (hit.Series != s);
Console.WriteLine(vsum);
如果您真的想访问 x 值,您有两个选择:
您可以明确地将字符串添加到每个
DataPoint
的AxisLabel
中。虽然 x 值仍将全部为0
,但现在可以访问AxisLabels
。或者您可以将它们添加为数字,也许使用某种方案将字符串
map
转换为数字并返回,然后再次设置AxisLabels
.
好的,所以我终于设法使用 Chart.Customize
事件在图表上放置了自定义标签。
这是我用于此图表的数据:
Vendeur | Total | idDepartement | idEmploye | TotalLastYear
Ghislain 5256.30 1 56 0.00
Kim 12568.42 1 1 74719.18
Philippe 17565.27 1 44 38454.85
我将 X 轴 XValueType
更改为 Double
,将 XValueMember
更改为 idEmploye。
Result
如您所见,在图表上显示员工 ID 对用户来说不是很友好。这是自定义事件有用的地方。
这是我的活动:
private void chart1_Customize(object sender, EventArgs e)
{
// Set X axis interval to 1, label will be centered (between 0.5 and 1.5)
chart1.ChartAreas[0].AxisX.Interval = 1;
double startOffset = 0.5;
double endOffset = 1.5;
chart1.ChartAreas[0].AxisX.CustomLabels.Clear();
// Cycle through chart Datapoints in first serie
foreach (System.Windows.Forms.DataVisualization.Charting.DataPoint pt in chart1.Series[0].Points)
{
// First get the dataset used for the chart (from its bindingsource)
DataSet dsSales = (DataSet)bsViewVentesParUtilisateurSignsMoisCourant.DataSource;
// Second get the datatable from that dataset based on the datamember
// property of the bindingsource
DataTable dtSales = (DataTable)dsSales.Tables[bsViewVentesParUtilisateurSignsMoisCourant.DataMember];
// Get a dataview and filter its result based on the current point's XValue
DataView dv = new DataView(dtSales);
dv.RowFilter = "idEmploye=" + pt.XValue.ToString();
// Get the "Salesperson" (or "Vendeur") column value from the first result
// (other rows will have the same value but row 0 is safe)
string firstname = dv.ToTable().Rows[0].Field<string>("Vendeur").ToString();
// Create new customlabel and add it to the X axis
CustomLabel salespersonLabel = new CustomLabel(startOffset, endOffset, firstname, 0, LabelMarkStyle.None);
chart1.ChartAreas[0].AxisX.CustomLabels.Add(salespersonLabel);
startOffset += 1;
endOffset += 1;
}
}
Final result
我对结果很满意。现在当我双击图表中的条形时,我可以从 X 值中获取员工 ID 并生成代码以获取该人在给定月份的详细销售报告。