1

我的应用程序中有一个水平堆叠的条形图,我试图弄清楚当用户单击条形时如何获取 X 轴值。问题是当我在运行时查看值时,Y 值很好,但 X 值全为 0。

屏幕截图

在上图中,浅蓝色条来自Series[0]并代表 MTD 销售额,而较暗的条来自Series[1]去年同月的销售额。我的目标是当用户双击一个条形图时,他会被带到该销售人员的详细销售报告中。

我没有尝试将我的图表切换到常规条形图,因为这是我最终需要的样子。但我开始怀疑我在XValue字段中得到全 0 的原因是因为这个还是因为我使用字符串作为值的类型。

有没有人遇到过这个问题或有任何关于如何解决它的线索?

运行时点的屏幕截图

4

2 回答 2

0

您使用其中一种Bar图表类型。

与大多数普通类型相比,它们的 x 轴和 y 轴切换。

因此,为了获得沿水平轴的值,您实际上想要获取 y-values

要获得双击数据点的 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]);
    }
}

但是请注意,在堆积条形图中,值看起来是堆积的,但每个点仍然只有自己的值。

如果您想获得堆叠/汇总的值,则必须将下面的所有点相加,包括被击中的点。这里的“下方”是指位于同一 x 槽但在较低系列中的点!

如果您将 x 值添加为字符串,您将无法使用它们,因为在这种情况下,它们都将是0,正如您在屏幕截图中看到的那样。

但是由于您案例中的所有堆叠点都相同e.PointIndex,我们可以使用它来访问以下系列中的所有点..:

    ..
    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 值,你有两个选择:

  • 您可以将字符串显式添加到AxisLabel每个DataPoint. 0虽然现在仍然可以访问x 值AxisLabels

  • 或者您可以将它们添加为数字,也许使用一些方案map将字符串转换为数字并返回,然后再次设置AxisLabels.

于 2018-10-29T21:11:00.667 回答
0

好的,所以我终于设法使用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 轴更改XValueTypeDouble,并将idEmployeXValueMember更改为。

结果

如您所见,在图表上显示员工 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;
        }
    }

最后结果

我对结果很满意。现在,当我双击图表中的一个条形时,我可以从 X 值中获取员工 ID,并生成代码以获取该人在给定月份的详细销售报告。

于 2018-10-31T20:44:16.510 回答