VB2010 Chartでの表示と収得の方法?

解決


しょう  2012-10-08 14:53:01  No: 147845  IP: [192.*.*.*]

何度もすみません。

Q1、サンプルでは4日とも全ての日付が表示されますが、多数になると按分され全ては表示されませ

ん。
      この日付を、例えば週始めのみ、などと任意に指定して表示するには?
Q2、x軸のカーソル(矢印)の位置から、該当する日付などを特定するには?
      その特定した日付などから、描画されてるローソク足の株価などを検索したいのです。
Q3、折れ線の値が 0 の時には、線の描画がされないようにするには?
Q4、折れ線で小数点以下の値も取り扱えるでしょうか?
      可能でしたらその方法も教えてください。  

超初心者です。
どうぞよろしくお願いします。

        'データの取得
        Dim ds As New DataSet
        Dim dt As New DataTable
        Dim dtRow As DataRow

        '列の作成
        dt.Columns.Add("日付", Type.GetType("System.String"))
        dt.Columns.Add("高値", Type.GetType("System.Int32"))
        dt.Columns.Add("安値", Type.GetType("System.Int32"))
        dt.Columns.Add("始値", Type.GetType("System.Int32"))
        dt.Columns.Add("終値", Type.GetType("System.Int32"))
        dt.Columns.Add("指数①", Type.GetType("System.Int32"))
        ds.Tables.Add(dt)

        'データの追加
        dtRow = ds.Tables(0).NewRow
        dtRow(0) = "2012/08/01" '日付
        dtRow(3) = "600"        '始値
        dtRow(1) = "700"        '高値
        dtRow(2) = "500"        '安値
        dtRow(4) = "550"        '終値
        dtRow(5) = "500"        '指数①
        ds.Tables(0).Rows.Add(dtRow)

        dtRow = ds.Tables(0).NewRow
        dtRow(0) = "2012/08/2" '日付
        dtRow(3) = "850"        '始値
        dtRow(1) = "1100"       '高値
        dtRow(2) = "800"        '安値
        dtRow(4) = "800"        '終値
        dtRow(5) = "0"          '指数①
        ds.Tables(0).Rows.Add(dtRow)

        dtRow = ds.Tables(0).NewRow
        dtRow(0) = "2012/08/7"  '日付
        dtRow(3) = "700"        '始値
        dtRow(1) = "800"        '高値
        dtRow(2) = "500"        '安値
        dtRow(4) = "750"        '終値
        dtRow(5) = "600"        '指数①
        ds.Tables(0).Rows.Add(dtRow)

        dtRow = ds.Tables(0).NewRow
        dtRow(0) = "2012/08/8"  '日付
        dtRow(3) = "300"        '始値
        dtRow(1) = "800"        '高値
        dtRow(2) = "500"        '安値
        dtRow(4) = "600"        '終値
        dtRow(5) = "400"        '指数①
        ds.Tables(0).Rows.Add(dtRow)

        'Chartコントロールにデータソースを設定
        Chart1.DataSource = ds

        '初期化    
        Chart1.Series.Clear()
        'Chartコントロールにタイトルを設定
        Chart1.Titles.Add("株価 日足")

        Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = False
        Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False

        'グラフの種類,系列,軸の設定
        Dim rosoku = Chart1.Series.Add("ローソク足")
        With rosoku
            .ChartType = DataVisualization.Charting.SeriesChartType.Candlestick
            .XValueMember = "日付"
            .YValueMembers = "高値, 安値, 始値, 終値"
            '.IsVisibleInLegend = False
        End With
        '        
        Dim ore1 = Chart1.Series.Add("折れ線①")
        With ore1
            .ChartType = DataVisualization.Charting.SeriesChartType.Line
            .XValueMember = "日付"
            .YValueMembers = "指数①"
            '.IsVisibleInLegend = False
        End With
        Chart1.DataBind()
    End Sub

編集 削除
shu  2012-10-09 10:26:06  No: 147846  IP: [192.*.*.*]

Q1,Q3に関するサンプル
Q2はChart.Hittestで出来るのではないでしょうか。
Q4出来ます。型をIntegerではなく小数点を扱える型にするだけ。

        Dim tbl As New DataTable
        With tbl.Columns
            .Add("日付", GetType(Date))
            .Add("高値", GetType(Integer))
            .Add("安値", GetType(Integer))
            .Add("始値", GetType(Integer))
            .Add("終値", GetType(Integer))
            .Add("指数1", GetType(Integer))
        End With

        tbl.Rows.Add({#8/1/2012#, 700, 500, 600, 550, 500})
        tbl.Rows.Add({#8/2/2012#, 1100, 800, 850, 800, DBNull.Value})
        tbl.Rows.Add({#8/7/2012#, 800, 500, 700, 750, 600})
        tbl.Rows.Add({#8/9/2012#, 800, 500, 300, 600, 400})
        'tbl.Rows.Add({#8/31/2012#, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value})

        Chart1.Series.Clear()
        Chart1.Titles.Add("株価 日足")

        With Chart1.ChartAreas(0).AxisX
            .MajorGrid.Enabled = False
            .MinorGrid.Enabled = False
            .Minimum = #8/1/2012#.Subtract(#1/1/1900#).TotalDays + 1
            .Maximum = .Minimum + 31
            .Interval = 7
            .IntervalAutoMode = DataVisualization.Charting.IntervalAutoMode.VariableCount
        End With

        Dim rosoku = Chart1.Series.Add("ローソク足")
        With rosoku
            .ChartType = DataVisualization.Charting.SeriesChartType.Candlestick
            .XValueMember = "日付"
            .YValueMembers = "高値, 安値, 始値, 終値"
            '.IsVisibleInLegend = False
        End With

        Dim ore1 = Chart1.Series.Add("折れ線①")
        With ore1
            .ChartType = DataVisualization.Charting.SeriesChartType.Line
            .XValueMember = "日付"
            .YValueMembers = "指数①"
            '.IsVisibleInLegend = False
        End With
        Chart1.DataSource = tbl
        Chart1.DataBind()

編集 削除
しょう  2012-10-09 16:40:45  No: 147847  IP: [192.*.*.*]

shuさん、ありがとうございます。

>Q1,Q3に関するサンプル
Q3は解決しました。ありがとうございます。
Q1ですが、日付優先ではなくデータ優先なのです。
  質問の仕方が悪くてすみません。少しサンプルを変更させて頂きました。

  Q,特定の日付を指定して表示、他の日付は非表示にすることは可能でしょうか?

>Q2はChart.Hittestで出来るのではないでしょうか。
  得られた座標から該当のローソク足が特定できれば出来るような気がします。

お教えのほどよろしくお願いします。

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'データの取得
        Dim tbl As New DataTable

        '列の作成
        With tbl.Columns
            .Add("日付", GetType(String))
            .Add("高値", GetType(Integer))
            .Add("安値", GetType(Integer))
            .Add("始値", GetType(Integer))
            .Add("終値", GetType(Integer))
            .Add("指数1", GetType(Integer))
        End With

        'データの追加
        tbl.Rows.Add("2012/08/1", 700, 500, 600, 550, 500)
        tbl.Rows.Add("2012/08/2", 1100, 800, 850, 800, DBNull.Value)
        tbl.Rows.Add("2012/08/7", 800, 500, 700, 750, 600)
        tbl.Rows.Add("2012/08/8", 800, 500, 300, 600, 400)
        'tbl.Rows.Add({#8/31/2012#, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value})

        '初期化    
        Chart1.Series.Clear()

        'Chartコントロールにタイトルを設定
        Chart1.Titles.Add("株価 日足")

        With Chart1.ChartAreas(0).AxisX
            .MajorGrid.Enabled = False   'Chart1.ChartAreas(0).AxisX.MajorGrid.Enabled = False
            .MinorGrid.Enabled = False   'Chart1.ChartAreas(0).AxisX.MinorGrid.Enabled = False
            '.Minimum = #8/1/2012#.Subtract(#1/1/1900#).TotalDays + 1
            '.Maximum = .Minimum + 31
            '.Interval = 7
            '.IntervalAutoMode = DataVisualization.Charting.IntervalAutoMode.VariableCount
        End With

        'グラフの種類,系列,軸の設定
        Dim rosoku = Chart1.Series.Add("ローソク足")
        With rosoku
            .ChartType = DataVisualization.Charting.SeriesChartType.Candlestick
            .XValueMember = "日付"
            .YValueMembers = "高値, 安値, 始値, 終値"
            .IsVisibleInLegend = False
        End With
        '        
        Dim ore1 = Chart1.Series.Add("折れ線1")
        With ore1
            .ChartType = DataVisualization.Charting.SeriesChartType.Line
            .XValueMember = "日付"
            .YValueMembers = "指数1"
            .IsVisibleInLegend = False
        End With
        Chart1.DataSource = tbl
        Chart1.DataBind()
    End Sub
   
    'マウスをクリック時の処理  ??
    Private Sub Chart1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Chart1.Click
        '??
        
    End Sub

    'X,Y 座標を求める ??
    Private Function Coordinates(ByVal x As Integer, ByVal y As Integer) As CoordinatesResult
        '??

    End Function

編集 削除
shu  2012-10-09 18:06:12  No: 147848  IP: [192.*.*.*]

>Q1ですが、日付優先ではなくデータ優先なのです。
優先も何もx軸が日付でy軸がデータなのでは?


前レスよりAxisXの部分を変更。
Intervalが一定でないのならこんな感じでしょうか。

        With Chart1.ChartAreas(0).AxisX
            .MajorGrid.Enabled = False
            .MinorGrid.Enabled = False
            Dim Min = #8/1/2012#.Subtract(#1/1/1900#).TotalDays + 1
            Dim Max = Min + 31
            .Minimum = Min
            .Maximum = Max
            .LabelAutoFitStyle = DataVisualization.Charting.LabelAutoFitStyles.None
            .CustomLabels.Add(Min, Min + 2, "8/1")
            .CustomLabels.Add(Min + 5, Min + 7, "8/6")
            .CustomLabels.Add(Min + 15, Min + 17, "8/16")
        End With

編集 削除
しょう  2012-10-09 20:41:30  No: 147849  IP: [192.*.*.*]

shuさん、説明が下手ですみません(^^;

先ほど16:40:45 の投稿サンプルを実行しますと、
"2012/08/1"、"2012/08/2"、"2012/08/8"、"2012/08/8" と4日分すべての日付が表示されます。
これを、例えば "2012/08/1"のみを表示で、他のすべての日付を非表示にしたいのです。
 あくまでも "2012/08/1" の表示は一例です。
"2012/08/2" になるかもしれませんし "2012/08/8"  になるかもしれません。
どの日付を表示・非表示にするかは別途指定することになります。
実際のデータ数はもっと多いですので、表示・非表示ともに複数となります。

このようなことは可能でしょうか?
よろしくお願いします。

編集 削除
shu  2012-10-09 22:24:48  No: 147850  IP: [192.*.*.*]

提示した内容に対する違いを示されないということは全否定ととらえます。
こちらが提示した内容がマッチしないようなので
x軸のラベル表示の話ではないということですね?
データを表示しないのなら、DataTableに追加しなければ
よいと思いますが、どうでしょう?またはフィルタリングして
表示するデータを絞ればよいと思います。

編集 削除
しょう  2012-10-10 14:58:30  No: 147851  IP: [192.*.*.*]

shuさん、ありがとうごさいます。

tbl.Rows.Add("", 800, 500, 700, 750, 600)
確かに、上記のようにすれば表示したくない日の日付は表示されなくなります。
しかしデータ件数が多くなると…、
ローソク足や折れ線は、データ件数分すべてが描画されますが、
日付表示については、何故か飛び飛びにしか表示されません。
例えば、データ件数が20件ですと…、
20120913、20120921、20120928、20121005 にといった具合に、5日おきの表示になります。
実際のデータ(日付)は 20120913、20120914、20120918、20120919、20120920、20120921、20120924、(以下省略)となっていて、
ローソク足はこれらすべてが描画されます。

そこで何がしたか、ですが…、
例えば、今表示されてる 20120913、20120921 などは非表示にして、表示がされてない 20120914 を表示にしたいのです。

ややっこしい説明ですみません。

編集 削除
shu  2012-10-10 16:16:07  No: 147852  IP: [192.*.*.*]

2012/10/09(火) 10:26:06 

2012/10/09(火) 18:06:12 
のサンプル結果は確認して頂けたのでしょうか?
ややこしい説明かもしれませんがこの2つのサンプルは
言われていることのヒントになると思っています。
tbl.Rows.Add(#8/1/2012#, 700, 500, 600, 550, 500)
であり
tbl.Rows.Add("2012/8/1", 700, 500, 600, 550, 500)
と書いていない理由をよく考えてみてください。

再度書きます。この2つのサンプルを実行して思っていることとの
違いを教えてください。

編集 削除
しょう  2012-10-10 18:22:02  No: 147853  IP: [192.*.*.*]

shuさん、お手数をお掛けします。

データの型が違うのは分かります。

① 日付をDateで扱うとイメージ的には下記のように表示されます。
( : はローソク足の位置です)
  : :       : :
  : :       : : 
 8/1     8/6          8/16    
  
② 一方、日付をStringで扱うと下記のようになります。
  :      :      :      :
  :      :      :      :
 8/1    8/2    8/7    8/8   


① では、日付にローソク足(データ)の位置を合わせてますが、
  (2012/10/09(火) 16:40:45 に日付優先と言いましたのはこの意味です)
② ではデータの数にて、X軸を按分して日付もローソク足も表示しています。

求めてます表示は ② のほうです。
しかも、例えば月初めの 8/1 と言う文字のみを表示して、あとの  8/2、8/7、8/8 の文字は消したいのです。
消すのは簡単なのですが、データ数が多くなると 14:58:30 で説明しましたような困ったことが起きます。
8/1 と言う文字が表示される保証がないのです。

意図するところは分かって頂けたでしょうか。
よろしくお願いします。

編集 削除
しょう  2012-10-10 18:28:05  No: 147854  IP: [192.*.*.*]

すみません。
ローソク足(:)の位置が少し左にずれてしまいました。
実際はもう少し右で、しかも : と : の間隔ももう少し広いです。

編集 削除
shu  2012-10-10 21:13:18  No: 147855  IP: [192.*.*.*]

つまり日付というのはx軸に割り当てる順序値としてふさわしくないということで、グラフを書く上で意味がないわけですね。
integer値を追加してx軸に割り当てCustomLabelsの方のサンプルを参考にすると出来そうですね。

編集 削除
しょう  2012-10-10 23:28:42  No: 147856  IP: [192.*.*.*]

shuさん、ありがとうごさいます。

>グラフを書く上で意味がないわけですね。
そのようです。

>integer値を追加してx軸に割り当て…
出来そうなのですね。
でも、超初心者にはどうすれば良いのやら??

それにどうしてデータ数が増えると、日にちの表示が簡略化されるのでしょう?
すべて表示されれば問題がないのですが。

この件は何だか難しそうなので、もうひとつの…、
Q2、の Chart.Hittestを使って、該当データの特定で対処をしようかと思います。

下記でもマウスをクリックすると e値で座標が取得できるようです。
この得られた x座標から、どの日付のデータかが特定出来れば嬉しいです。
    
    Private Sub Chart1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Chart1.Click

    End Sub

編集 削除
しょう  2012-10-11 23:59:52  No: 147857  IP: [192.*.*.*]

shuさん、何度もお手数をお掛けしました。

教えて頂いたことを元に自分なりに試行錯誤をしてみたいと思います。
本当にありがとうございました。

編集 削除