C#从CSV文件中读取字符串并绘制线图 [英] C# Read string from CSV file and plot line graph

查看:829
本文介绍了C#从CSV文件中读取字符串并绘制线图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我能够从多个CSV文件中读取数据,并使用窗体应用程序绘制线图。但是,现在我需要绘制一个基于CSV文件的节名称(csv文件的第三列)的线图。

Currently, I am able to read data from multiple CSV file and plot line graph using windows form application. However, now I need to plot a line graph based on a CSV file's section name (3rd column of csv file).

修改的/新的CSV文件:名称列)

Modified/New CSV file: (Added the Section Name column)

Entropy Values,File Offset,Section Name
5.55675,1024,.text
5.3757,1536,.text
5.68973,2048,.rdata
5.6652,2560,.rdata
5.1902,3072,.data
...




  1. 根据节名称列,我的折线图需要在单行中,不同的部分必须以不同的颜色绘制,包括图表侧面显示的图例必须根据不同的部分名称显示。

  2. 1 csv file = 1 Series 。但是在csv文件中有相同的段名称(上面显示的csv文件示例,例如第一20行的.text)。 相同版面名称=相同颜色。如果我打开2个或更多的csv文件= 2系列。

  1. Based on the Section Name column, my line graph need to be plotted accordingly in a Single line and different sections must be plotted with different colors, including the legends shown at the side of the graph must be shown based on the different section names.
  2. 1 csv file = 1 Series. But there are same section names in a csv file (csv file example shown above, e.g. .text for the 1st 20lines). Same section names = same color. If I open 2 or more csv files = 2 Series. Each Series will have different colors due to different section names in the csv file.

我是一个新的编程,并会真的很感激有人可以通过我的代码进行编辑来帮助我。

I am quite new with programming, and would really appreciate someone could help me by editing from my code.

谢谢。

strong>

Read Class

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

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

        fileName = Path.GetFileName(file);
        string[] lines = File.ReadAllLines(file);
        if (lines == null || lines.Length < 2)
        {
            return;     // No data in file
        }

        header = lines[0].Split(',');
        nLines = lines.Length - 1; 
        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 section name
        section = new string[nLines]; 
        for (int i = 0; i < nLines; i++)
        {
            pieces = lines[i + 1].Split(',');       // Read line by line, exclude comma
            if (pieces.Length != nColumns)          // Check if there's 3 col in each line
            {
                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]);
            }
            section[i] = pieces[nColumns - 1];        
        }
    }
}

/ strong>

Plot Class

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

        chart.Series.Clear();               
        chart.Legends.Clear();              

        Legend myLegend = chart.Legends.Add("myLegend");
        myLegend.Title = "Legends";                             
        Color[] colors = new Color[] { Color.Blue, Color.Red, Color.Green, Color.DarkMagenta, Color.DarkCyan, Color.Black, Color.Chocolate, Color.Purple};


        var sectionColors = new Dictionary<string, int>();      

        int i = 0;                      // Series index
        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].IsVisibleInLegend = false;

            chart.ChartAreas[0].AxisX.LabelStyle.Format = "{F0}";
            chart.ChartAreas[0].AxisY.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 legend based on series
        foreach (var x in sectionColors)
        {
            string section = x.Key;
            iColor = x.Value;
            myLegend.CustomItems.Add(colors[iColor], section); // Add new LegendItem()
        }
    }
}

GraphDemo类

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

   void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        OpenFileDialog ofd = new OpenFileDialog();

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

        if (ofd.ShowDialog() == DialogResult.OK)
        {
            try
            {
                rrList.Clear();
                foreach (string file in ofd.FileNames)
                {
                    rr = new Read(file);
                    rrList.Add(rr);
                }

                // Populate the ComboBoxes
                if (rrList.Count > 0)
                {
                    string[] header = rrList[0].header;
                    xBox.DataSource = header;
                    yBox.DataSource = header.Clone();
                }
                if (xBox.Items.Count > 1)
                {
                    xBox.SelectedIndex = 1;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }
    }

    private void btnPlot_Click(object sender, EventArgs e)
    {
        if (rr != null)
        {
            Plot.Draw(rrList, xBox, yBox, chart);
        }
        else
        {
            MessageBox.Show("Error, no data to plot! Please load csv file!");
            return;
        }
    }


推荐答案

代码:

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);
    }

class Read:
$ b

class Read:

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
        }
    }

}


$ b b

class Plot:

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#从CSV文件中读取字符串并绘制线图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