C#从CSV文件读取字符串并绘制折线图

目前,我能够使用Windows窗体应用程序从多个CSV文件读取数据并绘制折线图.但是,现在我需要根据CSV文件的部分名称(csv文件的第三列)绘制折线图.

修改/新的CSV文件:(添加了“部分名称”列)

Values,Sector,Name
5.55,1024,red
5.37,1536,red
5.73,2048,blue
5.62,2560,.blue
5.12,3072,.yellow
...

>根据“节名称”列,我的折线图需要相应地绘制在一条直线上,并且不同的节必须用不同的颜色绘制,包括图侧面显示的图例必须根据不同的节名称显示.
> 1个CSV文件= 1系列.但是,csv文件中有相同的部分名称(上面显示的csv文件示例,例如,第20行的红色).相同的部分名称=相同的颜色.如果我打开2个或更多的csv文件= 2系列.由于csv文件中的节名称不同,每个系列将具有不同的颜色.

我对编程非常陌生,非常感谢有人可以通过编辑代码来帮助我.

谢谢.

解决方法:

更新的代码:

GraphDemo(窗体):

    List<Read> rrList = new List<Read>();

    void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        OpenFileDialog ff = new OpenFileDialog();
        Read rr;

        ff.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //"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)
                {
                    rr = new Read(file);
                    rrList.Add(rr); 
                }

                //Populate the ComboBoxes
                if (rrList.Count > 0)
                {
                    string[] header = rrList[0].header; //header of first file
                    xBox.DataSource = header; 
                    yBox.DataSource = header.Clone(); //without Clone the 2 comboboxes link together!
                }
                if (yBox.Items.Count > 1) yBox.SelectedIndex = 1; //select second item
            }
            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.Draw(rrList, xBox, yBox, chart);
    }

课堂阅读:

public class Read
{
    public int nLines { get; private set; }
    public int nColumns { get; private set; }
    public string[] header { get; private set; }
    public float[,] data { get; private set; }
    public string fileName { get; set; }
    public string[] section { get; private set; }

    public Read(string file)
    {
        string[] pieces;

        fileName = Path.GetFileName(file);  
        string[] lines = File.ReadAllLines(file); // read all lines
        if (lines == null || lines.Length < 2) return; //no data in file
        header = lines[0].Split(','); //first line is header
        nLines = lines.Length - 1; //first line is header
        nColumns = header.Length;

        //read the numerical data and section name from the file
        data = new float[nLines, nColumns - 1]; // *** 1 less than nColumns as last col is sectionName
        section = new string[nLines]; // *** 
        for (int i = 0; i < nLines; i++) 
        {
            pieces = lines[i + 1].Split(','); // first line is header
            if (pieces.Length != nColumns) { MessageBox.Show("Invalid data at line " + (i + 2) + " of file " + fileName); return; }
            for (int j = 0; j < nColumns - 1; j++)
            {
                float.TryParse(pieces[j], out data[i, j]); //data[i, j] = float.Parse(pieces[j]);
            }
            section[i] = pieces[nColumns - 1]; //last item is section
        }
    }

}

类图:

public class Plot
{
    //public Plot() { } //no constructor required as we use a static class to be called

    public static void Draw(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");
        myLegend.Title = "myTitle";

        //define a set of colors to be used for sections
        Color[] colors = new Color[] { Color.Black, Color.Blue, Color.Red, Color.Green, Color.Magenta, Color.DarkCyan, Color.Chocolate, Color.DarkMagenta }; 

        //use a Dictionary to keep iColor of each section
        // key=sectionName, value=iColor (color index in our colors array)
        var sectionColors = new Dictionary<string, int>();

        int i = 0;
        int iColor = -1, maxColor = -1;
        foreach (Read rr in rrList)
        {
            float[,] data = rr.data;
            int nLines = rr.nLines;
            int nColumns = rr.nColumns;
            string[] header = rr.header;

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

            //chart.Series[i].LegendText = rr.fileName;
            chart.Series[i].IsVisibleInLegend = false; //hide default item from legend

            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++)
            {
                int k = chart.Series[i].Points.AddXY(data[j, indX], data[j, indY]);
                string curSection = rr.section[j];
                if (sectionColors.ContainsKey(curSection))
                {
                    iColor = sectionColors[curSection];
                }
                else
                {
                    maxColor++;
                    iColor = maxColor; sectionColors[curSection] = iColor;
                }
                chart.Series[i].Points[k].Color = colors[iColor];
            }

            i++; //series#

        } //end foreach rr

        //fill custom legends based on sections/colors
        foreach (var x in sectionColors)
        {
            string section = x.Key;
            iColor = x.Value;
            myLegend.CustomItems.Add(colors[iColor], section); //new LegendItem()
        }
    }

}
上一篇:c#-启用和禁用按钮,基于某些条件的标签


下一篇:C#ConfigurationManager从app.config检索错误的连接字符串