在 mschart 中添加数据点时使用双标签

Double label while adding a datapoint in mschart

我正在用 C#.Net WinForms 编写代码以在单击图表上的某些数据点时添加标签。 在单击图表之前,图表看起来像这样。

现在我单击 330-340 之间的数据点。该图表显示了带有双标签 (338.61) 的选定数据点。如下所示:

下面是调试输出:

下面是 chart_mouseclick

的代码
private void chart1_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {               
        double mouse_Xvalue = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
        double mouse_Yvalue = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);

        DataPoint Prev_DataPoint = chart1.Series[0].Points.Select(x => x)
            .Where(x => x.XValue >= mouse_Xvalue)
            .DefaultIfEmpty(chart1.Series[0].Points.First()).First();

        DataPoint Next_DataPoint = chart1.Series[0].Points.Select(x => x)
            .Where(x => x.XValue <= mouse_Xvalue)
            .DefaultIfEmpty(chart1.Series[0].Points.Last()).Last();

        DataPoint Add_DataPoint = Math.Abs(Prev_DataPoint.XValue - mouse_Xvalue) < Math.Abs(Next_DataPoint.XValue - mouse_Xvalue) ? Prev_DataPoint : Next_DataPoint;

        int add_data_point_index = chart1.Series[0].Points.IndexOf(Add_DataPoint);

        DataPoint max = Add_DataPoint;
        for (int i = add_data_point_index - 10; i <= add_data_point_index + 10; i++)
        {
            DataPoint dp = chart1.Series[0].Points[i];

            if (dp.YValues[0] > max.YValues[0])
            {
                add_data_point_index = i;
                max = dp;
            }
        }

        chart1.Series[1].Points.Add(max);
        chart1.Series[1].Sort(PointSortOrder.Ascending, "X");

        for (int i = 0; i < chart1.Series[1].Points.Count; i++)
        {
            chart1.Series[1].Points[i].Label = 
            Math.Round(chart1.Series[1].Points[i].XValue, 2).ToString();
        }                 
    }
}

代码有什么问题?

这实际上是一个非常有趣的观察..

让我们看看第二个版本,它适合您:

chart1.Series[1].Points.AddXY(max.XValue, max.YValue[0])

或简而言之:

series1.Points.AddXY(x,y);

这是添加 DataPoints 的正常方法:新点 是使用两个(或更多)值以及从 [= 获取的所有其他属性创建的15=] 默认值.

'other' 属性包括 颜色、标记和标签数据,包括 IsValueShownAsLabel

这里没有惊喜。

现在为原始版本:

chart1.Series[1].Points.Add(max);

或简而言之

series1.Points.Add(dp);

其中max(或dp)是第一个系列(series0)中的DataPoints

这表现出惊人的不同..:[=​​25=]

可以想象 DataPoint 移动 (就像 Controls 那样),但事实并非如此。或者像字符串一样克隆。

相反,仅创建了一个新引用并将其添加到 series1.Points。这有几个令人惊讶的后果..:[=​​25=]

  • 两个引用都指向同一个数据点对象;所以突然在 series1 中有一个点具有从 series0 中获取的属性,包括 IsValueShownAsLabel!

  • 由于这两个系列现在都包含一个具有相同 values/coordinates 的数据点,因此该图表足够智能,可以稍微分开显示它们的标签以避免重叠。 这是你看到的效果

  • 如果您现在从其原始 series0 中删除数据点,series1 仍将包含对它的引用以及颜色、标签等,因为它在 series0..

因此确实无法使原始版本正常工作,因为对同一点的两次引用总是会使图表显示标签两次或根本不显示标签。