如何让用户在 MSChart 上创建注释?

How to let user create Annotations on MSChart?

如何在 运行 上创建注释以及如何使用 Annotation.BeginPlacement() 启用最终用户放置?我试过以多种方式做到这一点,但无法让它发挥作用。它应该在调用 BeginPlacement() 后实时呈现自己。

关于此主题的文档很少 none - 大部分 none - 所以我无法找到解决此问题的任何帮助。

到目前为止我尝试过的是创建一个注释并将其放置在 AnchorX/Y 中,将所有 Allow- 标志设置为 true 并在鼠标移动时调用 BeginPlacement(),但看不到注释在放置它时,它也不会相应地进入它的位置。例如,LineAnnotation 从正确的位置开始,但不会在我离开它的地方结束。当我移动它时,它从我的 ChartAreas {0,0} 开始,它将到达终点。

我想知道的是,何时以及如何使用这些工具?我想做的是让用户在图表上绘制注释并在分析图表时用作工具。

您需要计算正确的位置。请记住,MouseMove 不会为您提供位置(百分比)或值(数据),而是像素。您可以使用各种轴函数来转换它们。正式他们只在 xxxPaint 事件中工作,但在鼠标事件中他们也工作正常。

更新: 有两种锚定方式:

  • 通过使用“位置”,即百分比或 'Values',即数据值。

这是第一种的例子:

    LineAnnotation laNew = null;

    private void chart1_MouseDown(object sender, MouseEventArgs e)
    {
        if (cbx_drawAnnotation.Checked)
        {
            Axis ax = chart1.ChartAreas[0].AxisX;
            Axis ay = chart1.ChartAreas[0].AxisY;
            laNew = new LineAnnotation();
            chart1.Annotations.Add(laNew);
            double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X));
            double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y));
            laNew.X = vx;
            laNew.Y = vy;
        }
    }


    private void chart1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button.HasFlag(MouseButtons.Left) && cbx_drawAnnotation.Checked)
        {
            Axis ax = chart1.ChartAreas[0].AxisX;
            Axis ay = chart1.ChartAreas[0].AxisY;
            double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X))- laNew.X;
            double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y)) - laNew.Y;
            laNew.Width =  Math.Min(100, vx);
            laNew.Height =  Math.Min(100, vy);
            laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
            laNew.AllowMoving = true;  // optional
        }
    }

除非您需要以某种方式重新调整轴的比例,例如更改轴的最小值 and/or 最大值。

  • 如果您需要锚定数据值

首先我们需要将 AnnotationAxes 相关联,并将 IsSizeAlwaysRelative 设置为 false。然后我们可以计算锚点和大小值:

private void chart1_MouseDown(object sender, MouseEventArgs e)
{
    if (cbx_drawAnnotation.Checked)
    {
        Axis ax = chart1.ChartAreas[0].AxisX;
        Axis ay = chart1.ChartAreas[0].AxisY;
        laNew = new LineAnnotation();
        chart1.Annotations.Add(laNew);

        laNew.IsSizeAlwaysRelative = false;

        laNew.AxisX = ax;
        laNew.AxisY = ay;

        laNew.AnchorX = ax.PixelPositionToValue(e.X);
        laNew.AnchorY = ay.PixelPositionToValue(e.Y);

        laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
        laNew.AllowMoving = true;
    }
}


private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button.HasFlag(MouseButtons.Left) && cbx_drawAnnotation.Checked)
    {
        Axis ax = chart1.ChartAreas[0].AxisX;
        Axis ay = chart1.ChartAreas[0].AxisY;

        laNew.Width = ax.PixelPositionToValue(e.X) - laNew.AnchorX;   // values
        laNew.Height = ay.PixelPositionToValue(e.Y) - laNew.AnchorY;  
    }
}

请注意我现在如何缩放最大值并仍然调整图表的大小并且注释保留在数据点中..:[=​​23=]

更新: 要将行限制为 ChartArea 将此添加到 MouseDown 事件中的定义:

 laNew.ClipToChartArea = chart1.ChartAreas[0].Name;

为了防止异常离开图表,将其添加到 MouseMove 中的条件..:[=​​23=]

.. && chart1.ClientRectangle.Contains(e.Location)