C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 複数のChartでのマウス位置による数量表示


(過去ログ 171 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■98520 / inTopicNo.1)  複数のChartでのマウス位置による数量表示
  
□投稿者/ ゆい (22回)-(2021/11/27(Sat) 17:15:18)

分類:[VB.NET/VB2005 以降] 

お世話になっています。

VB2017です。
これを実行しますと、Chart1上にあるマウス(罫線)の位置に対しての数量がLabel1に表示もされます。
そこでこれと同じことを、もう一つのChart2、Label2にもしたいのですが、どのようにすれば良いのでしょうか?
このサンプルは大きくは変えずにお願いします。

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim dat As DataTable = New DataTable
        With dat.Columns
            .Add("件数", GetType(Integer))
            .Add("数量", GetType(Integer))
        End With
        For i = 10 To 50 Step 10
            dat.Rows.Add(i, i * 10)
        Next
        'Chart1
        Chart1.DataSource = dat
        Chart1.Series.Clear()
        Dim Column1 = Chart1.Series.Add("棒グラフ1")
        With Column1
            .ChartType = DataVisualization.Charting.SeriesChartType.Column
            .XValueMember = "件数"
            .YValueMembers = "数量"
        End With
        'Chart2
        Chart2.DataSource = dat
        Chart2.Series.Clear()
        Dim Column2 = Chart2.Series.Add("棒グラフ2")
        With Column2
            .ChartType = DataVisualization.Charting.SeriesChartType.Column
            .XValueMember = "件数"
            .YValueMembers = "数量"
        End With
    End Sub

    'Chart上にマウスがある時、Chartに罫線を引く
    Private Sub Charts_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Chart1.MouseMove
        Chart1.Invalidate()
    End Sub

    Private Sub Charts_PostPaint(ByVal sender As Object, ByVal e As DataVisualization.Charting.ChartPaintEventArgs) Handles Chart1.PostPaint
        DrawCrossLine(e)
    End Sub

    Private Sub DrawCrossLine(e As DataVisualization.Charting.ChartPaintEventArgs)
        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座標
        Dim mp = e.Chart.PointToClient(MousePosition)
        If mp.X >= x1 AndAlso mp.X <= x2 Then
            '垂直線
            e.ChartGraphics.Graphics.DrawLine(Pens.Green, mp.X, CInt(y1), mp.X, CInt(y2))
        End If
        If mp.Y >= y1 AndAlso mp.Y <= y2 Then
            '水平線
            e.ChartGraphics.Graphics.DrawLine(Pens.Green, CInt(x1), mp.Y, CInt(x2), mp.Y)
        End If
    End Sub

    'Chart1上にマウスがある時Label1に座標の数量を表示 
    Private Sub Chart1_PostPaint(ByVal sender As Object, ByVal e As System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs) Handles Chart1.PostPaint
        Dim g = e.ChartGraphics.Graphics
        Dim axx = Chart1.ChartAreas(0).AxisX
        Dim axy = Chart1.ChartAreas(0).AxisY
        Dim y1 = axy.ValueToPixelPosition(axy.Maximum)  'グラフ領域上部のY座標
        Dim y2 = axy.ValueToPixelPosition(axy.Minimum)  'グラフ領域下部のY座標
        '
        Dim YjikuMax As Integer, YjikuMin As Integer
        YjikuMin = Chart1.ChartAreas(0).AxisY.Minimum   'Y軸 最小数
        YjikuMax = Chart1.ChartAreas(0).AxisY.Maximum   'Y軸 最大数
        '
        Dim Pos As Point = Chart1.PointToClient(Windows.Forms.Cursor.Position)
        Dim ZaKa As Integer
        ZaKa = YjikuMax - (YjikuMax - YjikuMin) * ((Pos.Y - y1) / (y2 - y1))
        Label1.Text = ZaKa
    End Sub
End Class

引用返信 編集キー/
■98523 / inTopicNo.2)  Re[1]: 複数のChartでのマウス位置による数量表示
□投稿者/ 魔界の仮面弁士 (3227回)-(2021/11/27(Sat) 17:54:17)
No98520 (ゆい さん) に返信
> そこでこれと同じことを、もう一つのChart2、Label2にもしたいのですが、どのようにすれば良いのでしょうか?
> このサンプルは大きくは変えずにお願いします。

Option Strict On
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        Dim dat As New DataTable()
        With dat.Columns
            .Add("件数", GetType(Integer))
            .Add("数量", GetType(Integer))
        End With
        For i = 10 To 50 Step 10
            dat.Rows.Add(i, i * 10)
        Next
        'Chart1
        Chart1.DataSource = dat
        Chart1.Series.Clear()
        With Chart1.Series.Add("棒グラフ1")
            .ChartType = SeriesChartType.Column
            .XValueMember = "件数"
            .YValueMembers = "数量"
        End With
        'Chart2
        Chart2.DataSource = dat
        Chart2.Series.Clear()
        With Chart2.Series.Add("棒グラフ2")
            .ChartType = SeriesChartType.Column
            .XValueMember = "件数"
            .YValueMembers = "数量"
        End With
    End Sub

    'Chart上にマウスがある時、Chartに罫線を引く
    Private Sub Charts_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Chart1.MouseMove, Chart2.MouseMove
        DirectCast(sender, System.Windows.Forms.DataVisualization.Charting.Chart).Invalidate()
    End Sub

    Private Sub DrawCrossLine(e As ChartPaintEventArgs)
        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座標
        Dim mp = e.Chart.PointToClient(MousePosition)
        If mp.X >= x1 AndAlso mp.X <= x2 Then
            '垂直線
            e.ChartGraphics.Graphics.DrawLine(Pens.Green, mp.X, CInt(y1), mp.X, CInt(y2))
        End If
        If mp.Y >= y1 AndAlso mp.Y <= y2 Then
            '水平線
            e.ChartGraphics.Graphics.DrawLine(Pens.Green, CInt(x1), mp.Y, CInt(x2), mp.Y)
        End If
    End Sub

    Private Sub Charts_PostPaint(ByVal sender As Object, ByVal e As ChartPaintEventArgs) Handles Chart1.PostPaint, Chart2.PostPaint
        Dim srcChart = DirectCast(sender, Chart)
        Dim dstLabel = If(sender Is Chart1, Label1, Label2)

        DrawCrossLine(e)

        Dim axy = srcChart.ChartAreas(0).AxisY
        Dim y1 = axy.ValueToPixelPosition(axy.Maximum)  'グラフ領域上部のY座標
        Dim y2 = axy.ValueToPixelPosition(axy.Minimum)  'グラフ領域下部のY座標
        '
        Dim YjikuMax = axy.Maximum   'Y軸 最大数
        Dim YjikuMin = axy.Minimum   'Y軸 最小数
        '
        Dim Pos = srcChart.PointToClient(System.Windows.Forms.Cursor.Position)
        Dim ZaKa = YjikuMax - (YjikuMax - YjikuMin) * ((Pos.Y - y1) / (y2 - y1))
        dstLabel.Text = ZaKa.ToString("N0")
    End Sub

End Class

引用返信 編集キー/
■98524 / inTopicNo.3)  Re[2]: 複数のChartでのマウス位置による数量表示
□投稿者/ ゆい (23回)-(2021/11/28(Sun) 16:05:37)
No98523 (魔界の仮面弁士 さん) に返信

すみません、もう少しお願いします。

もう一枚のチャート(Chart3)を追加して、それには罫線だけを引くにはどのようにすれば良いのでしょうか?
下のようにしのではLabel2にChart3の数量が反映もされます。
 Private Sub Charts_PostPaint(ByVal sender As Object, ByVal e As DataVisualization.Charting.ChartPaintEventArgs) Handles Chart1.PostPaint, Chart2.PostPaint, Chart3.PostPaint

 If(sender Is Chart1, Label1, Label2)
この意味も教えていただけませんか?
なぜ Chart1のみを指定するかも?  

Option Strict On と ToString("N0") 初めて知りました。
ありがとうございます。

引用返信 編集キー/
■98525 / inTopicNo.4)  Re[3]: 複数のChartでのマウス位置による数量表示
□投稿者/ 魔界の仮面弁士 (3228回)-(2021/11/28(Sun) 23:36:42)
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

引用返信 編集キー/
■98541 / inTopicNo.5)  Re[4]: 複数のChartでのマウス位置による数量表示
□投稿者/ ゆい (24回)-(2021/11/29(Mon) 22:45:25)
No98525 (魔界の仮面弁士 さん) に返信

ありがとうございます。

> VB のバージョンによって使用可能な文法も変わってくるわけですが、
そうなんですよね、色んな新しい書き方などもあるようなのですが、
VBも必要な時にちょこっと使う者にとっては、
例え古めかしくとも分かり易くが本当に有難いとこもあるのです。
すみません、勝手なことばかり言ってます。

この度も本当にありがとうございました。
上手く動くようになりました。
うれしかったです。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -