使用图表鼠标悬停事件计算数据点位置

时间:2014-10-17 13:40:59

标签: excel-vba events charts vba excel

我在工作表上嵌入了一个图表(X,Y散点图)。我还在图表上有一个鼠标悬停事件 - 当您将鼠标悬停在数据点上时 - 将相应数据点的选定值打印到单元格。这适用于使用.GetChartElement方法。

但是,我还想添加一个功能,您可以添加连接数据点和预定义命名单元格的箭头(或线)。我也设法做到这一点,但不幸的是,我的计算不够精确,因为线的数据点末端从不是恰好在它周围的某个地方(见图)。

lines almost at the right place

我这样做的方式:

Private Sub myChartClass_MouseMove(ByVal Button As Long, ByVal Shift As Long, ByVal X As Long, ByVal Y As Long)

Me.myChartClass.GetChartElement X, Y, ElementID, Arg1, Arg2

Set chrt = ActiveSheet.ChartObjects(1).Chart
Set ser = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(1)

chart_data = ser.Values
chart_label = ser.XValues

YValue = chart_data(Arg2)
XValue = chart_label(Arg2)

'[Code to print corresponding values]

If addComment = True Then Call wks35.addComment(XValue, YValue)

这样我可以传递坐标(X,Y变量)和轴上的实际值(XValue,YValue)。以上,使用后者。

Public Sub addComment( _
                       ByVal X As Double, _
                       ByVal Y As Double _
           )

Dim chartObj As Chart
Dim chartWidth As Double
Dim chartHeight As Double
Dim l1 As Long, l2 As Long, r1 As Long, r2 As Long

With wks35

    Set chartObj = .ChartObjects(1).Chart

    chartWidth = chartObj.PlotArea.Width
    chartHeight = chartObj.PlotArea.Height

    Y = chartHeight - (chartHeight * ((Y - chartObj.Axes(xlValue).MinimumScale) _
    /(chartObj.Axes(xlValue).MaximumScale - chartObj.Axes(xlValue).MinimumScale)))
    X = chartWidth * ((X - chartObj.Axes(xlCategory).MinimumScale) / _
    (chartObj.Axes(xlCategory).MaximumScale - chartObj.Axes(xlCategory).MinimumScale))

    l1 = Range("Comment1").Left
    l2 = Range("Comment1").Top
    r1 = X + ActiveSheet.ChartObjects(1).Left + chartObj.PlotArea.InsideLeft
    r2 = Y + ActiveSheet.ChartObjects(1).Top + chartObj.PlotArea.InsideTop
    With ActiveSheet.Shapes.AddLine(l1, l2, r1, r2).Line
        .ForeColor.RGB = RGB(255, 0, 0)
    End With

End With

End Sub

所以基本上我的想法是在轴上设置值,并通过计算轴的最小值和最大值来计算其相对位置,从绘图区域的边界获得数据点的绝对顶部和左侧值。然后添加图表和plotarea的差异,然后添加图表的顶部和左侧。

可能需要很长时间才能遵循,但我感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

无论如何,我都明白了。

我用过这个

chartWidth = chartObj.PlotArea.InsideWidth
chartHeight = chartObj.PlotArea.InsideHeight

而不是

chartWidth = chartObj.PlotArea.Width
chartHeight = chartObj.PlotArea.Height

几乎就在那里,所以我添加了一些常量到最后(10到左,3到顶),这些线就在他们的位置。