如何将多个CSV文件中的数据读入线图

时间:2017-01-11 06:07:36

标签: c# winforms csv

目前,我的代码可以使用OpenFileDialogMultiSelect = True选择多个csv文件。但我的图表似乎只是从一个csv文件获取数据而不是其他文件。

我所有的csv文件只有2列(X和Y轴):

Value, Sector
5.55,1024
5.37,1536
5.73,2048
...

我需要能够从多个csv文件中获取数据,并提供一个包含多行的图表(例如,3 csv文件=图中显示的3行)。

真的很感激,如果有人可以帮助我。

感谢。

1 个答案:

答案 0 :(得分:0)

当您使用Multiselect时,您必须遍历用户选择的所有文件,而不是使用OpenFile()方法,因为它仅适用于一个文件

if (ff.ShowDialog() == DialogResult.OK)
{
    //if ((myStream = ff.OpenFile()) != null)
    foreach (String file in ff.FileNames)
    {
        myStream = File.OpenRead(file);
        // ...
    }
}

编辑关于需要修改的其他代码部分:

您必须使用rrList作为List<Read>,而不是仅使用一个rr。

<强> GraphDemo.cs

    Read rr;
    List<Read> rrList = new List<Read>(); // *** new

    void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Stream myStream = null;
        OpenFileDialog ff = new OpenFileDialog();

        ff.InitialDirectory = "C:\\";
        ff.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
        ff.Multiselect = true;
        ff.FilterIndex = 1;
        ff.RestoreDirectory = true;

        if (ff.ShowDialog() == DialogResult.OK)
        {
            try
            {
                rrList.Clear(); //***
                foreach (String file in ff.FileNames) //if ((myStream = ff.OpenFile()) != null)
                {
                    using (myStream = File.OpenRead(file))
                    {
                        rr = new Read(myStream);
                        rr.fileName = Path.GetFileName(file);  // !!! new
                        string[] header = rr.get_Header();
                        List<string> lX = new List<string>();
                        List<string> lY = new List<string>();
                        for (int i = 0; i < header.Length; i++)
                        {
                            lX.Add(header[i]); lY.Add(header[i]);
                        }
                        //Populate the ComboBoxes
                        xBox.DataSource = lX;
                        yBox.DataSource = lY;
                        // Close the stream
                        myStream.Close();
                    }
                    rrList.Add(rr); //***
                }
            }
            catch (Exception err)
            {
                //Inform the user if we can't read the file
                MessageBox.Show(err.Message);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {

        Plot p = new Plot(rrList, xBox, yBox, chart); //*** use rrList instead of rr

    }

绘图类

class Plot
{
    public Plot(List<Read> rrList, ComboBox xBox, ComboBox yBox, Chart chart) //***
    {
        int indX = xBox.SelectedIndex;
        int indY = yBox.SelectedIndex;

        chart.Series.Clear(); //ensure that the chart is empty
        chart.Legends.Clear();
        Legend myLegend = chart.Legends.Add("myLegend"); // !!! new
        myLegend.Title = "myTitle"; // !!! new

        int i = 0; //series index
        foreach (Read rr in rrList)
        {
            float[,] data = rr.get_Data();
            int nLines = rr.get_nLines();
            int nColumns = rr.get_nColumns();
            string[] header = rr.get_Header();

            chart.Series.Add("Series" + i);
            chart.Series[i].ChartType = SeriesChartType.Line;

            chart.Series[i].LegendText = rr.fileName; // !!! new

            chart.ChartAreas[0].AxisX.LabelStyle.Format = "{F2}";
            chart.ChartAreas[0].AxisX.Title = header[indX];
            chart.ChartAreas[0].AxisY.Title = header[indY];

            for (int j = 0; j < nLines; j++)
            {
                chart.Series[i].Points.AddXY(data[j, indX], data[j, indY]);
            }

            i++; //series index
        }
    }
}

添加到Read类:

public string fileName { get; set; } // !!! new

注意:您的代码方法不太好,例如Plot应该是其类中的void方法而不是构造函数,因为每次要绘制新的时都必须重新创建Plot的新实例不需要的情节。那里有许多其他的提示......但是它有效