我使用.csv文件绘制了一个图表。现在用户启用选择图表区域并单击导出按钮,然后选择要写入另一个.csv文件的数据。
在这里,我想要接近这个方法。用户希望获得chart1.ChartAreas[0].CursorX.SelectionStart
,chart1.ChartAreas[0].CursorX.SelectionEnd
然后想要读取.csv文件并删除未选择区域中的其他原始文件。
注意:用户也想选择多个图表区域。请给我一个澄清。这是winform应用程序,我使用MsChart。
我的代码如下;
private void btnExport_Click(object sender, EventArgs e)
{
List<Graph> ObservingData = new List<Graph>(); // List to store all available Graph objects from the CSV
int index = 0;
using (StreamWriter sw = new StreamWriter(@"D:\CSVFile\NEWFile\Export\NewFile.csv"))
{
// Loops through each lines in the CSV
foreach (string line in System.IO.File.ReadAllLines(pathToCsv))
{
// here line stands for each line in the csv file
string[] CsvLine = line.Split(',');
// creating an object of type Graph based on the each csv line
// and adding them to the List<Graph>
Graph Instance1 = new Graph();
if (index == 0)
{
sw.WriteLine(line);
}
else
{
//Add the code here..
// if (((chart1.ChartAreas[0].CursorX.SelectionStart))<= && ( <= (chart1.ChartAreas[0].CursorX.SelectionEnd)))
{
sw.WriteLine(line);
}
}
index++;
}
sw.Close();
}
MessageBox.Show("Data are copied to the new .CSV file");
}
以下代码用于我的图表区域的多重选择。
SizeF curRange = SizeF.Empty;
List<SizeF> ranges = new List<SizeF>();
List<int> selectedIndices = new List<int>();
private void chart1_SelectionRangeChanged(object sender, CursorEventArgs e)
{
ranges.Add(curRange);
selectedIndices.Union(collectDataPoints(chart1.Series[0],curRange.Width, curRange.Height)).Distinct();
StripLine sl = new StripLine();
sl.BackColor = Color.FromArgb(255, Color.LightSeaGreen);
sl.IntervalOffset = Math.Min(curRange.Width, curRange.Height);
sl.StripWidth = Math.Abs(curRange.Height - curRange.Width);
chart1.ChartAreas[0].AxisX.StripLines.Add(sl);
}
List<int> collectDataPoints(Series s, double min, double max)
{
List<int> hits = new List<int>();
for (int i = 0; i < s.Points.Count; i++)
if (s.Points[i].XValue >= min && s.Points[i].XValue <= max) hits.Add(i);
return hits;
}
private void chart1_SelectionRangeChanging(object sender, CursorEventArgs e)
{
curRange = new SizeF((float)e.NewSelectionStart, (float)e.NewSelectionEnd);
}
以下代码绘制图形;
private void Output_Load(object sender, EventArgs e)
{
List<Graph> ObservingData = new List<Graph>(); // List to store all available Graph objects from the CSV
// Loops through each lines in the CSV
foreach (string line in System.IO.File.ReadAllLines(pathToCsv).Skip(1)) // .Skip(1) is for skipping header
{
// here line stands for each line in the csv file
string[] InCsvLine = line.Split(',');
// creating an object of type Graph based on the each csv line
Graph Inst1 = new Graph();
Inst1.Date = DateTime.ParseExact(InCsvLine[0], dateFormatString, CultureInfo.InvariantCulture);
Inst1.AvE = double.Parse(InCsvLine[15]);
Inst1.AvI = double.Parse(InCsvLine[16]);
chart1.Series["Speed"].YAxisType = AxisType.Primary;
chart1.Series["Velocity"].YAxisType = AxisType.Secondary;
chart1.Series["Speed"].Points.AddXY(Inst1.Date.TimeOfDay.ToString(), Inst1.AvE);
chart1.Series["Speed"].ChartType = SeriesChartType.FastLine;
chart1.Series["Velocity"].Points.AddXY(Inst1.Date.TimeOfDay.ToString(), Inst1.AvI);
chart1.Series["Velocity"].ChartType = SeriesChartType.FastLine;
ChartArea CA = chart1.ChartAreas[0];
CA.AxisX.ScaleView.Zoomable = false;
CA.AxisY.ScaleView.Zoomable = false;
CA.CursorX.AutoScroll = true;
CA.CursorX.IsUserSelectionEnabled = true;
}
}
答案 0 :(得分:0)
以下是您可能想要学习的示例。
假设x值被添加为DateTimes
;设置XValueType
!
eachSeries.XValueType = ChartValueType.DateTime;
它还假设您有一个要导出的sereis的班级列表:
var series2Export = new List<Series>() { chart.Series[0], chart.Series[1]};
进一步假设系列中的点是并行添加的,因此您希望将相同的范围一起导出,例如从指数33-66开始的前20或点。
现在您可以为SelectionRangeChanged
事件编码(或者当然是保存 Button
点击):
private void chart_SelectionRangeChanged(object sender, CursorEventArgs e)
{
ChartArea ca = chart.ChartAreas[0];
var d0 = (int) ca.CursorX.SelectionStart;
var d1 = (int) ca.CursorX.SelectionEnd;
var spoints = series2Export[0].Points
.Where(x => x.XValue >= d0 && x.XValue <= d1).ToList();
string del1 = ";";
string del2 = "\t";
string fmt1 = "yyyy.MM.dd";
string fmt2 = "#0.0";
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = suggestedFilePath;
sfd.Title = (d1 - d0) + " points selected. Save data to..";
if (sfd.ShowDialog() == DialogResult.OK)
{
StringBuilder sb = new StringBuilder();
foreach (var dp0 in spoints)
{
int pi = chart.Series[0].Points.IndexOf(dp0);
string st = "";
foreach (var s in series2Export)
{
DataPoint dp = s.Points[pi];
st += (DateTime.FromOADate(dp.XValue)).ToString(fmt1) +
del1 + dp.YValues[0].ToString(fmt2) + del2;
}
sb.AppendLine(st);
}
File.WriteAllText(sfd.FileName, sb.ToString());
}
}
}
请注意,我已经为分隔符和数据的formts使用了字符串。你可以根据需要调整它们。
以上代码以以下格式导出所有参与系列的数据: x-value1,yvalue1 .. ;这意味着它假设......
如果您只想导出csv行,那么最简单的方法是将每行DataPoint
存储到第一个系列中。存储它们的自然位置是Tags
。
以下是两个函数,用于从一行创建数据点列表并从一系列中恢复该行:
List<DataPoint> PointsFromCsvLine(string line)
{
var parts = line.Split(',').ToList(); // use your separator
DateTime dt = Convert.ToDateTime(parts[0]); // add checks!
double d1 = Convert.ToDouble(parts[1]); // use..
double d2 = Convert.ToDouble(parts[4]); // ..your..
double d3 = Convert.ToDouble(parts[9]); // ..numbers!
var points = new List<DataPoint>();
points.Add(new DataPoint( dt.ToOADate(), d1));
points.Add(new DataPoint( dt.ToOADate(), d2));
points.Add(new DataPoint( dt.ToOADate(), d3));
points[0].Tag = line;
return points;
}
string CsvLineFromPoint(Series series0, int index )
{
DataPoint dp = series0.Points[index]; // check index
string s = dp.Tag.ToString();
return s;
}