-
Notifications
You must be signed in to change notification settings - Fork 981
Description
ScottPlot version v4.1.8-beta
Note: this might be related to #548 and maybe this function is just not yet supported for SignalPlotXY (then this is not a bug of course, but probably this function should then not be available to SignalPlotXY instead of returning false values).
There seems to be an issue with the results returned by IHasPoints.GetPointNearestX with a SignalPlotXY when the x values aren't consecutive integers starting at zero.
Here is an example to highlight the nearest point of a ScatterPlot (adapted from here)
public partial class MainWindow : Window
{
private readonly IHasPoints plottable;
private readonly ScatterPlot HighlightedPoint;
private int LastHighlightedIndex = -1;
public MainWindow()
{
InitializeComponent();
int sampleCount = 50;
double[] xs = new double[sampleCount];
double[] ys = new double[sampleCount];
Random rand = new Random(0);
for (int i = 0; i < 50; i++)
{
xs[i] = DateTime.Now.ToOADate() + i*10;
ys[i] = i > 0 ? ys[i - 1] + rand.NextDouble() - .5 : 0;
}
//plottable = plot.Plot.AddScatterPoints(xs, ys); // <-- this works as expected
plottable = plot.Plot.AddSignalXY(xs, ys);
HighlightedPoint = plot.Plot.AddPoint(0, 0);
HighlightedPoint.Color = System.Drawing.Color.Red;
HighlightedPoint.MarkerSize = 10;
HighlightedPoint.MarkerShape = MarkerShape.openCircle;
HighlightedPoint.IsVisible = false;
plot.Plot.XAxis.DateTimeFormat(true);
}
private void plot_MouseMove(object sender, MouseEventArgs e)
{
(double mouseCoordX, double mouseCoordY) = plot.GetMouseCoordinates();
// these results are incorrect when plottable is SignalPlotXY:
(double pointCoordX, double pointCoordY, int pointIndex) = plottable.GetPointNearestX(mouseCoordX);
// highlight the point of interest
HighlightedPoint.Xs[0] = pointCoordX;
HighlightedPoint.Ys[0] = pointCoordY;
HighlightedPoint.IsVisible = true;
tbPointCoord.Text = $"{pointCoordX:N1}, {pointCoordY:N1}";
tbIndex.Text = pointIndex.ToString();
if (LastHighlightedIndex != pointIndex)
{
LastHighlightedIndex = pointIndex;
plot.Render();
}
}
}With the ScatterPlot this works as expected. Changing the IHasPoints plottable to SignalPlotXY, GetPointNearestX now gives wrong results, the index always relates to x=0. This is especially striking when using DateTimeFormat(true) as here we provide DateTime.ToOADate() values as xs values, which e.g. are in the range of 44000 and above. So here, the determined index by GetPointNearestX is always the max index of the array (49 in the example case).
I guess this is because here
| int index = (int)((x - OffsetX) / SamplePeriod); |
SignalPlot but not for SignalPlotXY. Probably GetPointNearestX should be made virtual in SignalPlotBase and SignalPlotXY would need to override it with an implementation to determine the index based on the parameter value similar to here ScottPlot/src/ScottPlot/Plottable/ScatterPlot.cs
Lines 292 to 309 in 92ec055
| public (double x, double y, int index) GetPointNearestX(double x) | |
| { | |
| int from = MinRenderIndex ?? 0; | |
| int to = MaxRenderIndex ?? (Xs.Length - 1); | |
| double minDistance = Math.Abs(Xs[from] - x); | |
| int minIndex = 0; | |
| for (int i = from; i <= to; i++) | |
| { | |
| double currDistance = Math.Abs(Xs[i] - x); | |
| if (currDistance < minDistance) | |
| { | |
| minIndex = i; | |
| minDistance = currDistance; | |
| } | |
| } | |
| return (Xs[minIndex], Ys[minIndex], minIndex); | |
| } |