MsChart Select a portion of data and update Chart

2019-02-20 02:06发布

I've created a program that reads in a text file and displays the data from that file into a DataGridView; I then use the data from this DGV to update a 'chart' based on the results, the chart only consists of line graphs.

What I'm trying to accomplish is allowing the user to select a portion of that data my dragging a beginning and end over it like you would to zoom in if only the x axis was enabled, and update the the graph based on that selection, calculating averages for this subset of data.

Using

chart1.ChartAreas["ChartArea1"].CursorX.IsUserEnabled = Enabled;
chart1.ChartAreas["ChartArea1"].CursorX.IsUserSelectionEnabled = Enabled;

This allows me to select the area and zoom in but I'm unsure how to actually update the data based on the selection rather than just zoom.

1条回答
别忘想泡老子
2楼-- · 2019-02-20 02:29

To allow nice zooming you should add this line to the two you show:

chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Zoomable = true;

Here is a function to calculate an average of the visible points' 1st YValues:

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

Note that the ViewEventArgs parameter is providing the values of the position and size of the View, but these are just the XValues of the datapoints and not their indices; so we need to search the Points from the left for the 1st and from right for the last point.

Update Sometimes the zooming runs into a special problem: When the data are more finely grained than the default CursorX.IntervalType it just won't let you zoom. In such a case you simply have to adapt to the scale of your data, e.g. like this: CA.CursorX.IntervalType = DateTimeIntervalType.Milliseconds;

查看更多
登录 后发表回答