图表注释:如何沿数据点的轴对齐注释 [英] Chart annotations: How can I align the annotation along an axis of a datapoint

查看:77
本文介绍了图表注释:如何沿数据点的轴对齐注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将注释与数据点对齐;我想垂直对齐注释。

I have aligned the annotations to data points; I want to align the annotations vertically.

我已经读过这篇文章,但无法弄清楚如何将图表宽度与数据点相关联。 https://msdn.microsoft.com/en-us/library/dd456731。 aspx

I have read this, But can't figure out how to relate the chart width to data points. https://msdn.microsoft.com/en-us/library/dd456731.aspx

然后: MS图表注释拒绝与鼠标位置对齐

到目前为止,我已经添加了一张图表图片

I added a picture of the chart so far as an example.

'create new chart
 chart1 = New DataVisualization.Charting.Chart

 'add chart areas
  chart1.ChartAreas.Add("NewChartArea")
  chart1.ChartAreas("NewChartArea").Area3DStyle.Enable3D = False
  chart1.ChartAreas("NewChartArea").AxisX.MajorGrid.Enabled = False 'turn chart background grid on and off
  chart1.ChartAreas("NewChartArea").AxisY.MajorGrid.Enabled = False 'turn chart background grid on and off
  chart1.ChartAreas("NewChartArea").AxisX.Title = "Activities of daily living" '----> title on the bottom for the x axis
  '[template] chart1.ChartAreas("NewChartArea").AxisX.LabelStyle.Angle = 45
  '[template] Chart1.Series(SeriesZeroChartName).Label = " my own label" ' -----> adds a label at the top of each bar

   For c As Integer = 2 To Me.DataGridViewResultsAdls.ColumnCount - 1

        Dim NextSeriesChartName As String
        NextSeriesChartName = DataGridViewResultsAdls.Columns(c).Name

        chart1.Series.Add(NextSeriesChartName)
        chart1.Series(NextSeriesChartName).ChartType = DataVisualization.Charting.SeriesChartType.Bar 'CHART CHANGER ******  change this value to change chart type
        chart1.Series(NextSeriesChartName).Points.Clear()
        chart1.Series(NextSeriesChartName).IsValueShownAsLabel = True '----> puts little labels ontop of each bar
        chart1.Series(NextSeriesChartName).SmartLabelStyle.Enabled = True


       ' fill each subsequent series with points
         For Count As Integer = 0 To DataGridViewResultsAdls.Rows.Count - 2
                Dim NextColumnName As String
                NextColumnName = DataGridViewResultsAdls.Columns(c).Name

                ' define X values
                Dim XLabelMyCustom As String
                XLabelMyCustom = DataGridViewResultsAdls.Item(0, Count).Value
                'define Y values
                Dim YLabelMyCustom As String
                YLabelMyCustom = DataGridViewResultsAdls.Item(NextColumnName, Count).Value

                ' add the point to the chart
                chart1.Series(NextSeriesChartName).Points.AddXY(XLabelMyCustom, YLabelMyCustom)

                ' create custom labels for the x axis
                chart1.ChartAreas("NewChartArea").AxisX.CustomLabels.Add(Count + 0.5, Count + 0.4 + 0.5, "Q2", 0, DataVisualization.Charting.LabelMarkStyle.None)
                chart1.ChartAreas("NewChartArea").AxisX.CustomLabels.Add(Count + 0.5 + 0.5, Count + 0.9 + 0.5, "Q1", 0, DataVisualization.Charting.LabelMarkStyle.None)
                chart1.ChartAreas("NewChartArea").AxisX.CustomLabels.Add(Count + 0.5, Count + 1, "Q3", 2, DataVisualization.Charting.LabelMarkStyle.LineSideMark)



                'Create a variable MyDataPoint to hold the current datapoint
                Dim MyDataPoint As DataPoint
                MyDataPoint = chart1.Series(NextSeriesChartName).Points(Count)
                'Create a new text annotation
                Dim MyTextAnnotation As TextAnnotation
                MyTextAnnotation = New TextAnnotation
                MyTextAnnotation.Text = "some notation"
                '[template] MyTextAnnotation.X =   <---- sets coordinates on screen for x
                '[template ]MyTextAnnotation.Y =   <---- sets coordinates on screen for y
                '[template] MyTextAnnotation.AnchorDataPoint = MyDataPoint  'sets the point where the notation will be
                '[template] chart1.Annotations.Add(MyTextAnnotation) ' adds the notation to the chart

                ' only add annotations to the chart once per series
                If c = 2 Then
                    MyTextAnnotation.AxisY = chart1.ChartAreas("NewChartArea").AxisY

                    ' [template] chart1.Series(NextSeriesChartName).Points.Item(Count).ToString  <--- output points to a string {x,y}


                    MyTextAnnotation.AnchorDataPoint = MyDataPoint  'sets the point where the notation will be
                    chart1.Annotations.Add(MyTextAnnotation) ' adds the notation to the chart
                    MyTextAnnotation.AnchorOffsetX = -10


                End If
            Next

        Next

        'Add chart to control and set dock to fill
        Me.PanelChartAdls.Controls.Add(chart1)
        chart1.Dock = DockStyle.Fill

    End If


推荐答案

图表控件中定位非常复杂。

Positioning in a Chart control is rather complex.

要从图表开始,具有三个坐标系:

To begin with a chart has three coordinate systems:


  • 数据值

  • 某个区域的百分比,最值得注意的是 ChartArea InnerPlotPosition

  • 图表控件的 ClientArea
  • $的像素b $ b
  • The data values
  • Percentages of some area, most notably the ChartArea and the InnerPlotPosition
  • Pixels of the Chart control's ClientArea

实现注释对齐的最简单方法是首先将每个锚定到其 DataPoint

The simplest way to achieve an alignment of your Annotations is to first anchor each to its DataPoint:

MyTextAnnotation.AnchorDataPoint = MyDataPoint 

接下来,您会将X位置覆盖为您喜欢的

Next you override the X-Position to a value you like:

MyTextAnnotation.X = someValue;

一些注意事项:


  • 默认中, Annotation.Position 会使用百分比 将其锚定到 DataPoint ,它使用代替。因此,使用 50 不会放在中间位置,而是所有位置都在右侧...

  • While by default the Annotation.Position would use percentages, after anchoring it to a DataPoint it uses the values instead. So using 50 would not place in somewhere around the middle but all to the right...

查看图表,建议使用 3


  • 如果您的值变化,则此位置也会变化。并且当您调整图表大小时,轴的大小也会随之调整,注释也会随之移动。

Btw:百分比与下一个外部容器: ChartAreas Chart.ClientRectangle InnerPlotPostion ChartArea ,并将每个元素停靠到容器中。.

Btw: The percentages are in relation to the next outer container: The ChartAreas to the Chart.ClientRectangle, the InnerPlotPostion to the ChartArea and each element to the container it is docked to..


  • 位置默认情况下设置为自动,因此其值为 NaN 。要访问(当前)值,可以调用 ElementPosition.ToRectangleF()

  • The Positions are by default set to automatic so their values are NaN. To access the (current) values you can call ElementPosition.ToRectangleF().

图表的轴上有几个函数可以转换值,像素和百分比位置。

Also note that there are several functions on the Chart's Axes that will convert values, pixels and percent-positions.

但是您需要找到有效的时刻来调用这些函数;如果图表的布局未完成,则它们将返回 null

However you need to find a valid moment to call those functions; if the Chart is not done with its layout, they will return null.

您可以安全地在三个 Paint 事件之一中调用它们,也可以响应用户的交互(例如Mouse事件)。

You can safely either call them in one of the three Paint events or in response to a user interaction like a Mouse event.

这里是如何使用它们将所有注释定位到(一定)固定像素位置:

Here is how to use them for positioning all Annotations to a (somewhat) fixed pixel position:

private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
    Axis AY = chart1.ChartAreas[0].AxisY;

    double pypx = AY.ValueToPosition(AY.PixelPositionToValue(30));

    foreach (TextAnnotation ta in chart1.Annotations)
    {
        ta.X = pypx;
    }
}

现在添加注释不会移动。至少不是很多;可以看到一些跳跃。

Now the Annotations will not move when the chart is resized or when the data values grow or shrink. At least not a lot; a few jumps can be seen. Either because I missed something or because of rounding issues.

但是我建议采用更简单的方法将其X位置设置为轴上的固定值。

But I suggest going with the simpler method of setting their X-Position to a fixed value on your axis..:

MyTextAnnotation.X = 3;

这会将它们置于您绘制的黄线。

This would put them at the yellow line you drew.

这篇关于图表注释:如何沿数据点的轴对齐注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