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

MarkerPlot: clip when outside data area #1423

Closed
lucabat opened this issue Nov 5, 2021 · 2 comments · Fixed by #1459
Closed

MarkerPlot: clip when outside data area #1423

lucabat opened this issue Nov 5, 2021 · 2 comments · Fixed by #1459
Labels
BUG unexpected behavior

Comments

@lucabat
Copy link
Contributor

lucabat commented Nov 5, 2021

Bug Report

Issue:
I'm using a point and a crosshair to highlight a specific point in a graph.
The crosshair works as expected but the point is rendered also when it goes outside the axis ranges.
This happens when the user moves the axis around until the point goes outside the axes ranges
(in the example below the point has coordinates (100,0)).

vNhLLTphdV

Reproducing:

The point is added when the graph is initialized

image

and then is just changed its coordinates in the following way (and its .IsVisible property to show/hide the point).
image

Maybe I'm doing something wrong in how I use a point, but I've followed this example:
https://scottplot.net/faq/mouse-position/#show-value-near-mouse-with-winforms

System Details

  • ScottPlot Version: 4.1.27
  • Operating System: Windows 10
  • Application Type: WPF
  • .NET Version: NET Framework 4.7.2
@lucabat lucabat added the BUG unexpected behavior label Nov 5, 2021
@PremekTill
Copy link
Contributor

I have also ran into this problem, and after some testing and having checked the source code, I believe it to be a problem with the recently added MarkerPlot type. First of all, when testing with other plot types, MarkerPlot (including AddPoint, which was changed to create a MarkerPlot in 4.1.27) is the only plot type to go out of bounds, as seen in the following screenshot:

marker_plot_bug

Second, after checking the source code, I have noticed that when rendering, most of the other Plottable types call the GDI.Graphics(Bitmap bmp, PlotDimensions dims, bool lowQuality = false, bool clipToDataArea = true) overload (see for example here), whereas MarkerPlot only uses the GDI.Graphics(Bitmap bmp, bool lowQuality = false, double scale = 1.0) version, which does not check for bounds (see here). As such, I believe that simply changing MarkerPlot to call the correct overload might be enough to fix this bug, though I'm not familiar enough with the rest of the codebase to be completely sure, there might have been a reason for calling a different overload in the first place (maybe to prevent the marker size from scaling?).

@AndXaf
Copy link

AndXaf commented Nov 20, 2021

Dear PremekTill,
I can tell that after I added the PlotDimensions to the second overload you are mentioning the plot area is fully respected - so perhaps it was just forgotten. See attachment:
MarkerPlot.zip

using System.Drawing;

namespace ScottPlot.Plottable
{
    public class MarkerPlot : IPlottable
    {
        public bool IsVisible { get; set; } = true;
        public int XAxisIndex { get; set; } = 0;
        public int YAxisIndex { get; set; } = 0;

        /// <summary>
        /// Horizontal position in coordinate space
        /// </summary>
        public double X { get; set; }

        /// <summary>
        /// Vertical position in coordinate space
        /// </summary>
        public double Y { get; set; }

        /// <summary>
        /// Marker to draw at this point
        /// </summary>
        public MarkerShape MarkerShape { get; set; } = MarkerShape.filledCircle;

        /// <summary>
        /// Size of the marker in pixel units
        /// </summary>
        public double MarkerSize { get; set; } = 10;

        /// <summary>
        /// Color of the marker to display at this point
        /// </summary>
        public Color Color { get; set; }

        /// <summary>
        /// Text to appear in the legend (if populated)
        /// </summary>
        public string Label { get; set; }

        public AxisLimits GetAxisLimits() => new(X, X, Y, Y);

        public LegendItem[] GetLegendItems()
        {
            LegendItem item = new()
            {
                label = Label,
                markerShape = MarkerShape,
                color = Color
            };

            return new LegendItem[] { item };
        }

        public void ValidateData(bool deep = false)
        {
            Validate.AssertIsReal(nameof(X), X);
            Validate.AssertIsReal(nameof(Y), Y);
        }

        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            if (!IsVisible)
                return;

            PointF point = new(dims.GetPixelX(X), dims.GetPixelY(Y));

            using Graphics gfx = Drawing.GDI.Graphics(bmp, dims, lowQuality);
            MarkerTools.DrawMarker(gfx, point, MarkerShape, (float)MarkerSize, Color);
        }
    }
}

@swharden swharden changed the title Point is not hidden when goes outside the visible cartesian space MarkerPlot: clip when outside data area Dec 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BUG unexpected behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants