如何在指向某些数据的图表中添加箭头

时间:2016-08-10 10:36:45

标签: c# winforms charts

我目前正在开发一个模块来创建图表以显示数据。 我使用 System.Windows.Forms.DataVisualization.Charting.Chart

我有两条带状线显示我们得到的平均结果,另一条显示我们想要的结果。

到目前为止,我对自己拥有的东西感到非常满意,但我想添加明确的箭头来指出这些线条。我无法弄清楚如何做到这一点。

我看到Line Annotation可能会有所帮助,但我无法找到一种方法来做我想做的事。

以下是我想要做的一个例子:

enter image description here

2 个答案:

答案 0 :(得分:0)

您可以选择使用

  • 注释或
  • GDI +绘图

在这两种情况下,挑战都是让职位正确。

更自然的方法是使用Annotations,所以让我们首先看一下:

有各种类型,但功能不同;文字可以RectangleAnnotationTextAnnotation显示。线条和箭头只能由LineAnnotations显示。因此,我们需要为您的两行中的每一行提供一对Line - 加TextAnnotation

与许多其他图表元素一样,注释位于各自容器的百分比 ;这有时会使事情变得棘手。

要在图表右侧放置线条注释,您可以将其X属性设置为100;让它向左移动你将宽度设置为负数。问题是在那之后开始..

要找出ChartArea右边缘的位置,您需要对Pre- or PostPaint事件进行编码并使用ToRectangleF方法。

要找出y值,您需要从数据值计算它;为此,您可以使用转换为像素的AxisY.ValueToPixelPosition方法,您可以使用图表ClientArea以及ChartArea百分比大小来计算每个百分比。

复杂?对。如果你能锚定到某个Annotations,那么DataPoint可以更加简单易用;但你的不在ChartArea ..

这是一个在进行计算时应该有用的函数:

double PercentFromValue(Chart chart, ChartArea ca, double value)
{
    Axis ay = ca.AxisY;
    RectangleF car = ca.Position.ToRectangleF();
    double py = ay.ValueToPixelPosition(value);
    int caHeight = (int)(chart.ClientRectangle.Height * car.Height / 100f);
    return 100d * py / caHeight;
}

请注意,它仅在从Pre/PostPaint事件中调用时才能可靠地工作..

所以这是定位PrePaint

LineAnnotation lAnn事件的示例
private void chart1_PrePaint(object sender, ChartPaintEventArgs e)
{
    Rectangle cr = chart1.ClientRectangle;
    ChartArea ca = chart1.ChartAreas[0];
    RectangleF car = ca.Position.ToRectangleF();

    lAnn.Width = car.Width - lAnn.X;
    lAnn.Y =  PercentFromValue(chart1, ca, someDataValue);
}

插入有效的DataPoint Y值时,将设置起始y位置。您可以使用它,直到找到设置四个位置属性的良好组合。

在创建和添加四个(!)注释时,您可能希望保留类级别引用,因此您不必从Annotations集合中引用它们。

对于LineAnnotation,您需要使用EndCapStartCap设置线宽,颜色和大写样式:

lAnn.EndCap = LineAnchorCapStyle.Arrow;

GDI +绘图更直接,只要您知道要绘制线条和文本的位置。

它也在PrePaint事件中完成,再次使用ValueToPixelPosition查找两个数据行的像素位置。除此之外是Graphics.DrawLine的所有常见内容,PenStart- or EndCapGraphics.DrawString或者TextRenderer.DrawText ..

我坦率地不确定我会选择哪种方式..

答案 1 :(得分:0)

创建三角形图像并将标记图像设置为:

Chart1.Series.Points.AddXY(0, 10);
Chart1.Series.Points.AddXY(20,10);
Chart1.Series[0].Points[1].MarkerImage = "TriangleImage.bmp";
Chart1.Series[0].Points[1].MarkerImageTransparentColor = Color.White;

or
Chart1.Series[0].Points[1].MarkerStyle = MarkerStyle.Triangle;