MsChart Select 部分数据并更新Chart
MsChart Select a portion of data and update Chart
我创建了一个读取文本文件并将该文件中的数据显示到 DataGridView 中的程序;然后我使用这个 DGV 的数据根据结果更新 'chart',该图表仅包含折线图。
我想要完成的是允许用户 select 我在其上拖动开始和结束的一部分数据,就像您在仅启用 x 轴时放大一样,并且根据 selection 更新图形,计算此数据子集的平均值。
使用
chart1.ChartAreas["ChartArea1"].CursorX.IsUserEnabled = Enabled;
chart1.ChartAreas["ChartArea1"].CursorX.IsUserSelectionEnabled = Enabled;
这允许我 select 区域并放大,但我不确定如何根据 selection 而不仅仅是缩放来实际更新数据。
为了更好地缩放,您应该将此行添加到您显示的两行中:
chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Zoomable = true;
这是计算可见点的第一个 Y 值的平均值的函数:
private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
// for a test the result is shown in the Form's title
Text = "AVG:" + GetAverage(chart1, chart1.Series[0], e);
}
double GetAverage(Chart chart, Series series, ViewEventArgs e)
{
ChartArea CA = e.ChartArea; // short..
Series S = series; // references
DataPoint pt0 = S.Points.Select(x => x)
.Where(x => x.XValue >= CA.AxisX.ScaleView.ViewMinimum)
.DefaultIfEmpty(S.Points.First()).First();
DataPoint pt1 = S.Points.Select(x => x)
.Where(x => x.XValue <= CA.AxisX.ScaleView.ViewMaximum)
.DefaultIfEmpty(S.Points.Last()).Last();
double sum = 0;
for (int i = S.Points.IndexOf(pt0); i < S.Points.IndexOf(pt1); i++)
sum += S.Points[i].YValues[0];
return sum / (S.Points.IndexOf(pt1) - S.Points.IndexOf(pt0) + 1);
}
请注意,ViewEventArgs
参数提供了视图的位置和大小的值,但这些只是数据点的 XValues
而不是它们的索引;所以我们需要从左边搜索 Points
第一个点,从右边搜索最后一个点。
更新 有时缩放会遇到一个特殊问题:当数据比默认 CursorX.IntervalType
更细粒度时,它不会让您缩放。在这种情况下,您只需适应数据的规模,例如像这样:CA.CursorX.IntervalType = DateTimeIntervalType.Milliseconds;
我创建了一个读取文本文件并将该文件中的数据显示到 DataGridView 中的程序;然后我使用这个 DGV 的数据根据结果更新 'chart',该图表仅包含折线图。
我想要完成的是允许用户 select 我在其上拖动开始和结束的一部分数据,就像您在仅启用 x 轴时放大一样,并且根据 selection 更新图形,计算此数据子集的平均值。
使用
chart1.ChartAreas["ChartArea1"].CursorX.IsUserEnabled = Enabled;
chart1.ChartAreas["ChartArea1"].CursorX.IsUserSelectionEnabled = Enabled;
这允许我 select 区域并放大,但我不确定如何根据 selection 而不仅仅是缩放来实际更新数据。
为了更好地缩放,您应该将此行添加到您显示的两行中:
chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Zoomable = true;
这是计算可见点的第一个 Y 值的平均值的函数:
private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
// for a test the result is shown in the Form's title
Text = "AVG:" + GetAverage(chart1, chart1.Series[0], e);
}
double GetAverage(Chart chart, Series series, ViewEventArgs e)
{
ChartArea CA = e.ChartArea; // short..
Series S = series; // references
DataPoint pt0 = S.Points.Select(x => x)
.Where(x => x.XValue >= CA.AxisX.ScaleView.ViewMinimum)
.DefaultIfEmpty(S.Points.First()).First();
DataPoint pt1 = S.Points.Select(x => x)
.Where(x => x.XValue <= CA.AxisX.ScaleView.ViewMaximum)
.DefaultIfEmpty(S.Points.Last()).Last();
double sum = 0;
for (int i = S.Points.IndexOf(pt0); i < S.Points.IndexOf(pt1); i++)
sum += S.Points[i].YValues[0];
return sum / (S.Points.IndexOf(pt1) - S.Points.IndexOf(pt0) + 1);
}
请注意,ViewEventArgs
参数提供了视图的位置和大小的值,但这些只是数据点的 XValues
而不是它们的索引;所以我们需要从左边搜索 Points
第一个点,从右边搜索最后一个点。
更新 有时缩放会遇到一个特殊问题:当数据比默认 CursorX.IntervalType
更细粒度时,它不会让您缩放。在这种情况下,您只需适应数据的规模,例如像这样:CA.CursorX.IntervalType = DateTimeIntervalType.Milliseconds;