Skip to content

Function: AutoScale offscreen function causes crash #3618

@Matthew-Chidlow

Description

@Matthew-Chidlow

Issue:
If plot contains a function which is entirely outside the rendered area and you try
to use auto scale it will crash.

I believe the issue could be in several places.

Firstly in FunctionPlot:

public void Render(RenderPack rp)
{
var unitsPerPixel = Axes.XAxis.GetCoordinateDistance(1, rp.DataRect);
double max = double.MinValue;
double min = double.MaxValue;
using SKPath path = new();
bool penIsDown = false;
for (double x = MinX; x <= MaxX; x += unitsPerPixel)
{
double y = Source.Get(x);
if (y.IsInfiniteOrNaN())
{
penIsDown = false; // Picking up pen allows us to skip over regions where the function is undefined
continue;
}
max = Math.Max(max, y);
min = Math.Min(min, y);
Pixel px = Axes.GetPixel(new(x, y));
if (penIsDown)
{
path.LineTo(px.ToSKPoint());
}
else
{
path.MoveTo(px.ToSKPoint());
penIsDown = true;
}
}
using SKPaint paint = new();
LineStyle.ApplyToPaint(paint);
rp.Canvas.DrawPath(path, paint);
LastRenderLimits = new AxisLimits(XRange.Min, XRange.Max, min, max);
}

If no points are inside the render area then the minX and maxX used to report the GetAxisLimits() on the next render will remian:

double max = double.MinValue; 
double min = double.MaxValue;

Then in FractionalAutoScaler.GetAxisLimits() it calls GetDataLimits() which will be polluted but the plots GetAxisLimits()
so that Left == Right however they are either double.MinValue or double.MaxValue in which case adding or subtracting 1 to then won't do anything because 1 is outside the precision range so the HasArea check will fail because Left == Right.

Not sure where the right place to fix things would be.

ScottPlot Version: 5.0.24

Code Sample:

I found the bug clicking middle click in a winforms interactive plot but this code also causes it.

var plot = new Plot();
plot.Add.Function(new FunctionSource(x => x)
{
  RangeX = new CoordinateRange(-1, 1)
});
plot.Axes.SetLimits(-10, -9, -10, -9);
plot.SavePng("offscreen.png", 400, 400);
plot.Axes.AutoScale();
plot.SavePng("crash.png", 400, 400);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions