0

I would like to read the start and end coordinates from a OxyPlot PlotView graph. The following is a code snippet from the ViewModel.

plotModel.MouseDown += (s1, e1) =>
{
    if (e1.ChangedButton == OxyMouseButton.Middle)
    {            
        plotModel.MouseUp += (s2, e2) =>
        {
             if (e2.IsControlDown)
             {
                 DateTime xstart = DateTime.FromOADate(xAxis.InverseTransform(e1.Position.X, e1.Position.Y, yAxis).X);
                 double ystart = yAxis.InverseTransform(e1.Position.X, e1.Position.Y, yAxis).Y;
                 DateTime xend = DateTime.FromOADate(xAxis.InverseTransform(e2.Position.X, e2.Position.Y, yAxis).X);
                 double yend = yAxis.InverseTransform(e2.Position.X, e2.Position.Y, yAxis).Y;
             }
         };
     } 
};

The problem is that the value I get for xstart and ystart is not correct, it seems like the value for y is just a random number, while the x value is somewhat acceptable. xend and yend are correct. Is there something I should change in the code or is there some alternative way to approach this?

I use the middle button since it highlights the selected area, but I couldn´t find a way to simply get the coordinates of the area.

Robin
  • 3
  • 1
  • I think the transformation itself is correct. The problem seems to be that you connect a new event handler to the mouse up event whenever the user presses the middle mouse button and the same mouse operations also perform a zooming operation. So when this code runs a second time the mouse up handler will run twice. The first time it runs I get the correct values. The second time the axis values already seem to have changed. – Döharrrck Feb 12 '21 at 17:53
  • That seems to be the problem, thank you. Do you have any suggestion on how to run the event without creating a new each time? I can´t figure out how to run an event like this, so I can get the `e.Position`, without creating a new event. – Robin Feb 15 '21 at 05:44
  • That depends on what exactly you want to achieve with that information. I will post the most straight-forward way as an answer. – Döharrrck Feb 15 '21 at 08:31

1 Answers1

0

There are several ways to implement this. You might have noticed that the events of the plot model are tagged as obsolete but they won't get removed in the near future because it is not yet clear how to replace them if a client needs to access information about internal changes from the outside (see here).

So this is the easy way to implement it event-based using a private field for the mouse down point:

    /// <summary>
    /// Constructor
    /// </summary>
    public MyClass()
    {
        ...
        var plotModel = new PlotModel();
        plotModel.MouseDown += PlotModel_MouseDown;
        plotModel.MouseUp += PlotModel_MouseUp;
    }

    private ScreenPoint mouseDownPoint;

    private void PlotModel_MouseDown(object sender, OxyMouseDownEventArgs e)
    {
        if (e.ChangedButton == OxyMouseButton.Middle)
        {
            mouseDownPoint = e.Position;
        }
    }

    private void PlotModel_MouseUp(object sender, OxyMouseEventArgs e)
    {
        if (e.IsControlDown)
        {
            ScreenPoint mouseUpPoint = e.Position;

            // assuming your x-axis is at the bottom and your y-axis is at the left.
            Axis xAxis = plotModel.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
            Axis yAxis = plotModel.Axes.FirstOrDefault(a => a.Position == AxisPosition.Left);

            DateTime xstart = DateTime.FromOADate(xAxis.InverseTransform(mouseDownPoint.X));
            double ystart = yAxis.InverseTransform(mouseDownPoint.Y);
            DateTime xend = DateTime.FromOADate(xAxis.InverseTransform(mouseUpPoint.X));
            double yend = yAxis.InverseTransform(mouseUpPoint.Y);
        }
    }

Note that I have also used the simpler overloads of the transformation methods.

The other way would be to derive a class from the 'ZoomRectangleManipulator' class and override it's 'Completed' method but in this case I don't know how you would access the calculated values from the outside. So whether this approach makes sense for you depends on what you are trying to achieve.

Döharrrck
  • 687
  • 1
  • 4
  • 15
  • Thank you! I´ll look into the other approach. But this does the job, so I´ll mark it as the answer. – Robin Feb 15 '21 at 09:26