none
Visual Basic 2010 グラフ(Chartコントロール)でX軸を日付時刻型で設定する方法 RRS feed

  • 質問

  • Visual Studio 2010を初めてから一通りのプログラムを作成できたのですが、グラフ表示設定で煮詰まっています。

    あるファイル内に保存されているデータを全て読み込み、変化グラフ(折れ線グラフ)に読み込んだデータを表示するグラフを

    以下のように作成しました。

    [Form2.vp]作成 ===================================================
    ・使用変数・
     全保存データ数                  → AllMax (as Long)
     保存データの計測データ項目数  → CalcMax (as Integer)....グラフにPLOTするデータ数
     読込保存データ→ cdt(AllMax)構造体
        .YMD............日付(as String "yyyy/MM/dd")
        .Hns............時刻(as String "hh:mm:00")
        .Calc(CalcMax)..計測データ値(as String)
    ・コントロール類・
      Form2デザイン上にMSChartコントロールを使用。
    ・MSChartコントロールの設定・
      2軸の折れ線グラフ→ X軸:計測データ数(0~AllMax) / Y軸:計測データ値
    ・コード・
    「Form2.vp」内
    Imports System.Windows.Forms.DataVisualization.Charting
    Public Class Form2
        '   
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '初期化
            Chart1.Series.Clear()

            'データの設定
            Dim ds As DataSet = Getdata()

            'コントロールにデータソースを設定
            Chart1.DataSource = ds
            Chart1.Titles.Add("[ 計測データ ]")

            'グラフPLOT
            For i As Integer = 1 To ds.Tables(0).Columns.Count - 1
                Dim columnName As String = ds.Tables(0).Columns(i).ColumnName
                Chart1.Series.Add(columnName)                                                  '凡例表示項目名
                Chart1.Series(columnName).ChartType = SeriesChartType.Line      'グラフタイプ
                'X軸(データ)
                Chart1.Series(columnName).XValueMember = ds.Tables(0).Columns(0).ColumnName.ToString
                Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = True
                Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
                'Y軸(データ値)
                Chart1.Series(columnName).YValueMembers = columnName
            Next i
            '
            Chart1.ChartAreas(0).AxisX.Title = "日付"
            Chart1.DataBind()

        End Sub
        'データの設定'//////////////////////////////
        Private Function Getdata() As DataSet
            Dim ds As New DataSet
            Dim dt As New DataTable
            Dim dtRow As DataRow
            Dim i As Integer
            Dim ss As Long = 0

            dt.Columns.Add("日付", Type.GetType("System.String"))
            '凡例項目セット(データ項目)
            For i = 1 To CalcMax
                dt.Columns.Add("計測値" & i, Type.GetType("System.Single"))
            Next i
            ds.Tables.Add(dt)

            'データセット--------------------------------------------------
            For ss = 1 To AllMax
                dtRow = ds.Tables(0).NewRow
                'X軸日付セット
                Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns        'ここで文字列を"yyyy/MM/dd HH:mm:ss"にする.
                Dim xYMD As DateTime = DateTime.Parse(Xdt1)             ←①ここでDataTime型に変換
                dtRow(0) = Format(xYMD, "yy/MM/dd")
                'X軸データセット
                For i = 1 To CalcMax
                    dtRow(i) = Cdt(ss).Calc(i)
                Next i
                ds.Tables(0).Rows.Add(dtRow)
            Next ss
            '----------------------------------------------------------
            Return (ds)

        End Function
    End Class
    =============================================================

    上のコードで、グラフX軸の設定を "計測データ数(Long型)"→日付値 "①の変数(DataTime型)"に変更させたいのですけれど、日付時刻値の

    操作[Axis.IntervalOffset・Axis.InterOffSetType]等、調べてはいるんですけど...どのように変更させればいいのかで、先に進んでいません。
    グラフもMSChartコントロールを変更せずに行おうとしています。データの時刻は分までで、秒は無く"hh:mm:00"になります。
    最終的このグラフを発展させて、[カレンダーコントロールを使用→出力範囲を指定→範囲内にデータを出力させる]ものを作りたいのですけど..

    2012年7月6日 4:49

回答

  • ここで、範囲をForm1で設定した開始日(sPlotymd)、終了日(ePlotymd)の範囲で計測データを表示させたいので、以下の変更を行った所で現状煮詰まっています。
    X軸の指定範囲がDateTime型。その範囲内で計測データを表示する。データがあるかないかの判定は、①で計測日付時刻文字列を変数DateTime型に変換して判定させる。日付DateTime型→Double型に変換でカウントにするとかWEB上ではいろいろ調べてはいるんですが

    (日付、時間軸のカウントって難しいです....RowFilterの使用法も参考にします)。

    まずはX軸にする日付列を文字列のString型の列ではなくDateTime型の列にしましょう。
    (文字列が日時だとは自動で判断してはくれません。)
    そうすればChartはX軸を日付で範囲指定可能になりますし、DataViewのRowFilterで範囲指定することもできます。
    この場合、X軸のラベルに年月日の書式設定が必要であればAxisX.LabelStyle.Formatで書式を指定できます。

    次にX軸の範囲を指定するのにAxisX.Minimum,MaximumがDouble型しか入らないので困っているのですよね?
    ここはDateTime型のToOADate()メソッドでDouble型に変換できます。
    これで得られるDouble型は整数部が1989/12/30からの経過日数です。
    小数部は1日の内の時刻になります。(0.25が6時,0.5が12時,0.75が18時)
    このDouble値によりChartは日付型の軸を範囲指定することが可能になります。

    あと、Form2を表示した後で範囲を変更しない場合には、日時が範囲内の場合のみDataTable.Rows.Addするようにすれば処理を軽くできます。
    この場合はDataViewのRowFilterを使わなくてもDataTableをDataSourceにすることが可能です。

    Public Class Form2
        Inherits System.Windows.Forms.Form
        '実際にはForm1から設定する
        Public AllMax As Integer = 100
        Public CalcMax As Integer = 5
        Public sPlotymd As DateTime = DateTime.Now
        Public ePlotymd As DateTime = DateTime.Now
        'public Cdt() As Cdt
        Private view As DataView
        'Private Chart1 As Chart
        'Private WithEvents DateTimePicker1 As DateTimePicker
        'Private WithEvents DateTimePicker2 As DateTimePicker
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
            '初期化
            Chart1.Series.Clear()
            'データの設定
            Dim ds As DataSet = Getdata()
            'コントロールにデータソースを設定
            Chart1.Titles.Add("[ 計測データ ]")
            'グラフPLOT
            For i As Integer = 1 To ds.Tables(0).Columns.Count - 1
                Dim columnName As String = ds.Tables(0).Columns(i).ColumnName
                Chart1.Series.Add(columnName)                                                  '凡例表示項目名
                Chart1.Series(columnName).ChartType = SeriesChartType.Line      'グラフタイプ
                'X軸(データ)
                Chart1.Series(columnName).XValueMember = ds.Tables(0).Columns(0).ColumnName.ToString
                Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = True
                Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
                Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "yyyy/MM/dd HH:mm"
                'Y軸(データ値)
                Chart1.Series(columnName).YValueMembers = columnName
            Next i
            '
            Chart1.ChartAreas(0).AxisX.Title = "日付"
            'DataTableではなくDataViewをソースにする
            view = New DataView(ds.Tables(0))
            '描画範囲を指定
            UpdateRange(view, sPlotymd, ePlotymd)
        End Sub
        'データの設定'//////////////////////////////
        Private Function Getdata() As DataSet
            Dim ds As New DataSet
            Dim dt As New DataTable
            Dim dtRow As DataRow
            Dim i As Integer
            Dim ss As Integer = 0
            dt.Columns.Add("日付", GetType(DateTime)) 'string -> DateTime
            '凡例項目セット(データ項目)
            For i = 1 To CalcMax
                dt.Columns.Add("計測値" & i, GetType(Single))
            Next i
            ds.Tables.Add(dt)
            Dim rnd As New Random
            'データセット--------------------------------------------------
            For ss = 1 To AllMax
                'X軸日付セット
                'Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns        'ここで文字列を"yyyy/MM/dd HH:mm:ss"にする.
                'Dim xYMD As DateTime = DateTime.Parse(Xdt1)             '←①ここでDataTime型に変換
                Dim xYMD As DateTime = DateTime.Now.AddHours(ss)
                'If(Me.sPlotymd <= xYMD && xYMD < Me.ePlotymd) then '不要なデータを除外するならここで判定
                'X軸データセット
                dtRow = ds.Tables(0).NewRow
                dtRow(0) = xYMD 'わざわざ文字列形にせずにDateTime型のままDataRowに格納する
                For i = 1 To CalcMax
                    dtRow(i) = CSng(rnd.Next()) 'ダミーのデータを格納
                Next i
                ds.Tables(0).Rows.Add(dtRow)
            Next ss
            '----------------------------------------------------------
            Return (ds)
        End Function
        ''' <summary> 2個のDateTimePickerの日付の間をRowFilterで抽出 </summary>
        Private Sub DateTimePicker_ValueChanged(sender As System.Object, e As System.EventArgs) _
            Handles DateTimePicker1.ValueChanged, DateTimePicker2.ValueChanged
            sPlotymd = DateTimePicker1.Value
            ePlotymd = DateTimePicker2.Value
            UpdateRange(Me.view, sPlotymd, ePlotymd)
        End Sub
        Private Sub UpdateRange(ByVal view As DataView, ByVal sPlotymd As DateTime, ByVal ePlotymd As DateTime)
            Dim dt1 As DateTime = sPlotymd
            Dim dt2 As DateTime = ePlotymd
            If (dt2 < dt1) Then
                Dim temp As DateTime
                temp = dt1
                dt1 = dt2
                dt2 = temp
            End If
            dt1 = dt1.Date
            dt2 = dt2.Date.AddDays(1)
            view.RowFilter = "日付>='" & dt1.ToLongDateString() & "' and 日付<'" & dt2.ToLongDateString() & "'"
            'X軸の表示範囲を設定する
            Dim ax As System.Windows.Forms.DataVisualization.Charting.Axis = Chart1.ChartAreas(0).AxisX
            ax.Minimum = dt1.ToOADate
            ax.Maximum = dt2.ToOADate
            If (dt2.Subtract(dt1).TotalDays = 1) Then
                ax.Interval = 1 / 6 '範囲が1日の場合のみ4時間おきに縦線
            Else
                ax.Interval = 0 'それ以外は自動
            End If
            '表示更新
            Me.Chart1.DataSource = view
            Me.Chart1.DataBind()
        End Sub
    End Class

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク K's 2012年7月10日 9:13
    2012年7月9日 10:07

すべての返信

  • 「日付範囲を指定して、その範囲のみのグラフを書きたい」ってことですよね

    Imports System.Windows.Forms.DataVisualization.Charting
    'Public Structure Cdt
    '    Public YMD As String
    '    Public Hns As String
    '    Public Calc() As String
    'End Structure
    Public Class Form1
        Inherits System.Windows.Forms.Form
        Private AllMax As Integer = 100
        Private CalcMax As Integer = 5
        'Private Cdt() As Cdt
        Private view As DataView
        'Private Chart1 As Chart
        'Private WithEvents DateTimePicker1 As DateTimePicker
        'Private WithEvents DateTimePicker2 As DateTimePicker
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '初期化
            Chart1.Series.Clear()
            'データの設定
            Dim ds As DataSet = Getdata()
            'コントロールにデータソースを設定
            Chart1.Titles.Add("[ 計測データ ]")
            'グラフPLOT
            For i As Integer = 1 To ds.Tables(0).Columns.Count - 1
                Dim columnName As String = ds.Tables(0).Columns(i).ColumnName
                Chart1.Series.Add(columnName)                                                  '凡例表示項目名
                Chart1.Series(columnName).ChartType = SeriesChartType.Line      'グラフタイプ
                'X軸(データ)
                Chart1.Series(columnName).XValueMember = ds.Tables(0).Columns(0).ColumnName.ToString
                Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = True
                Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
                Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "yyyy/MM/dd HH:mm"
                'Y軸(データ値)
                Chart1.Series(columnName).YValueMembers = columnName
            Next i
            '
            Chart1.ChartAreas(0).AxisX.Title = "日付"
            'DataTableではなくDataViewをソースにする
            view = New DataView(ds.Tables(0))
            Chart1.DataSource = view
            Chart1.DataBind()
        End Sub
        'データの設定'//////////////////////////////
        Private Function Getdata() As DataSet
            Dim ds As New DataSet
            Dim dt As New DataTable
            Dim dtRow As DataRow
            Dim i As Integer
            Dim ss As Integer = 0
            dt.Columns.Add("日付", GetType(System.DateTime)) 'string -> DateTime
            '凡例項目セット(データ項目)
            For i = 1 To CalcMax
                dt.Columns.Add("計測値" & i, Type.GetType("System.Single"))
            Next i
            ds.Tables.Add(dt)
            Dim rnd As New Random
            'データセット--------------------------------------------------
            For ss = 1 To AllMax
                dtRow = ds.Tables(0).NewRow
                'X軸日付セット
                'Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns        'ここで文字列を"yyyy/MM/dd HH:mm:ss"にする.
                'Dim xYMD As DateTime = DateTime.Parse(Xdt1)             '←①ここでDataTime型に変換
                Dim xYMD As DateTime = DateTime.Now.AddHours(ss)
                dtRow(0) = xYMD 'わざわざ文字列形にせずにDateTime型のままDataRowに格納する
                'X軸データセット
                For i = 1 To CalcMax
                    dtRow(i) = CSng(rnd.Next()) 'ダミーのデータを格納
                Next i
                ds.Tables(0).Rows.Add(dtRow)
            Next ss
            '----------------------------------------------------------
            Return (ds)
        End Function
        ''' <summary> 2個のDateTimePickerの日付の間をRowFilterで抽出 </summary>
        Private Sub DateTimePicker_ValueChanged(sender As System.Object, e As System.EventArgs) _
            Handles DateTimePicker1.ValueChanged, DateTimePicker2.ValueChanged
            Dim dt1 As DateTime = DateTimePicker1.Value
            Dim dt2 As DateTime = DateTimePicker2.Value
            If (dt2 < dt1) Then
                Dim temp As DateTime
                temp = dt1
                dt1 = dt2
                dt2 = temp
            End If
            dt1 = dt1.Date
            dt2 = dt2.Date.AddDays(1)
            view.RowFilter = "日付>='" & dt1.ToLongDateString() & "' and 日付<'" & dt2.ToLongDateString() & "'"
            '表示更新
            Me.Chart1.DataSource = view
            Me.Chart1.DataBind()
        End Sub
    End Class

    #「~ですけど」ばかりで、何がわからなくて、何がやりたいことなのかが伝わってこないのですよ。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2012年7月6日 11:04
  • 「日付範囲を指定して、その範囲のみのグラフを書きたい」ってことですよね

    #「~ですけど」ばかりで、何がわからなくて、何がやりたいことなのかが伝わってこないのですよ。

    gekkaさん「すいませんでした!!”日付範囲を指定して、その範囲のみのグラフを書きたい”です!

    もっと細かくやりたい事を説明します!!」

    ----------------------------------------------------------------------------------------------------

    目的:1つのcsvファイル内のデータを全て読み込み、出力範囲を指定して計測データを時系列のグラフに出力。

    ----------------------------------------------------------------------------------------------------

    プログラム→Form1(グラフ出力範囲設定)→Form2(グラフの出力)

    Form1.vpの処理→[csvファイル内の全データをて読み込み処理、グラフの開始日付、終了日付の設定]

    < Form2.vp(作成中)の内容> ------------------------------------------------

    ・グラフ表示→System.Windows.Forms.DataVisualization.Charting使用

    [使用変数]

    ・グラフ表示計測データ数→Form1内で設定:CalcMax(as Integer)

    ・データ件数→Form1内で設定:AllMax(as Long)

    ・読み込みcsv計測データ定義:Form1内で定義/////

     Public Structure CsvAll
          Public Rmax As String
          Public Ymd As String       ←"yyyy/mm/dd"→ 日付データ(グラフで使用)
          Public Hns As String        ←"hh:nn:ss"     → 時間データ(グラフで使用)
          Public Calc(CalcMax) As String     '測定データ(グラフで使用)
    End Structure

    Public Cdt(AllMax) As CsvAll 

    //////////////////////////////////////////////////

    ・グラフ出力開始日=sPlotymd(as DateTime)→ Form1で取得
    ・グラフ出力終了日=ePlotymd(as DateTime)→ Form1で取得
    ---------------------------------------------------------------------------------

    * 作成中のForm2では、Form1でのグラフの出力範囲設定に関係なくただ読み込んだ

       データ全てを出力させています*

    (以下は前記述コードとほぼ同じForm2.vbのコードです)

    ==============================================

    Imports System.Windows.Forms.DataVisualization.Charting
    Public Class Form2

        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            '初期化
            Chart1.Series.Clear()
            'データの取得
            Dim ds As DataSet = Getdata()

            'Chartコントロールにデータソースを設定
            Chart1.DataSource = ds
            Chart1.Titles.Add("[ 計測生データ ]")

            'グラフの設定
            For i As Integer = 1 To ds.Tables(0).Columns.Count - 1
                Dim columnName As String = ds.Tables(0).Columns(i).ColumnName
                '凡例設定
                Chart1.Series.Add(columnName)           '凡例表示項目名
                Chart1.Series(columnName).ChartType = SeriesChartType.Line
                'X軸
                Chart1.Series(columnName).XValueMember = ds.Tables(0).Columns(0).ColumnName.ToString
                Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = True
                Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
                'Y軸
                Chart1.Series(columnName).YValueMembers = columnName
            Next i
            '
            Chart1.ChartAreas(0).AxisX.Title = "日付"
            Chart1.DataBind()

        End Sub

        Private Function Getdata() As DataSet
            Dim ds As New DataSet
            Dim dt As New DataTable
            Dim dtRow As DataRow
            Dim i As Integer
            Dim ss As Long = 0

            '列の作成
            dt.Columns.Add("日付", Type.GetType("System.String"))
            '凡例セット
            For i = 1 To CalcMax
                dt.Columns.Add("計測値" & i, Type.GetType("System.Single"))
            Next i
            ds.Tables.Add(dt)

            'PLOTデータセット
            For ss = 1 To AllMax
                dtRow = ds.Tables(0).NewRow
                'X軸日付セット
                '計測データの日付と時刻情報が分裂しているため年月日時刻型にセット
                Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns
                '年月日時刻型→DateTime型に
                Dim xYMD As DateTime = DateTime.Parse(Xdt1)  ............①
                dtRow(0) = Format(xYMD, "yy/MM/dd")
                'X軸データセット(計測データ)
                For i = 1 To CalcMax
                    dtRow(i) = Cdt(ss).Calc(i)
                Next i
                ds.Tables(0).Rows.Add(dtRow)
            Next ss
            Return (ds)

        End Function
    End Class

    ==============================================

    Form2のグラフ出力はできたので、これからForm1で設定した開始日付と終了日付範囲の

    出力グラフに変更させるのですが、現状のX軸はただ件数全部を表示しているだけなので、

    AllMaxぶんですみます。ここで、範囲をForm1で設定した開始日(sPlotymd)、終了日(ePlotymd)

    の範囲で計測データを表示させたいので、以下の変更を行った所で現状煮詰まっています。

    X軸の指定範囲がDateTime型。その範囲内で計測データを表示する。データがあるかないかの

    判定は、①で計測日付時刻文字列を変数DateTime型に変換して判定させる。日付DateTime型

    →Double型に変換でカウントにするとかWEB上ではいろいろ調べてはいるんですが

    (日付、時間軸のカウントって難しいです....RowFilterの使用法も参考にします)。

    2012年7月9日 4:22
  • ここで、範囲をForm1で設定した開始日(sPlotymd)、終了日(ePlotymd)の範囲で計測データを表示させたいので、以下の変更を行った所で現状煮詰まっています。
    X軸の指定範囲がDateTime型。その範囲内で計測データを表示する。データがあるかないかの判定は、①で計測日付時刻文字列を変数DateTime型に変換して判定させる。日付DateTime型→Double型に変換でカウントにするとかWEB上ではいろいろ調べてはいるんですが

    (日付、時間軸のカウントって難しいです....RowFilterの使用法も参考にします)。

    まずはX軸にする日付列を文字列のString型の列ではなくDateTime型の列にしましょう。
    (文字列が日時だとは自動で判断してはくれません。)
    そうすればChartはX軸を日付で範囲指定可能になりますし、DataViewのRowFilterで範囲指定することもできます。
    この場合、X軸のラベルに年月日の書式設定が必要であればAxisX.LabelStyle.Formatで書式を指定できます。

    次にX軸の範囲を指定するのにAxisX.Minimum,MaximumがDouble型しか入らないので困っているのですよね?
    ここはDateTime型のToOADate()メソッドでDouble型に変換できます。
    これで得られるDouble型は整数部が1989/12/30からの経過日数です。
    小数部は1日の内の時刻になります。(0.25が6時,0.5が12時,0.75が18時)
    このDouble値によりChartは日付型の軸を範囲指定することが可能になります。

    あと、Form2を表示した後で範囲を変更しない場合には、日時が範囲内の場合のみDataTable.Rows.Addするようにすれば処理を軽くできます。
    この場合はDataViewのRowFilterを使わなくてもDataTableをDataSourceにすることが可能です。

    Public Class Form2
        Inherits System.Windows.Forms.Form
        '実際にはForm1から設定する
        Public AllMax As Integer = 100
        Public CalcMax As Integer = 5
        Public sPlotymd As DateTime = DateTime.Now
        Public ePlotymd As DateTime = DateTime.Now
        'public Cdt() As Cdt
        Private view As DataView
        'Private Chart1 As Chart
        'Private WithEvents DateTimePicker1 As DateTimePicker
        'Private WithEvents DateTimePicker2 As DateTimePicker
        Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
            '初期化
            Chart1.Series.Clear()
            'データの設定
            Dim ds As DataSet = Getdata()
            'コントロールにデータソースを設定
            Chart1.Titles.Add("[ 計測データ ]")
            'グラフPLOT
            For i As Integer = 1 To ds.Tables(0).Columns.Count - 1
                Dim columnName As String = ds.Tables(0).Columns(i).ColumnName
                Chart1.Series.Add(columnName)                                                  '凡例表示項目名
                Chart1.Series(columnName).ChartType = SeriesChartType.Line      'グラフタイプ
                'X軸(データ)
                Chart1.Series(columnName).XValueMember = ds.Tables(0).Columns(0).ColumnName.ToString
                Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = True
                Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
                Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "yyyy/MM/dd HH:mm"
                'Y軸(データ値)
                Chart1.Series(columnName).YValueMembers = columnName
            Next i
            '
            Chart1.ChartAreas(0).AxisX.Title = "日付"
            'DataTableではなくDataViewをソースにする
            view = New DataView(ds.Tables(0))
            '描画範囲を指定
            UpdateRange(view, sPlotymd, ePlotymd)
        End Sub
        'データの設定'//////////////////////////////
        Private Function Getdata() As DataSet
            Dim ds As New DataSet
            Dim dt As New DataTable
            Dim dtRow As DataRow
            Dim i As Integer
            Dim ss As Integer = 0
            dt.Columns.Add("日付", GetType(DateTime)) 'string -> DateTime
            '凡例項目セット(データ項目)
            For i = 1 To CalcMax
                dt.Columns.Add("計測値" & i, GetType(Single))
            Next i
            ds.Tables.Add(dt)
            Dim rnd As New Random
            'データセット--------------------------------------------------
            For ss = 1 To AllMax
                'X軸日付セット
                'Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns        'ここで文字列を"yyyy/MM/dd HH:mm:ss"にする.
                'Dim xYMD As DateTime = DateTime.Parse(Xdt1)             '←①ここでDataTime型に変換
                Dim xYMD As DateTime = DateTime.Now.AddHours(ss)
                'If(Me.sPlotymd <= xYMD && xYMD < Me.ePlotymd) then '不要なデータを除外するならここで判定
                'X軸データセット
                dtRow = ds.Tables(0).NewRow
                dtRow(0) = xYMD 'わざわざ文字列形にせずにDateTime型のままDataRowに格納する
                For i = 1 To CalcMax
                    dtRow(i) = CSng(rnd.Next()) 'ダミーのデータを格納
                Next i
                ds.Tables(0).Rows.Add(dtRow)
            Next ss
            '----------------------------------------------------------
            Return (ds)
        End Function
        ''' <summary> 2個のDateTimePickerの日付の間をRowFilterで抽出 </summary>
        Private Sub DateTimePicker_ValueChanged(sender As System.Object, e As System.EventArgs) _
            Handles DateTimePicker1.ValueChanged, DateTimePicker2.ValueChanged
            sPlotymd = DateTimePicker1.Value
            ePlotymd = DateTimePicker2.Value
            UpdateRange(Me.view, sPlotymd, ePlotymd)
        End Sub
        Private Sub UpdateRange(ByVal view As DataView, ByVal sPlotymd As DateTime, ByVal ePlotymd As DateTime)
            Dim dt1 As DateTime = sPlotymd
            Dim dt2 As DateTime = ePlotymd
            If (dt2 < dt1) Then
                Dim temp As DateTime
                temp = dt1
                dt1 = dt2
                dt2 = temp
            End If
            dt1 = dt1.Date
            dt2 = dt2.Date.AddDays(1)
            view.RowFilter = "日付>='" & dt1.ToLongDateString() & "' and 日付<'" & dt2.ToLongDateString() & "'"
            'X軸の表示範囲を設定する
            Dim ax As System.Windows.Forms.DataVisualization.Charting.Axis = Chart1.ChartAreas(0).AxisX
            ax.Minimum = dt1.ToOADate
            ax.Maximum = dt2.ToOADate
            If (dt2.Subtract(dt1).TotalDays = 1) Then
                ax.Interval = 1 / 6 '範囲が1日の場合のみ4時間おきに縦線
            Else
                ax.Interval = 0 'それ以外は自動
            End If
            '表示更新
            Me.Chart1.DataSource = view
            Me.Chart1.DataBind()
        End Sub
    End Class

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク K's 2012年7月10日 9:13
    2012年7月9日 10:07
  • まずはX軸にする日付列を文字列のString型の列ではなくDateTime型の列にしましょう。
    (文字列が日時だとは自動で判断してはくれません。)
    そうすればChartはX軸を日付で範囲指定可能になりますし、DataViewのRowFilterで範囲指定することもできます。
    この場合、X軸のラベルに年月日の書式設定が必要であればAxisX.LabelStyle.Formatで書式を指定できます。

    次にX軸の範囲を指定するのにAxisX.Minimum,MaximumがDouble型しか入らないので困っているのですよね?
    ここはDateTime型のToOADate()メソッドでDouble型に変換できます。
    これで得られるDouble型は整数部が1989/12/30からの経過日数です。
    小数部は1日の内の時刻になります。(0.25が6時,0.5が12時,0.75が18時)
    このDouble値によりChartは日付型の軸を範囲指定することが可能になります。

    gekkaさん大変参考になりました!!思い通りのグラフが描けました。

    グラフでX軸を日付時刻でカウントさせる場合には、”日付時刻(Char型)"→DateTime型にして、X座標をDouble型スケールとするんですね。なるほど!

    Chartコントロールで作図させる以外でも記述の時間軸の考え方をふまえれば、PictureBox上でのグラフもこの時間軸の考え方でいけば対応できますね!有難うございました!

    * データセットのコードは以下の記述でまとまりました。 *

    --------------------------------------------------------------------------------------- 

    For ss = 1 To AllMax
          dtRow = ds.Tables(0).NewRow

          '計測データの測定日と測定時刻刻文字列→"yyyy/MM/dd HH:mm:ss"形式に.
          Dim Xdt1 As String = Cdt(ss).Ymd & " " & Cdt(ss).Hns

          '測定日時刻:"yyyy/MM/dd HH:mm:ss"→DataTime型→(時間軸X座標)セット
          Dim xYMD As DateTime = DateTime.Parse(Xdt1)

          dtRow = ds.Tables(0).NewRow
          dtRow(0) = xYMD                            'DataTime型で格納→(PLOT位置:時間軸X座標)

          For i = 1 To CalcMax
                dtRow(i) = CSng(Cdt(ss).Calc(i))   '各計測データ格納
          Next i
          ds.Tables(0).Rows.Add(dtRow)

    Next ss
    Return (ds)

    ------------------------------------------------------------------------------------------

      


    2012年7月10日 9:43