Элемент управления C # Chart: значение X горизонтальной гистограммы равно 0 для всех точек серии - PullRequest
0 голосов
/ 29 октября 2018

У меня есть горизонтальная гистограмма в моем приложении, и я пытаюсь выяснить, как получить значение оси X, когда пользователь нажимает на гистограмму. Проблема в том, что когда я смотрю на значения во время выполнения, значения Y в порядке, но все значения X равны 0.

Снимок экрана

На изображении выше светло-голубые столбцы от Series[0] представляют продажи MTD, а более темные от Series[1] - прошлогодние продажи за тот же месяц. Моя цель состоит в том, чтобы, когда пользователь дважды щелкает по панели, он попадает в подробный отчет о продажах для этого продавца.

Я не пытался переключить свой график на обычную гистограмму, потому что это то, что мне нужно будет выглядеть в конце. Но я начинаю задаваться вопросом, причина того, почему я получаю все 0 в поле XValue, из-за этого или потому, что я использую строки в качестве типа значения.

Кто-нибудь когда-нибудь сталкивался с этим или есть какие-либо подсказки, как это исправить?

Снимок экрана точек во время выполнения

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

ОК, так что мне, наконец, удалось разместить пользовательские метки на графике с помощью события 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 .

Результат

Как видите, не очень удобно иметь идентификаторы сотрудников на графике. Вот где событие Customize становится полезным.

Вот мое событие:

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 и сгенерировать код, чтобы получить подробный отчет о продажах для этого человека за указанный месяц.

0 голосов
/ 30 октября 2018

Вы используете один из типов диаграмм 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]);
    }
}

Обратите внимание, что в столбце с накоплением значения выглядят сложенными, но каждая точка будет по-прежнему иметь только свое значение.

Если вы хотите получить сложенные / суммированные значения, вам нужно сложить все пункты ниже, включая тот, который был достигнут. «Ниже» здесь означает точки в том же 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. В то время как значения x будут все 0, теперь можно получить доступ к AxisLabels.

  • Или вы можете добавить их в виде чисел, возможно, используя некоторую схему для map строк в числах и обратно и снова установить AxisLabels.

...