I am trying to implement a CSV data plotting program in C#. In the plotting part, I use ScottPlot.NET to perform plotting operation. There are five column in the given CSV file, therefore, I use Channel1
to Channel5
to present these 5 channels. The following program only plots first channel data. The given CSV file has millions of rows. I am wondering how to improve the performance for the case of drawing millions of points.
The experimental implementation
using ScottPlot.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PlottingApp
{
public partial class Form1 : Form
{
private readonly ScottPlot.WinForms.FormsPlot formsPlot1 = new ScottPlot.WinForms.FormsPlot();
private ScottPlot.Plottables.DataLogger Logger1;
public Form1()
{
InitializeComponent();
}
private void button_add_channel_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
// Set the title and filter for the dialog
openFileDialog.Title = "Open File";
openFileDialog.Filter = "CSV files (*.csv)|*.csv|Text files (*.txt)|*.txt|All files (*.*)|*.*";
// Display the dialog and check if the user clicked OK
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// Get the selected file name
string fileName = openFileDialog.FileName;
var contents = File.ReadAllText(fileName);
string[] lines = contents.Split(
new string[] { Environment.NewLine },
StringSplitOptions.None
);
foreach (var item in lines)
{
string[] eachData = item.Split(
new string[] { "," },
StringSplitOptions.None
);
Channels channels = new Channels();
if (!double.TryParse(eachData[0], out channels.Channel1))
{
continue;
}
if (!double.TryParse(eachData[1], out channels.Channel2))
{
continue;
}
if (!double.TryParse(eachData[2], out channels.Channel3))
{
continue;
}
if (!double.TryParse(eachData[3], out channels.Channel4))
{
continue;
}
if (!double.TryParse(eachData[4], out channels.Channel5))
{
continue;
}
Logger1.Add(channels.Channel1);
formsPlot1.Refresh();
}
}
else
{
Console.WriteLine("No file selected.");
}
}
private void Form1_Load(object sender, EventArgs e)
{
panel1.Controls.Add(formsPlot1);
formsPlot1.Width = panel1.Width;
formsPlot1.Height = panel1.Height;
// create loggers and add them to the plot
Logger1 = formsPlot1.Plot.Add.DataLogger();
Logger1.LineWidth = 3;
}
}
}
Channels
classpublic class Channels { public double Channel1; public double Channel2; public double Channel3; public double Channel4; public double Channel5; public override string ToString() { return Channel1.ToString() + '\t' + Channel2.ToString() + '\t' + Channel3.ToString() + '\t' + Channel4.ToString() + '\t' + Channel5.ToString(); } }