|
■No98524 (ゆい さん) に返信
> If(sender Is Chart1, Label1, Label2)
> この意味も教えていただけませんか?
下記を 1 行で記したものです。
Dim dstLabel As Label
If sender Is Chart1 Then
dstLabel = Label1
Else
dstLabel = Label2
End If
> なぜ Chart1のみを指定するかも?
Chart1 と Chart2 という 2 種類に対するイベントハンドラーでしたので、
Else 句が Chart2 を意味することが必然であるためです。
> Option Strict On と ToString("N0") 初めて知りました。
データ型の曖昧さを防ぐため、自分は [ツール]-[オプション] の
[プロジェクトおよびソリューション]-[Visual Basic の既定値] から
Option Strict On を既定の設定としていたりします。
> もう一枚のチャート(Chart3)を追加して、それには罫線だけを引くにはどのようにすれば良いのでしょうか?
sender または e.Chart が Chart1 や Chart2 ならば Label に値を書き込み、
それが Chart3 だった時には、単に何もしなければ良いのでは?
書き方はいろいろとあろうかと思いますし、
VB のバージョンによって使用可能な文法も変わってくるわけですが、とりあえず一例として:
Option Strict On
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Private YLables As New Dictionary(Of Chart, Label)()
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
YLables.Add(Chart1, Label1)
YLables.Add(Chart2, Label2)
'YLables.Add(Chart3, Label3) 'Chart3 は値を拾わない
Dim dat As New DataTable()
dat.Columns.Add("件数", GetType(Integer))
dat.Columns.Add("数量", GetType(Integer))
For i = 10 To 50 Step 10
dat.Rows.Add(i, i * 10)
Next
dat.AcceptChanges()
For Each c In {Chart1, Chart2, Chart3}
c.DataSource = dat
c.Series.Clear()
With c.Series.Add("棒グラフ")
.ChartType = SeriesChartType.Column
.XValueMember = "件数"
.YValueMembers = "数量"
End With
Next
End Sub
Private Sub Charts_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Chart1.MouseMove, Chart2.MouseMove, Chart3.MouseMove
DirectCast(sender, Chart).Invalidate()
End Sub
Private Sub Charts_PostPaint(ByVal sender As Object, ByVal e As ChartPaintEventArgs) Handles Chart1.PostPaint, Chart2.PostPaint, Chart3.PostPaint
Dim mousePoint = e.Chart.PointToClient(MousePosition)
DrawCrossLine(e, mousePoint)
Dim yLabel As Label = Nothing
If YLables.TryGetValue(e.Chart, yLabel) Then
yLabel.Text = GetYValue(e.Chart.ChartAreas(0).AxisY, mousePoint.Y).ToString("N0")
End If
End Sub
Private Function GetYValue(yAxis As Axis, y As Integer) As Double
Dim y1 = yAxis.ValueToPixelPosition(yAxis.Maximum)
Dim y2 = yAxis.ValueToPixelPosition(yAxis.Minimum)
Return yAxis.Maximum - (yAxis.Maximum - yAxis.Minimum) * ((y - y1) / (y2 - y1))
End Function
Private Sub DrawCrossLine(e As ChartPaintEventArgs, mp As Point)
Dim axX = e.Chart.ChartAreas(0).AxisX
Dim axY = e.Chart.ChartAreas(0).AxisY
Dim x1 = axX.ValueToPixelPosition(axX.Minimum) 'グラフ領域左端のX座標
Dim x2 = axX.ValueToPixelPosition(axX.Maximum) 'グラフ領域右端のX座標
Dim y1 = axY.ValueToPixelPosition(axY.Maximum) 'グラフ領域上部のY座標
Dim y2 = axY.ValueToPixelPosition(axY.Minimum) 'グラフ領域下部のY座標
If mp.X >= x1 AndAlso mp.X <= x2 Then
'垂直線
e.ChartGraphics.Graphics.DrawLine(Pens.Green, mp.X, CSng(y1), mp.X, CSng(y2))
End If
If mp.Y >= y1 AndAlso mp.Y <= y2 Then
'水平線
e.ChartGraphics.Graphics.DrawLine(Pens.Green, CSng(x1), mp.Y, CSng(x2), mp.Y)
End If
End Sub
End Class
|