none
chartが使用できない RRS feed

  • 質問

  • 初心者の黒です。

    win10でvs2015pro、vb.net で開発しています。

    csvデータを読み込んでchartで折れ線グラフを表示しようとしましたが、チャートに表示させようとしたところで「インデックスが範囲を超えています。」というエラーメッセージがでて困っております。どのインデックスが範囲を超えているのかが分かりません。アドバイスをいただけると助かります。csvデータの-1015の列をY、行数をXとしての散布図を折れ線で表示させようとしています。最初はCSVの行数が8000を超えたので容量的に無理なのかなと思って行数を30行程度に少なくしましたが、同じエラーが出続けます。

    プログラム

    Imports System.Text
    Imports System.IO
    Imports System.Data.OleDb
    Imports System.Windows.Forms.DataVisualization.Charting
    Imports Microsoft.VisualBasic.FileIO
    Public Class Form1
        Dim tbm As New DataTable
        Dim NID, SID, DID As Integer
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

            '初期化
            Chart1.Series.Clear()

            'データの取得

        End Sub

        Private Sub btnSansyou_Click(sender As Object, e As EventArgs) Handles btnSansyou.Click

            Dim ds As New DataSet

            Dim columns As Integer
            Dim rows, q As Integer
            Dim folderPath As String
            Dim csvFileName As String
            Dim Csvpath As String

            '[開く]ダイアログの表示
            If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                folderPath = IO.Path.GetDirectoryName(OpenFileDialog1.FileName)
                csvFileName = IO.Path.GetFileName(OpenFileDialog1.FileName)
                tbFileName.Text = folderPath & "\" & csvFileName
                Csvpath = tbFileName.Text
            ElseIf OpenFileDialog1.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
                Exit Sub


            End If

            '************************
            '******何行あるか確認する
            '************************

            Dim csvRecords As New System.Collections.ArrayList()

            'Shift JISで読み込む
            Dim tfp As New FileIO.TextFieldParser(Csvpath, System.Text.Encoding.GetEncoding(932))
            'フィールドが文字で区切られているとする
            'デフォルトでDelimitedなので、必要なし
            tfp.TextFieldType = FileIO.FieldType.Delimited
            '区切り文字を,とする
            tfp.Delimiters = New String() {","}
            'フィールドを"で囲み、改行文字、区切り文字を含めることができるか
            'デフォルトでtrueなので、必要なし
            tfp.HasFieldsEnclosedInQuotes = True
            'フィールドの前後からスペースを削除する
            'デフォルトでtrueなので、必要なし
            tfp.TrimWhiteSpace = True

            While Not tfp.EndOfData
                'フィールドを読み込む
                Dim fields As String() = tfp.ReadFields()
                '保存
                csvRecords.Add(fields)
            End While


            '後始末
            tfp.Close()


            '****データの格納

            '接続文字列
            Dim conString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + folderPath + ";Extended Properties=""text;HDR=No;FMT=Delimited"""
            Dim con As New System.Data.OleDb.OleDbConnection(conString)

            Dim commText As String = "SELECT * FROM [" + csvFileName + "]"
            Dim da As New System.Data.OleDb.OleDbDataAdapter(commText, con)

            'DataTableに格納する
            Dim dt As New DataTable
            da.Fill(dt)





            Chart1.DataSource = dt
            columns = dt.Columns.Count - 1
            rows = dt.Rows.Count


            'Stop

            '--------------------------------ここから散布図の表示設定--------------------------------
            '************************************************************************
            '*
            '*   チャート用データ配列
            '*

            Dim x, y As Single

            '系列を初期化
            Dim tbl As New DataTable
            With tbl.Columns
                .Add("X", GetType(Integer))
                .Add("Y", GetType(Integer))
            End With


            'テーブルからデータを取得
            For i As Integer = 5 To rows - 1

                y = CType(dt.Rows.Item(i)(4), Integer)
                x = CType(i - 4, Integer)
                tbl.Rows.Add(x, y)

            Next
            Stop
            '************** Chart1の設定
            With Chart1
                .Series.Clear()
                .DataSource = tbl
                Dim sr = .Series(0)
                'グラフの種類をPoint(点グラフ)にして散布図を描画
                sr.ChartType = DataVisualization.Charting.SeriesChartType.Line
                sr.Color = Color.Black
                sr.XValueMember = "x"
                sr.YValueMembers = "y"
                sr.Points.AddXY(x, y)    'データを設定
                sr.MarkerSize = 1      'マーカーを大きくして表示
                sr.MarkerStyle = DataVisualization.Charting.MarkerStyle.Diamond
                sr.MarkerColor = Color.Red
                sr.BorderDashStyle = DataVisualization.Charting.ChartDashStyle.Solid
                sr.BorderWidth = 2
                sr.BorderColor = Color.Black
                ' If i < 5 Then        '正しく表示されているか確認の為ポイントラベルを表示
                '.Series(CType(i, String)).Label = CStr(i) & ":#VALX" & ",#VALY"
                'End If
                'すべての系列についてマーカーを表示し、線を表示解除します。

                '     .Legends(0).Enabled = False     '凡例を非表示にする
            End With

            '■------------------- X軸・Y軸のフォント・線等の設定 ----------------Start--■
            With Chart1.ChartAreas(0)
                'X軸のメモリを自動設定だと中途半端な値になるので別途設定
                'With .AxisX
                '    .Minimum = 0
                '    '.Maximum = cMaxDis
                '    '.Interval = cDisScale
                'End With

                'Y軸のメモリを自動設定だと中途半端な値になるので別途設定
                'With .AxisY
                '    .Minimum = 0
                '    '.Maximum = cMaxLoad
                '    '.Interval = cloadScale
                'End With

            End With
        End Sub
    End Class

    *****CSVデータの中身

    , StartTime,2019/4/5 16:16,,,
    , DataCount,8034,,,
    , SampleRate,62.5,,,
    No,Time,X軸/g,Y軸/g,Z軸/g,エンコーダ
    0,14:18.5,1000,0,0,0
    1,14:18.5,-1000,0,-1015,100002
    2,14:18.6,-1000,0,-1016,100002
    3,14:18.6,-1000,0,-1015,100002
    4,14:18.6,-1000,0,-1015,100002
    5,14:18.6,-1000,0,-1016,100002
    6,14:18.7,-1000,0,-1016,100002
    7,14:18.7,-1000,0,-1016,100002
    8,14:18.7,-1000,0,-1015,100002
    9,14:18.7,-1000,0,-1015,100002
    10,14:18.7,-1000,0,-1015,100002
    11,14:18.7,-1000,0,-1016,100002
    12,14:18.7,-1000,0,-1015,100002
    13,14:18.7,-1000,0,-1015,100002
    14,14:18.7,-1000,0,-1016,100002
    15,14:18.7,-1000,0,-1016,100002
    16,14:18.8,-1000,0,-1016,100002
    17,14:18.8,-1000,0,-1015,100002
    18,14:18.8,-1000,0,-1015,100002
    19,14:18.8,-1000,0,-1015,100002
    20,14:18.8,-1000,0,-1016,100002
    21,14:18.8,-1000,0,-1016,100002
    22,14:18.8,-1000,0,-1015,100002
    23,14:18.9,-1000,0,-1015,100002
    24,14:18.9,-1000,0,-1016,100002

    エラー画面


    • 編集済み 9638masa 2019年5月8日 5:56
    2019年5月8日 5:51

