Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception of “an excessive number of separators,” for no deep zooming #1495

Open
guilhermeolisi opened this issue Apr 26, 2024 · 5 comments

Comments

@guilhermeolisi
Copy link

guilhermeolisi commented Apr 26, 2024

I’m using LiveChart2 (version 2.0.0-rc2) in an Avalonia 11 (version 11.0.9) project. My control includes 3 CartesianCharts, and I frequently need to zoom and pan these charts. However, I’m encountering a recurring exception related to “an excessive number of separators,” which causes my application to crash. This issue does not occur with deep zooming, but rather when I pan the chart or apply a moderate zoom.

The exception arises within the GetPossibleMaxLabelSize() method of the LiveChartsCore.CoreAxis class. After analyzing the source code, I attempted to circumvent the issue by setting values for MinZoomDelta and MinStep, but the problem persists. I also tried controlling the MaxLimit and MinLimit of the axis, yet the exception continues to be thrown.

I have captured the values of all axis properties and non-public members of each axis in my project at the time the exception occurred (using the debug tools of Visual Studio 2022). The data is included in the attached file of this message. Unfortunately, I am unable to pinpoint the source of the problem; the property and variable values do not seem to justify the exception. It’s possible that the instance when I retrieved the axis values differs from the moment the exception is thrown.

Any assistance would be greatly appreciated. I am very fond of LiveChart2; it’s an incredible tool for data visualization, but this exception is causing my app to crash frequently.

File with Axes data:
LiveChart2 Axis exception.txt

          Never mind, I got the issue.

This happens because when you zoom so deep then the double type has not enough precision to handle the current range, the axis is for sure stuck at an infinite loop.

I think I can fix this internally, while this is fixed you can set a limit in the axis zoom, for example in this case I force the zoom to stop at 1ms:

        XAxes = new Axis[]
        {
            new Axis
            {
                MinZoomDelta = TimeSpan.FromMilliseconds(1).Ticks,
            }
        };

Originally posted by @beto-rodriguez in #1076 (comment)

@guilhermeolisi
Copy link
Author

Good night, @beto-rodriguez,

I believe I have identified one of the causes of the exception under the conditions I previously described. To better understand the issue, I integrated the LiveCharts project directly into my project, rather than using the NuGet package, which allowed me to utilize debugging tools during the exception. I observed that the variable _stepCount equals 9984 upon entry into the GetPossibleMaxLabelSize() method in Chart 3 of my control, triggering the exception due toto adding 25 more steps (const double testSeparators = 25).

Chart 3, which is a ScrollBarChart (https://livecharts.dev/docs/Avalonia/2.0.0-rc2/samples.general.scrollable) designed for zooming and panning the main Chart (Chart 1), does not alter the minimum and maximum values of the axis. Consequently, _stepCount is not reset to zero in the Invalidate() method. _stepCount is employed solely to verify the number of steps in the foreach loop (var i in EnumerateSeparators(min, max, s)). Would declaring _stepCount as a local variable immediately before the foreach loop resolve the issue?

Best regards,

@batzen
Copy link

batzen commented May 1, 2024

I am also encountering this issue.

My use case is:
I have fixed axes and LineSeries which never change min/max or anything and they are bound to pre-allocated ObservableValue arrays (500 items).
The values are updated in intervals of 50 ms and resemble a progress display.
After some time, because i never trigger Invalidate this way i get an exception because of excessive separators from GetPossibleMaxLabelSize.

The resulting UI is:
image

@batzen
Copy link

batzen commented May 1, 2024

My current workaround is:

private static readonly FieldInfo? stepCountFieldInfo = typeof(Axis).BaseType!.GetField("_stepCount", BindingFlags.Instance | BindingFlags.NonPublic);

and inside my update loop:

++counter;

if (counter % 25 is 0)
{
    counter = 0;

    foreach (var axis in this.YAxes)
    {
        stepCountFieldInfo?.SetValue(axis, 0);
    }

    foreach (var axis in this.XAxes)
    {
        stepCountFieldInfo?.SetValue(axis, 0);
    }
}

@cpyfferoen
Copy link

This bug is prevalent especially when combining the "RealTime" and "Scrollable" examples - there are other issues as well with that - but I'll put them in a new issue

@mvphelps
Copy link

mvphelps commented May 17, 2024

Also seeing this in Avalonia apps. In my case I have some charts on my screen that are hidden. It is monitoring a long running process and certain things can trigger the charts to hide and show. However I'm getting this exception for one of my hidden charts - because Avalonia still causes it to paint - which bypasses the Invalidate method.

@beto-rodriguez I opened PR #1514 for this. This does fix it for my application and should address any other platform calling paints without invalidating. Let me know if you'd like any changes to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants