OxyPlot 获取点击点

5

我正在尝试通过以下方式在散点图上绘制一些圆形:

<Grid>
    <oxy:PlotView x:Name="PlotView" Title="{Binding Title}" >
        <oxy:PlotView.Axes>
            <oxy:LinearAxis Position="Bottom" Minimum="-30" Maximum="30" IsAxisVisible="False" IsZoomEnabled="False" IsPanEnabled="False" />
            <oxy:LinearAxis Position="Left" Minimum="0" Maximum="35" IsAxisVisible="False" IsZoomEnabled="False" IsPanEnabled="False"/>
        </oxy:PlotView.Axes>
        <oxy:PlotView.Series>
            <oxy:ScatterSeries Height="100" Width="100" ItemsSource="{Binding Points}" MarkerType="Circle" />
        </oxy:PlotView.Series>
    </oxy:PlotView>
</Grid>

我无法弄清如何启用某种点击处理程序,以便在用户单击DataPoint时触发事件。
示例:
当用户单击坐标为(0,5)的DataPoint时,我想要触发事件,以便我可以处理该点的单击事件。
使用OxyPlot是否可能实现此功能?我目前正在调查Tracker以查看是否可以通过该路线实现,但是开始没有思路。

你尝试过使用 plotView.MouseDown 事件吗? - kennyzx
我已经能够获取鼠标的X和Y位置,但它不是相对于实际图表的。 - Matt
2
我没有尝试过,但是InverseTransform被用来将鼠标坐标转换为绘图坐标。 - kennyzx
kenny: 你能将那个作为回答添加吗,这样我就可以将其标记为正确的了吗?看起来这就是我继续前进所需要的! - Matt
3个回答

11
PlotView 定义了鼠标事件,通过它可以获取鼠标坐标,InverseTransform 用于将鼠标坐标转换为绘图坐标。

示例:

var model = new PlotModel { Title = "Test Mouse Events" };

var s1 = new LineSeries();
model.Series.Add(s1);

double x;

s1.MouseDown += (s, e) =>
{
    x = (s as LineSeries).InverseTransform(e.Position).X;
};

我知道这是一个老问题,但你能提供一下这个解决方案的例子吗?我正在努力让它工作。 - lucas.mdo
我的代码中没有触发任何事件。 - John

3
我不能让被接受的答案有效。当单击绘图时,MouseDown处理程序将不会接收事件。然而,它将接收右键单击和双击事件。我的解决方法是在PlotView上侦听PreviewMouseDown。

“MouseDown” 没有接收到事件,因为您可能有一个自定义系列,并且没有覆盖 “TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)” 方法。我曾经遇到过同样的问题,但是一旦我添加了该方法的覆盖来返回 InverseTransform - 一切都正常工作了。 - Dmitry Avtonomov

1

自v4.0起,该系列的MouseDown事件已被弃用。现在您可以添加一个TrackerManipulator并在那里捕获鼠标按下事件:

public class DoSomethingWithPointTrackerManipulator : OxyPlot.TrackerManipulator
{
  public DoSomethingWithPointTrackerManipulator (IPlotView plotView) : base(plotView)
  {
    Snap = true;
    PointsOnly = true;
  }

  public override void Started(OxyMouseEventArgs e)
  {
    base.Started(e);
    DoSomethingWithPoint(e);
  }

  private void DoSomethingWithPoint(OxyMouseEventArgs e)
  {
    var series = PlotView.ActualModel.GetSeriesFromPoint(e.Position) as ScatterSeries; // Or other type of series...
    if (series == null) return;

    var nearestPoint = series.GetNearestPoint(e.Position, false); // Possible set interpolate parameter to true.
    if (nearestPoint == null) return;

    var dataPoint = nearestPoint.DataPoint;
    var scatterPoint = series.Points.FirstOrDefault(x => Equals(x.X, dataPoint.X) && Equals(x.Y, dataPoint.Y));

  // Do whatever you want with the point.
  }

  public override void Completed(OxyMouseEventArgs e)
  {
    // Do nothing to avoid closing the tracker.
  }
}

然后将这个代码添加到你的PlotController中:

var mouseButton = OxyMouseButton.Left // Or whatever button you want the event to be fired with.
yourPlotController.BindMouseDown(mouseButton, 
    new DelegatePlotCommand<OxyMouseDownEventArgs>((view, controller, args) =>
      controller.AddMouseManipulator(view, new DoSomethingWithPointTrackerManipulator (view), args)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接