回答

  • Seriesが単複同形なんでちょっとややこしいですが、ChartのSeriesプロパティは、複数のSeriesオブジェクトを格納するコレクションであるSeriesCollectionです。

    なので、そのClearメソッドを呼び出すと、コレクションに含まれているSeriesオブジェクトを全部コレクションから除外することになります。結果、コレクションは要素数0になります。

    この状態で (0) を参照しようとしても、要素数0なので当然OutOfIndexです。

    新しいSeriesを使用するのであれば、New Seriesで新しいSeriesオブジェクトを生成したした上で、それをChartのSeriesプロパティに対してAddする必要があります。

    • 回答としてマーク 9638masa 2019年5月8日 8:27
    2019年5月8日 6:16

すべての返信

  • Seriesが単複同形なんでちょっとややこしいですが、ChartのSeriesプロパティは、複数のSeriesオブジェクトを格納するコレクションであるSeriesCollectionです。

    なので、そのClearメソッドを呼び出すと、コレクションに含まれているSeriesオブジェクトを全部コレクションから除外することになります。結果、コレクションは要素数0になります。

    この状態で (0) を参照しようとしても、要素数0なので当然OutOfIndexです。

    新しいSeriesを使用するのであれば、New Seriesで新しいSeriesオブジェクトを生成したした上で、それをChartのSeriesプロパティに対してAddする必要があります。

    • 回答としてマーク 9638masa 2019年5月8日 8:27
    2019年5月8日 6:16
  • Hongliangさん アドバイスありがとうございます。

    なるほど、私のコードではClearメソッドの配置場所が悪い?Clearは要らない?ですね。

    良くわからないで,Clearを使っていました。素晴らしい解説ありがとうございます。

    Clearをコメント文に変更したら、グラフが表示されました。ありがとうございました。


    2019年5月8日 8:27