Skip to content

Repository files navigation

ProEssentials WinUI — Custom Y-Axis Labeling: Annotations vs Events

A ProEssentials v11 WinUI 3 .NET 10 demonstration of two distinct approaches to replacing the default numeric Y-axis labels with custom text — shown side-by-side in a single PesgoWinUI chart split into two stacked multi-axis sections.

ProEssentials WinUI Custom Y-Axis Labeling

➡️ gigasoft.com/examples


What This Demonstrates

A single PesgoWinUI chart with two independent Y-axis sections, each using a different technique to display custom Y-axis labels:

Section Approach Best For
Top Line Annotation Grid Lines Fixed labels known at design time
Bottom PeCustomGridNumber Event Dynamic labels — works after zoom/scroll

The chart-configuration code is identical to the WPF version of this example. The ProEssentials API does not change between interfaces; only the window plumbing differs.


ProEssentials Features Demonstrated

Multi-Axis Layout

Two subsets share one chart but each gets its own independent Y-axis section via MultiAxesSubsets:

Pesgo1.PeGrid.MultiAxesSubsets[0] = 1;  // top section — subset 0
Pesgo1.PeGrid.MultiAxesSubsets[1] = 1;  // bottom section — subset 1

Pesgo1.PeGrid.MultiAxesProportions[0] = 0.5f;
Pesgo1.PeGrid.MultiAxesProportions[1] = 0.5f;

Pesgo1.PeGrid.Option.MultiAxisStyle      = MultiAxisStyle.SeparateAxes;
Pesgo1.PeGrid.Option.MultiAxesSeparators = MultiAxesSeparators.Medium;

// End-user can drag the separator to resize sections
Pesgo1.PeUserInterface.Allow.MultiAxesSizing = true;

WorkingAxis selects which axis subsequent property assignments apply to. Always reset to 0 when finished configuring axes.


Top Axis — Line Annotation Method (Example 005 technique)

The default numeric Y scale is hidden and replaced by LineAnnotationType.GridLine and GridTick annotations:

Pesgo1.PeGrid.WorkingAxis = 0;

// Hide the default numeric scale
Pesgo1.PeGrid.Option.ShowYAxis = ShowAxis.Empty;

// Fix the range so annotation values land at meaningful positions
Pesgo1.PeGrid.Configure.ManualScaleControlY = ManualScaleControl.MinMax;
Pesgo1.PeGrid.Configure.ManualMinY          = 0.0;
Pesgo1.PeGrid.Configure.ManualMaxY          = 1500.0;

// Annotations targeted to axis 0 via YAxisAxis[i]
Pesgo1.PeAnnotation.Line.YAxisAxis[0] = 0;
Pesgo1.PeAnnotation.Line.YAxis[0]     = 200;
Pesgo1.PeAnnotation.Line.YAxisType[0] = LineAnnotationType.GridLine;
Pesgo1.PeAnnotation.Line.YAxisText[0] = "|LLow Value";

// ... more GridLine and GridTick entries ...

Pesgo1.PeAnnotation.Line.LeftMargin = "Medium Value ";  // longest label
Pesgo1.PeAnnotation.Show            = true;
Pesgo1.PeFont.LineAnnotationTextSize = 100;

YAxisAxis[i] = 0 is what makes annotations appear only in the top axis region. Without it, annotations default to axis 0, but setting it explicitly is required for multi-axis correctness and clarity.

GridTick adds intermediate tick marks without a label — useful for subdividing the range between labeled gridlines.

Trade-off: label values must be known at design time. If the user zooms, new intermediate values appear as unlabeled numbers.


Bottom Axis — PeCustomGridNumber Event Method (Example 132 technique)

CustomGridNumbersY = true is set while WorkingAxis = 1 so it applies only to the bottom axis:

Pesgo1.PeGrid.WorkingAxis = 1;
Pesgo1.PeGrid.Option.CustomGridNumbersY = true;

The PeCustomGridNumber event fires for each grid line during image construction. The handler checks e.AxisIndex (1 = bottom axis) and e.AxisType (0 = left Y) before rewriting e.NumberString:

