Skip to content

Frame: Unexpected behavior across Frame(), Frameless(), and AddRadar() #1112

@arthurits

Description

@arthurits

Frame around RadarPlot

Description: When adding a RadarPlot the default settings give the plot a frameless appearance. Aesthetically, frame around the radar plot area might be preferred by some users, so the natural option is to call the Frame() method to draw the frame around. However, only the top and left frames are drawn, while the right and bottom are not.

Code example: The following code shows this unexpected behavior.

var plt = formsPlot1.Plot.AddRadar(_plotLux);
formsPlot1.Plot.Frame(visible: true);

image

This is not a big problem, since an approximated-framed RadarPlot (please note that the data area does not go right up to the edge of the plot) can actually be obtained, although it's slightly counterintuitive because the AddRadar function enables both the frame and the grid at the same time.

var plt = formsPlot1.Plot.AddRadar(_plotLux, disableFrameAndGrid: false);
formsPlot2.Plot.Grid(enable: false);

image

What's causing the issue?
The AddRadar method doesn't allow for independently disabling the frame and the grid:

public RadarPlot AddRadar(double[,] values, bool independentAxes = false, double[] maxValues = null, bool disableFrameAndGrid = true)
{
Color[] colors = Enumerable.Range(0, values.Length)
.Select(i => settings.PlottablePalette.GetColor(i))
.ToArray();
Color[] fills = colors.Select(x => Color.FromArgb(50, x)).ToArray();
RadarPlot plottable = new(values, colors, fills, independentAxes, maxValues);
Add(plottable);
if (disableFrameAndGrid)
{
Frameless();
Grid(enable: false);
}

Going down the rabbit hole, the Frameless() function is implemented this way:

public void Frameless()
{
foreach (var axis in settings.Axes)
axis.Hide();
}

And the code for hiding each axis is:

public void Hide()
{
AxisLine.IsVisible = false;
AxisTicks.MajorTickVisible = false;
AxisTicks.MinorTickVisible = false;
PixelSizeMinimum = 0;
PixelSizeMaximum = 0;
PixelSizePadding = 0;
}

It appears that hiding the axis also sets the private property PixelSizePadding to 0 (the one causing the issue). However, calling the Frame() method, as shown in the code at the very beginning, does not reset the value of this property, thus causing the bottom and right frames not to be drawn.

public void Frame(bool? visible = null, Color? color = null, bool? left = null, bool? right = null, bool? bottom = null, bool? top = null)
{
var primaryAxes = new Renderable.Axis[] { XAxis, XAxis2, YAxis, YAxis2 };
foreach (var axis in primaryAxes)
axis.Line(visible, color);
YAxis.Line(visible: left);
YAxis2.Line(visible: right);
XAxis.Line(visible: bottom);
XAxis2.Line(visible: top);
}

It's slightly counterintuitive that Frame() method just modifies the axis Visible property while the Frameless() method modifies the Visible and the three PixelSize... properties.

Possible solutions:

  1. Call AddRadar disabling frame and grid; later enable the grid (as shown above). That's effective but counterintuitive. This keeps the plot's data area smaller than the plot control.
  2. Modify the Frame() method in order to set back the three PixelSize... properties to their default values when the visible parameter is set to true. Note that the PixelSize... properties are private; and keep in mind that modifying them might cause unwanted side-effects.
  3. Modify the Frameless() method so that PixelSizePadding is set equal to 1 (that's enough to allow the bottom and right borders to be drawn when calling Frameless() first and Frame() later). This is the most radical solution, but it might not be appropriate in other contexts.

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