鼠标在ScottPlot中的位置

本页记录了如何使用ScottPlot用户控件来确定鼠标光标的位置以及鼠标光标附近的数据点。

确定鼠标光标的位置

可以使用GetMouseCoordinates()ScottPlot控制方法。本例演示了如何使用Windows窗体,但所有ScottPlot控件都使用相同的技术。

private void formsPlot1_MouseMoved(object sender, MouseEventArgs e)
{
    (double x, double y) = formsPlot1.GetMouseCoordinates();
    Console.WriteLine($"Mouse at ({x}, {y})");
}

💡 职位报告人GetMouseCoordinates()不是以像素为单位。报告的X和Y值以坐标空间,并具有与绘图的水平轴和垂直轴相同的单位。

找到光标附近的数据点

有些绘图表具有公共方法,可以轻松确定哪个数据点最靠近鼠标光标。这使得实现“悬停时显示值”或“鼠标下突出显示点”等功能变得容易。

此示例演示如何在鼠标移动时显示距离光标最近的数据点。它是使用WinForms显示的,但代码与所有ScottPlot控件几乎相同。

private void formsPlot1_MouseMove(object sender, MouseEventArgs e)
{
    (double mouseCoordX, double mouseCoordY) = formsPlot1.GetMouseCoordinates();
    double xyRatio = formsPlot1.Plot.XAxis.Dims.PxPerUnit / formsPlot1.Plot.YAxis.Dims.PxPerUnit;
    (double pointX, double pointY, int pointIndex) = MyScatterPlot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
    Text = $"Point index {pointIndex} at ({pointX}, {pointY})";
}

高亮显示光标附近的数据点

由于很容易确定哪一个数据点距离光标最近,因此可以高亮显示该数据点并显示其位置。如果我们有一个显示数据点的蓝点散点图,突出显示单个点的一种方法是使用AddPoint()样式为空心红色圆圈,然后移动其位置以指示距离光标最近的点。

使用WinForms在鼠标附近显示值

此示例显示如何使用散点图绘制X/Y数据,然后高亮显示距离光标最近的点并显示其值(在窗口标题栏中)。

下载此演示的完整源代码

private readonly ScottPlot.Plottable.ScatterPlot MyScatterPlot;
private readonly ScottPlot.Plottable.ScatterPlot HighlightedPoint;
private int LastHighlightedIndex = -1;

public Form1()
{
    InitializeComponent();

    // create a scatter plot from some random data and save it
    Random rand = new Random(0);
    int pointCount = 20;
    double[] xs = ScottPlot.DataGen.Random(rand, pointCount);
    double[] ys = ScottPlot.DataGen.Random(rand, pointCount, multiplier: 1_000);
    MyScatterPlot = formsPlot1.Plot.AddScatterPoints(xs, ys);

    // Add a red circle we can move around later as a highlighted point indicator
    HighlightedPoint = formsPlot1.Plot.AddPoint(0, 0);
    HighlightedPoint.Color = Color.Red;
    HighlightedPoint.MarkerSize = 10;
    HighlightedPoint.MarkerShape = ScottPlot.MarkerShape.openCircle;
    HighlightedPoint.IsVisible = false;
}

private void formsPlot1_MouseMove(object sender, MouseEventArgs e)
{
    // determine point nearest the cursor
    (double mouseCoordX, double mouseCoordY) = formsPlot1.GetMouseCoordinates();
    double xyRatio = formsPlot1.Plot.XAxis.Dims.PxPerUnit / formsPlot1.Plot.YAxis.Dims.PxPerUnit;
    (double pointX, double pointY, int pointIndex) = MyScatterPlot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);

    // place the highlight over the point of interest
    HighlightedPoint.Xs[0] = pointX;
    HighlightedPoint.Ys[0] = pointY;
    HighlightedPoint.IsVisible = true;

    // render if the highlighted point chnaged
    if (LastHighlightedIndex != pointIndex)
    {
        LastHighlightedIndex = pointIndex;
        formsPlot1.Render();
    }

    // update the GUI to describe the highlighted point
    Text = $"Point index {pointIndex} at ({pointX:N2}, {pointY:N2})";
}

使用信号图

不同于使用GetPointNearest(x, y),信号图显示均匀分布的数据点,并且仅水平跟踪鼠标。使用信号图时,请调用GetPointNearestX(x)相反

下载此演示的完整源代码

private readonly ScottPlot.Plottable.SignalPlot MySignalPlot;

public Form1()
{
    InitializeComponent();

    // create and store a scatter plot
    double[] ys = ScottPlot.DataGen.RandomWalk(100_000);
    MySignalPlot = formsPlot1.Plot.AddSignal(ys);

    // Add a red circle we can move around later as a highlighted point indicator
    /* same code as above */
}

private void formsPlot1_MouseMove(object sender, MouseEventArgs e)(){
    // determine point nearest the cursor
    (double mouseCoordX, _) = formsPlot1.GetMouseCoordinates();
    (double pointX, double pointY, int pointIndex) = MySignalPlot.GetPointNearestX(mouseCoordX);

    // Highlight the point closest to the cursor
    /* same code as above */
}

笔记

考虑性能

定位离光标最近的点需要一个操作,该操作(1)在数据集中的每个点上循环,(2)每次光标的像素位置改变时都必须运行。当这两个点结合在一个大数据集上时,鼠标的交互性能可能会受到影响。对高鼠标交互感兴趣的用户应该考虑创建专门为其应用而设计的自己的用户控件。

并非所有绘图表都有鼠标辅助对象方法

但是,该功能很容易由用户实现。因为用户可以访问正在绘制的数据GetMouseCoordinates()这项任务相对简单。迭代每个数据点,以确定其与光标的距离,并记录最接近的数据点。

显示缩放

ScottPlot自动检测并补偿显示缩放,所以你可能不需要担心。不同的GUI系统对显示缩放的处理方式不同,因此这种检测逻辑存在于ScottPlot控件中。如果启用了显示缩放,则会自动缩放鼠标坐标,以匹配所显示位图的像素单位。

Windows窗体可能支持也可能不支持显示缩放,具体取决于哪个。NET平台,以及如何Program.cs已配置。自定义中的显示缩放选项。NET WinForms应用程序,请致电SetHighDpiMode().

有关更多信息,请参阅设置流程的默认DPI感知混合模式DPI扩展和支持DPI的API.