private void Pesgo1_PeCustomGridNumber(object sender,
    Gigasoft.ProEssentials.EventArg.CustomGridNumberEventArgs e)
{
    if (e.AxisIndex != 1 || e.AxisType != 0) return;

    int level = (int)Math.Round(Math.Abs(e.NumberValue));
    e.NumberString = e.NumberValue >= 0
        ? $"+ {level}"
        : $"− {level}";
}

WinUI has no XAML designer, so the event is wired in the constructor rather than from a XAML attribute:

Pesgo1.Loaded += new RoutedEventHandler(Pesgo1_Loaded);
Pesgo1.PeCustomGridNumber += Pesgo1_PeCustomGridNumber;

Trade-off: slightly more code, but works correctly after any zoom or scroll because the event fires fresh for whatever values appear on screen.

Warning: do not place breakpoints inside this event handler. It fires during image construction; a breakpoint can trigger a recursive paint. Use Debug.WriteLine or trace logging instead.


Axis Color Sync

Axis label and grid number colors are synced to subset data colors so the user can visually associate each Y axis with its data line. WinUI uses Windows.UI.Color where WPF used System.Windows.Media.Color — same FromArgb(a, r, g, b) signature:

Pesgo1.PeGrid.WorkingAxis  = 0;
Pesgo1.PeColor.YAxis          = ColorTop;     // cyan
Pesgo1.PeColor.SubsetColors[0] = ColorTop;

Pesgo1.PeGrid.WorkingAxis  = 1;
Pesgo1.PeColor.YAxis          = ColorBottom;  // orange
Pesgo1.PeColor.SubsetColors[1] = ColorBottom;

Controls

Input Action
Left-click drag Zoom box
Drag separator Resize top / bottom sections
Right-click Context menu — export, print, customize

Prerequisites

  • Visual Studio 2026 with the .NET desktop development and Windows application development workloads
  • .NET 10 SDK
  • Internet connection for NuGet restore

No XAML designer: Visual Studio has no XAML designer for WinUI 3 in any edition, so the chart is declared in markup (<pe:PesgoWinUI x:Name="Pesgo1" />) rather than dragged from the Toolbox. That is a Windows App SDK limitation, not a ProEssentials one. Nothing needs to be installed beyond the NuGet packages for this project to build and run.

Two more WinUI window differences show up in this sample: a WinUI Window is not a Control, so it has no XAML Height/Width (the size is set with SizeAndCenterWindow() in the constructor) and no Loaded event — chart initialization runs from the chart's own Loaded, which is where it belongs in every interface anyway.


How to Run

1. Clone this repository
2. Open CustomYAxisLabelingWinUI.sln in Visual Studio 2026
3. Build → Rebuild Solution (restores NuGet packages automatically)
4. Press F5

NuGet Package

References ProEssentials.Chart.Net10.WinUI. Package restore is automatic on build.

The AnyCpu package embeds the native rendering engines inside the assembly and unpacks the one matching the running process at run time, so there is no native DLL to copy or deploy alongside your app. It also carries the control's .pri, whose resources are merged into your app's own .pri at build time.


Evaluation Watermark

The nuget.org package is the evaluation build and draws an "Evaluating ProEssentials" watermark across the chart. A licensed installation replaces the assembly and the watermark goes away — everything else behaves identically.


Deploying a WinUI App

WinUI deploys differently than WPF and WinForms:

  • A .NET app is not a single exe — ship the entire build or publish output folder, never a hand-picked subset.
  • The target machine needs two runtimes: the .NET 10 Desktop Runtime and the Windows App SDK Runtime. Or publish self-contained with -p:WindowsAppSDKSelfContained=true.
  • Your development machine already has both, so it will run from an under-filled folder. Always validate on a clean machine.

Related Examples


License

Example code is MIT licensed. ProEssentials requires a commercial license for continued use.

About

WinUI 3 custom Y-axis labels, .NET 10 C# how-to - two techniques in one multi-axis scientific chart: line-annotation grid lines set at design time, and the PeCustomGridNumber event for runtime, zoom-safe labels. PesgoWinUI, Direct2D.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages