Skip to content

Index was outside bounds of the array -- Occurs if zooming into an area where no SignalXY values exist #4261

@RFBomb

Description

@RFBomb

Issue:
I encountered a hard crash when attempting to zoom into a WPF plot using the native functionality (middle click + drag -> zoom).
The issue was 'Index was outside the bounds of the array', being generated from the SignalXYSourceDoubleArray class.

This first photo occurs at an interesting spot, I think reached that point due to JIT doing its job, because I successfully zoomed a few times before throwing the error
image

This exception seems to occur as soon as entering the method (which blows my mind a bit). This was taken on the first time zooming after loading in the file.
image

For the record here, this library is great and my application works successfully on the various files I throw at it, except for (so far) one file. The files I'm working with are roughly 20-40MB xml files filled out in the following format :

<slot PollingMode=Edge/Poll>
     <item><timestamp>1123123</timestamp><value>0</value></item>
     <item><timestamp>1123423</timestamp><value>1</value></item>
</slot>

When in PollingMode=Edge, I manipulate the values to create a square wave using a scatter plot (if there is a better plot let me know!)
When in PollingMode=Poll, I create an array of X values and an array of Y values, and create a SignalXY plot.

Now, I've determined that the root of this is that I was zooming in on a section of the plot where the SignalXY does not exist, as shown below. Note that the blue and orange lines on right are the only data available to those signal plots, and exist outside the zoom range.

image

ScottPlot Version: 5.0.39

Code Sample: See http://scottplot.net/faq/repro/ for tips about creating reproducible code samples

private void CreateTheProblem()
{
    var scatterX = new double[20] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
    var scatterY = new double[20] { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 };

    var signalX = new double[5] { 16, 17, 18, 19, 20 };
    var signalY = new double[5] { -20, 1, 15, 15, 10};

    var sig = MyPlot.Plot.Add.SignalXY(signalX, signalY, ScottPlot.Colors.Blue);
    var scat = MyPlot.Plot.Add.Scatter(scatterX, scatterY, ScottPlot.Colors.Red);

    sig.Axes.YAxis = MyPlot.Plot.Axes.Left;
    scat.Axes.YAxis = MyPlot.Plot.Axes.Right;
    scat.Axes.XAxis = MyPlot.Plot.Axes.Bottom;
    sig.Axes.XAxis = MyPlot.Plot.Axes.Bottom;
    MyPlot.Refresh();
// once view is loaded, simply zoom into an area of the plot that does not have any SignalXY drawn
}

Note : Adjusting so they have different X axes has no effect on this issue. BUT, Scatter does not produce the issue, only SignalXY does, which I need to use for both performance reasons and inconsistency of raw data x values.

Secondary Note : Simply zooming in and out with your scroll wheel will also cause this problem, but it can also trigger the fault on line 77, because GetLastPointX incorrectly returned an index value less than GetFirstPointX

throw new InvalidDataException("Xs must contain only ascending values. " + $"The value at index {num} ({Xs[num]}) is greater than the value at index {num2} ({Xs[num2]})");
Relevant Stack Trace
       at ScottPlot.DataSources.SignalXYSourceDoubleArray.GetPixelsToDrawHorizontally(RenderPack rp, IAxes axes, ConnectStyle connectStyle) in ScottPlot.DataSources\SignalXYSourceDoubleArray.cs:line 75
       at ScottPlot.Plottables.SignalXY.Render(RenderPack rp) in ScottPlot.Plottables\SignalXY.cs:line 232
       at ScottPlot.Rendering.RenderActions.RenderPlottables.Render(RenderPack rp) in ScottPlot.Rendering.RenderActions\RenderPlottables.cs:line 21
       at ScottPlot.Rendering.RenderManager.RenderOnce(SKCanvas canvas, PixelRect rect)
       at ScottPlot.Plot.Render(SKCanvas canvas, PixelRect rect) in ScottPlot\Plot.cs:line 207
       at SkiaSharp.Views.WPF.SKElement.OnRender(DrawingContext drawingContext)
       at System.Windows.UIElement.Arrange(Rect finalRect)
       at System.Windows.ContextLayoutManager.UpdateLayout()
       at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs:line 179
    --- End of stack trace from previous location ---
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs:line 203
       at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at App.Main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions