SignalXY: fix exception thrown when data runs outside the view window#4286
SignalXY: fix exception thrown when data runs outside the view window#4286swharden merged 11 commits intoScottPlot:mainfrom
Conversation
- Adds a validation check to check results of GetFirstPoint and GetLastPoint
|
fix would be required for both horizontal and vertical functions |
|
我也发现了这个bug,希望快点发布新版
|
|
ScottPlot/src/ScottPlot5/ScottPlot5/DataSources/SignalXYSourceDoubleArray.cs Lines 100 to 102 in 743c942 That's the whole problem with this check. It is really unnecessary and does not check anything completely. We already used binary search before it, and only after it we check that the array is sorted (which allows us to use binary search), and only by 2 points, which are relatively randomly selected depending on the Plot display settings. So we may realize that the array is not sorted, or we may not realize it, it depends on how lucky we are. The further code is resistant to wrong index order and correctly returns an empty list, so you don't need to make an early return. To summarize: you have added additional checks to prevent errors in the check, which is not really necessary (IMHO). @swharden had some considerations when he added this check. But personally I'm in favor of just removing it. |
|
This PR fixed two issues though: it was crashing applications (including demo) if scatter and SignalXY exist on same plot and you zoom in where no signalXY is displayed. The crash was due to one of two scenarios:
Either way, some validation needs to occur here to squash the bug, as I don't believe it has to do with the index search. The bug is 100% reproduceable. |
|
Here is you reproduce code (but in Winforms) var scatterY = Generate.SquareWave(/*20*/ 10, 2);This PR: WithValidateFix.mp4This PR, but WithoutValidateFix.mp4It looks like your fix breaks the interpolation on the outer points due to the early return.
If the start index is larger than the end index, it is an indicator that the number of points inside is empty. Further code handles this correctly. Moreover, it correctly handles external points and interpolation by them.
I have not been able to reproduce this. |
|
I will retest and upload a video of it crashing, along with a demo in winforms and wpf that is reproducible. I was able to reproduce this on two separate computers with fresh pulls of the library. You also zoom in on the signal area, that may be why yours is successful. I was zooming to the left of the start of the area, where the scatter exists but there are no values for the signalXY. Also, if it weren't an issue I shouldn't have been hitting the exceptions screenshotted in the related issue |
SignalXY.Zoom.Bug.Demo.2024-09-27.19-00-18.mp4 |
|
A very handy example, thank you. I'm not arguing that there is a bug that throws an exception in the original version. If we decide to keep this check, then your PR should be adjusted to bypass the accending check in case of “invalid” indexes, but still let them go further down the code. (the missing lines when zooming deep inside the interval are present in your PR example).
I was able to reproduce the Exception from the first case as you describe. I don't know why it displays dataIndexLast == 0 in the debugger. In fact dataIndexLast == -1 if you catch that point before the Exception. (Which is also correct for the code that follows, but the check doesn't take this into account) |
|
@StendProg I understand now, sorry for being abrasive/defensive there. Removing the exception does resolve the issue, and I was able to see after some additional testing that the I was also able to reproduce the interpolation issue you mentioned while my early escape was included. I'm uploading a new commit that removes the check altogether. Additionally, if the visible range length is 0, the binary search will always return index 0, which results in Finally, I suspected that DataLogger may have the same problem because it is so similar, so I tested it. DataLogger does not have the same issue, because (unsure why this occurs) it frames the plot and prevents adjustment of X/Y. (datalogger is green in video) SignalXY.Zoom.Bug.Demo.2024-09-28.08-33-02.mp4edit: It seems that validation exception is unit tested. So maybe it only checks for the exception when |
previously it would throw an exception if the signal xy plot was outside the data area
|
Hi @RFBomb and @StendProg, thanks for your feedback! This issue/PR reveals that the ascending value checker could fail if SignalXY data ran outside the data area. The original solution recommended by this PR was to remove the ascending value checker. Indeed, it's not a thorough check (because inspecting every X value in the entire dataset on every frame render would be to costly). While not completely thorough, it catches many cases. Without such a check, users who feed non-ascending X values into a SignalXY plot will have no negative feedback indicating there was a problem, and the plot may have confusing artifacts without a clear explanation. I found this from personal use when I accidentally used a SignalXY instead of a Scatter plot. If there's a better way to check for ascending values that isn't a negative performance impact, I'm happy to implement such an improvement! To correct the short term issue, I added tests that replicated the bug and added a check to avoid it, while preserving the original exception for users who accidentally use SignalXY to plot non-ascending X values. |
|
Yea, other than brute-forcing a check across the collection, which is really inefficient, I don't see a better check than the one that was originally implemented, or the one I had put in with the validation method initially (which was non-exhaustive). But i like the IsValid property being added, it's an elegant solution to various issues. |
Resolves #4261 by adding a validation check to check results of GetFirstPoint and GetLastPoint.
For some reason, I was only able to reproduce this bug when a plot had both a scatter and a signalXY.
Code to reproduce ( I pasted this into the SignalXY tester in the WPF demo and called it during constructor)