Skip to content

Bar: Add option to render labels on top#4886

Merged
swharden merged 10 commits intoScottPlot:mainfrom
manaruto:main
Jun 16, 2025
Merged

Bar: Add option to render labels on top#4886
swharden merged 10 commits intoScottPlot:mainfrom
manaruto:main

Conversation

@manaruto
Copy link
Contributor

This pull request improves how bar chart value labels are rendered by utilizing the IRenderLast interface. This ensures that labels are drawn at the top level. The change affects Bar, BarPlot, and introduces a Clone() method for LabelStyle.

  • Fixes overlapping label issue where value labels could be hidden by one before it.

Changes Made

Bar.cs

  • Implemented IRenderLast in the Bar class.
    
  • Split rendering logic: Render() draws the bar body, while RenderLast() renders the label on top.
    
  • Stored PixelRect and LabelStyle (cloned) for deferred rendering.
    
public void Render(RenderPack rp, IAxes axes, SKPaint paint, LabelStyle labelStyle)
{
    // Render bar body and store label data for later
}

public void RenderLast(RenderPack rp)
{
    // Render label safely using a new SKPaint instance
}

BarPlot.cs

  • Now implements IRenderLast.
    
  • Calls RenderLast() on each individual Bar it contains.
    
  • Updated RenderLast() method to be virtual (same as Render()), allowing future extensibility.
    
    public virtual void RenderLast(RenderPack rp)
    {
        foreach (Bar bar in Bars)
        {
            bar.RenderLast(rp);
        }
    }

LabelStyle.cs

  • Added Clone() method to safely copy all styling properties to avoid shared state or mutation between render passes.
    
public LabelStyle Clone()
{
    return new LabelStyle
    {
        // All public properties are copied here
    };
}

Note: I included a Clone() method in LabelStyle to defensively copy the style during Render(...). It may not be strictly necessary, but it's added to ensure stable label appearance in RenderLast().

Before / After

Before: Value labels could appear behind the one above it if there is no space.

After: Labels are now rendered on top of all.

Note: With this update, bar value labels are rendered after all other plot elements, including axis lines and grid ticks.

label at top

@swharden
Copy link
Member

Thanks for this @manaruto! I'm refining the code a bit to prevent duplication and will merge shortly.

There's a new cookbook recipe that looks like this:

bars.LabelsOnTop = true;

image

@swharden swharden changed the title Render Bar Labels at the top level, using IRenderLast Bar: Add option to render labels on top Jun 16, 2025
@swharden swharden enabled auto-merge (squash) June 16, 2025 00:45
@swharden swharden merged commit cd750f5 into ScottPlot:main Jun 16, 2025
3 checks passed
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

Successfully merging this pull request may close these issues.

Bar: add option to have text labels render last

2 participants