0

I'm using OxyPlot to show a data chart and to allow the user to select an interval of data he wants to do calculation on.

It looks like this:

enter image description here

Now, I would like the user to be able to set the data interval used for calculation himself by resizing the chart. For example, if he resized the chart on this particular interval it would only take the points located between the furthest left and the furthest right on screen.

enter image description here

I already found the event that triggers whenever the chart is resized :

 plotModel.Updated += (s, e) =>
        {
            //reset interval used for calculation
        };

What I couldn't find in OxyPlot documentation is a way to retrieve a certain set of points currently shown. It doesn't need to be points in particular, I could also use only the x components of each extremum.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291

1 Answers1

2

You could use Series.GetScreenRectangle().Contains() method after transforming your points using the Transform() method to detect if the point is currently in display.

For example,

model.Updated += (s,e)=> 
{
    if(s is PlotModel plotModel)
    {
        var series = plotModel.Series.OfType<OxyPlot.Series.LineSeries>().Single();
        var pointCurrentlyInDisplay = new List<DataPoint>();
        foreach (var point in series.ItemsSource.OfType<DataPoint>())
        {
            if (series.GetScreenRectangle().Contains(series.Transform(point)))
            {
                pointCurrentlyInDisplay.Add(point);
            }
        }
    }
};

You are iterating over the point collection and verifying if the Transformed point (Transform method transform DataPoint to screen point) falls within the Screen Rectangle used by the series.

Update

If you have used Series.Points.AddRange()/Add() for adding points instead of Series.ItemSource, use the following for retrieving points.

foreach (var point in series.Points.OfType<DataPoint>())
{
            if (series.GetScreenRectangle().Contains(series.Transform(point)))
            {
                pointCurrentlyInDisplay.Add(point);
            }
}
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • I get an ArgumentNullException at the line : 'foreach (var point in series.ItemsSource.OfType())'. Now the description of ItemsSource says it returns null by default, should I be initializing it then ? – FrougeurPro Jul 08 '21 at 12:18
  • @FrougeurPro It looks like you had used Series.Points to add the points instead of Series.ItemSource and hence the error. Please check the updated answer for how to retrieve the points when added using Series.Points. Hope that resolves your issue – Anu Viswan Jul 08 '21 at 12:35
  • 1
    Yes indeed, I had to make tiny adjustements since I used a dictionary instead of a list to store my data but overall your solution worked. Thanks. – FrougeurPro Jul 08 '21 at 14:10
  • Glad to help you – Anu Viswan Jul 08 '21 at 14:17