Skip to content

Commit 3de6475

Browse files
Plot: add figure and data border (ScottPlot#5024)
* Plot: Use the Render() method of the Sync object to uniformly call RenderManager.Render(). * PixelRect: Added a conversion method from SKRectI to PixelRect. * Plot: Update rendering boundaries The boundary of the Render(IMultiplot, SKSurface) method has been changed from LocalClipBounds to DeviceClipBounds to ensure that the rendered content fits within the device's clipping range * Plot: Add border styles and rendering features (ScottPlot#4854) * Plot: FigureBorder and DataBorder * Update CHANGELOG.md --------- Co-authored-by: Scott W Harden <swharden@gmail.com>
1 parent a1667d3 commit 3de6475

8 files changed

Lines changed: 56 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ _Not yet on NuGet..._
2323
* Legend: Added the ability to customize default marker shape for legend items (#5005, #5006) @aespitia
2424
* Pie: Added a `Radius` property (instead of forcing `1.0`) and improved rendering and SVG export (#5020) @CoderPM2011 @aespitia
2525
* Data Streamer: Added `FillY` and related properties so streaming plots support filled ares (#4948, #5023) @manaruto @Stephanowicz
26+
* Plot: Added `FigureBorder` and `DataBorder` for displaying custom borders on plots and subplots (#4854, #5024) @CoderPM2011
2627

2728
## ScottPlot 5.0.55
2829
_Published on [NuGet](https://www.nuget.org/profiles/ScottPlot) on 2025-03-22_

src/ScottPlot5/ScottPlot5 Cookbook/Recipes/General/Styling.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,36 @@ public override void Execute()
354354
}
355355
}
356356

357+
public class PlotBorder : RecipeBase
358+
{
359+
public override string Name => "Plot Border";
360+
public override string Description => "Plots can be assigned borders to draw around the figure or data area.";
361+
362+
[Test]
363+
public override void Execute()
364+
{
365+
myPlot.Add.Signal(Generate.Sin());
366+
myPlot.Add.Signal(Generate.Cos());
367+
368+
myPlot.FigureBorder = new()
369+
{
370+
Color = Colors.Magenta,
371+
Width = 3,
372+
Pattern = LinePattern.Dotted,
373+
};
374+
375+
myPlot.DataBorder = new()
376+
{
377+
Color = Colors.Green,
378+
Width = 3,
379+
Pattern = LinePattern.DenselyDashed,
380+
};
381+
382+
// the hide axis frame lines so our custom border is the only one
383+
myPlot.Axes.Frame(false);
384+
}
385+
}
386+
357387
public class SetFontName : RecipeBase
358388
{
359389
public override string Name => "Set Font by Name";

src/ScottPlot5/ScottPlot5/Interfaces/IMultiplot.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public static Image Render(this IMultiplot multiplot, int width, int height)
6565
/// </summary>
6666
public static void Render(this IMultiplot multiplot, SKSurface surface)
6767
{
68-
multiplot.Render(surface.Canvas, surface.Canvas.LocalClipBounds.ToPixelRect());
68+
multiplot.Render(surface.Canvas, surface.Canvas.DeviceClipBounds.ToPixelRect());
6969
}
7070

7171
/// <summary>

src/ScottPlot5/ScottPlot5/Plot.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public class Plot : IDisposable
2323
/// </summary>
2424
public BackgroundStyle DataBackground = new() { Color = Colors.Transparent };
2525

26+
public LineStyle FigureBorder { get; set; } = LineStyle.None;
27+
public LineStyle DataBorder { get; set; } = LineStyle.None;
28+
2629
public IZoomRectangle ZoomRectangle { get; set; }
2730
public double ScaleFactor { get => ScaleFactorF; set => ScaleFactorF = (float)value; }
2831
internal float ScaleFactorF { get; private set; } = 1.0f;
@@ -253,7 +256,7 @@ public void Render(SKCanvas canvas, PixelRect rect)
253256
/// </summary>
254257
public void Render(SKSurface surface)
255258
{
256-
RenderManager.Render(surface.Canvas, surface.Canvas.LocalClipBounds.ToPixelRect());
259+
Render(surface.Canvas, surface.Canvas.LocalClipBounds.ToPixelRect());
257260
}
258261

259262
public Image GetImage(int width, int height)

src/ScottPlot5/ScottPlot5/Primitives/LineStyle.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,14 @@ public void Render(SKCanvas canvas, PixelLine line, SKPaint paint)
126126
Drawing.DrawLine(canvas, paint, line, this);
127127
}
128128

129-
public void Render(SKCanvas canvas, PixelRect rect, SKPaint paint)
129+
public void Render(SKCanvas canvas, PixelRect rect, SKPaint paint, bool contract = false)
130130
{
131131
if (!IsVisible)
132132
return;
133133

134+
if (contract)
135+
rect = rect.Contract(Width / 2);
136+
134137
Pixel[] pixels =
135138
[
136139
rect.BottomLeft,

src/ScottPlot5/ScottPlot5/Primitives/PixelRect.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,4 +422,9 @@ public static PixelRect ToPixelRect(this SKRect rect)
422422
{
423423
return new PixelRect(rect.Left, rect.Right, rect.Bottom, rect.Top);
424424
}
425+
426+
public static PixelRect ToPixelRect(this SKRectI rect)
427+
{
428+
return new PixelRect(rect.Left, rect.Right, rect.Bottom, rect.Top);
429+
}
425430
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace ScottPlot.Rendering.RenderActions;
2+
3+
public class RenderBorders : IRenderAction
4+
{
5+
public void Render(RenderPack rp)
6+
{
7+
rp.Plot.FigureBorder.Render(rp.Canvas, rp.FigureRect, rp.Paint, contract: true);
8+
rp.Plot.DataBorder.Render(rp.Canvas, rp.DataRect, rp.Paint);
9+
}
10+
}

src/ScottPlot5/ScottPlot5/Rendering/RenderManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class RenderManager(Plot plot)
2727
new RenderActions.RenderGridsAbovePlottables(),
2828
new RenderActions.RenderLegends(),
2929
new RenderActions.RenderPanels(),
30+
new RenderActions.RenderBorders(),
3031
new RenderActions.RenderZoomRectangle(),
3132
new RenderActions.SyncGLPlottables(),
3233
new RenderActions.RenderPlottablesLast(),

0 commit comments

Comments
 (0)