トップ回答者
Visual Basic 2010 グラフ(Chartコントロール)でX軸を日付時刻型で設定する方法

質問
-
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 = 0dt.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"になります。
最終的このグラフを発展させて、[カレンダーコントロールを使用→出力範囲を指定→範囲内にデータを出力させる]ものを作りたいのですけど..
回答
-
ここで、範囲を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
すべての返信
-
「日付範囲を指定して、その範囲のみのグラフを書きたい」ってことですよね
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!)
-
「日付範囲を指定して、その範囲のみのグラフを書きたい」ってことですよね
#「~ですけど」ばかりで、何がわからなくて、何がやりたいことなのかが伝わってこないのですよ。
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 StructurePublic Cdt(AllMax) As CsvAll
//////////////////////////////////////////////////
・グラフ出力開始日=sPlotymd(as DateTime)→ Form1で取得
・グラフ出力終了日=ePlotymd(as DateTime)→ Form1で取得
---------------------------------------------------------------------------------* 作成中のForm2では、Form1でのグラフの出力範囲設定に関係なくただ読み込んだ
データ全てを出力させています*
(以下は前記述コードとほぼ同じForm2.vbのコードです)
==============================================
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form2Private 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の使用法も参考にします)。
-
ここで、範囲を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
-
まずは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)------------------------------------------------------------------------------------------