【问题标题】:How to read data from more than one CSV file into line graph如何将多个 CSV 文件中的数据读入折线图
【发布时间】:2017-01-11 06:07:36
【问题描述】:

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

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

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

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

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

谢谢。

【问题讨论】:

标签: c# winforms csv


【解决方案1】:

当您使用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 实例时都必须重新创建一个新实例不需要的情节。那里还有很多其他的技巧......但它的工作原理

【讨论】:

  • 感谢您的回答。我可以知道是否需要更改 Plot.cs 或 Read.cs 中的任何内容吗?我尝试添加您的代码,但即使我选择了 2 个 csv 文件,它也只在图表中显示 1 行。
  • 是的,您必须更新代码的其他部分。查看我的编辑
  • 是的,现在可以使用了!非常感谢。另一个简短的问题,我如何根据输入文件名在两侧添加图例? “Chart1.Legends.Add”有问题。
  • 已接受。我无法根据打开的文件显示图例。例如。打开 1.csv 和 2.csv 但图例没有相应显示。
  • 您必须将文件名保留为 Read 类中的新属性,并在绘图期间使用它。我将更新代码chart.Series[i].LegendText = rr.fileName;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 2019-11-23
  • 1970-01-01
  • 2017-04-24
  • 2010-11-06
  • 2019-11-19
  • 1970-01-01
相关资源
最近更新 更多