Skip to content

Repository files navigation

ProEssentials WinUI — Mouse Interaction: Coordinate Tracking & Hotspots

A ProEssentials v11 WinUI 3 .NET 10 demonstration of two complementary mouse-interaction techniques shown together in a single PegoWinUI dual-Y-axis chart.

ProEssentials Mouse Interaction Hotspots

➡️ gigasoft.com/examples


What This Demonstrates

Technique API Surface Best For
Tooltip — both Y values at cursor ConvPixelToGraph + PeCustomTrackingDataText Reading interpolated values at any position, between data points
Status bar — named element under cursor GetHotSpot + SearchSubsetPointIndex Identifying chart elements by name, driving click actions

Both techniques run simultaneously from the same chart. Move the mouse to see them work together.

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


ProEssentials Features Demonstrated

Dual Y-Axis (Right Y)

The last subset is assigned to the right Y axis via RYAxisComparisonSubsets:

Pego1.PePlot.RYAxisComparisonSubsets = 1;   // last 1 subset → right Y
Pego1.PePlot.Method                  = GraphPlottingMethod.PointsPlusSpline;
Pego1.PePlot.MethodII                = GraphPlottingMethodII.Line; // right Y style

Pego1.PeString.YAxisLabel  = "Units Sold";
Pego1.PeString.RYAxisLabel = "Market Share (%)";
Pego1.PeColor.RYAxis       = GoldColor;  // sync axis color to subset color

Technique 1 — ConvPixelToGraph Tooltip (Example 007)

ConvPixelToGraph converts mouse pixel coordinates to data-unit coordinates. Called twice — once per Y axis — to read both scales at the cursor position:

private void Pego1_PeCustomTrackingDataText(object sender,
    Gigasoft.ProEssentials.EventArg.CustomTrackingDataTextEventArgs e)
{
    // WinUI returns WinRT geometry types here; WPF returned System.Windows.Point/Rect
    Windows.Foundation.Point pt = Pego1.PeUserInterface.Cursor.LastMouseMove;
    Windows.Foundation.Rect  r  = Pego1.PeFunction.GetRectGraph();
    if (!r.Contains(pt)) return;

    int nA = 0, nX = (int)pt.X, nY = (int)pt.Y;
    double fX = 0, fLY = 0, fRY = 0;

    // Left Y axis
    Pego1.PeFunction.ConvPixelToGraph(ref nA, ref nX, ref nY, ref fX, ref fLY,
                                       false, false, false);
    // Right Y axis — reset coords then call again with rightAxis = true
    nX = (int)pt.X; nY = (int)pt.Y; nA = 0;
    Pego1.PeFunction.ConvPixelToGraph(ref nA, ref nX, ref nY, ref fX, ref fRY,
                                       true, false, false);

    e.TrackingText = $"Left Y  ←  {fLY:0.0}  (units)\n{fRY:0.0}  (%)  →  Right Y";
}

Key points:

  • TrackingCustomDataText = true activates the event
  • e.TrackingText replaces the default tooltip string
  • Works continuously between data points — values are interpolated
  • TrackingPromptTrigger == CursorMove means a keyboard arrow key moved the cursor to a snapped data point — read PeData.Y directly instead

Technique 2 — GetHotSpot Status Bar (Example 014)

GetHotSpot() returns the named chart element under the current mouse position. The PointerMoved handler updates the status TextBlock:

private void Pego1_MouseMove(object sender, PointerRoutedEventArgs e)
{
    Gigasoft.ProEssentials.Structs.HotSpotData ds = Pego1.PeFunction.GetHotSpot();

    if (ds.Type == HotSpotType.DataPoint)
    {
        // ds.Data1 = subset index, ds.Data2 = point index
        float val = Pego1.PeData.Y[ds.Data1, ds.Data2];
        StatusText.Text = $"Data point  ·  {Pego1.PeString.SubsetLabels[ds.Data1]}"
                        + $"  ·  {Pego1.PeString.PointLabels[ds.Data2]}  ·  {val:0.0}";
    }
    else if (ds.Type == HotSpotType.Subset)
        StatusText.Text = $"Series legend  ·  {Pego1.PeString.SubsetLabels[ds.Data1]}";
    else if (ds.Type == HotSpotType.Point)
        StatusText.Text = $"Point label  ·  {Pego1.PeString.PointLabels[ds.Data1]}";
    else
    {
        // Not over a named element — find nearest data point
        Windows.Foundation.Point pt = Pego1.PeUserInterface.Cursor.LastMouseMove;
        Gigasoft.ProEssentials.Structs.Point nResult =
            Pego1.PeFunction.SearchSubsetPointIndex((int)pt.X, (int)pt.Y);
        if (nResult.X >= 0)
        {
            int s = Pego1.PeFunction.ClosestSubsetIndex;
            int p = Pego1.PeFunction.ClosestPointIndex;
            StatusText.Text = $"Nearest  ·  {Pego1.PeString.SubsetLabels[s]}"
                            + $"  ·  {Pego1.PeString.PointLabels[p]}"
                            + $"  ·  {Pego1.PeData.Y[s, p]:0.0}";
        }
    }
}

HotSpotData struct fields:

Field Meaning
ds.Type HotSpotType enum — DataPoint, Subset, Point, None, ...
ds.Data1 Subset index for DataPoint/Subset; point index for Point
ds.Data2 Point index for DataPoint

Enable hotspot hit testing:

Pego1.PeUserInterface.HotSpot.Data   = true;  // data points
Pego1.PeUserInterface.HotSpot.Subset  = true;  // series legends
Pego1.PeUserInterface.HotSpot.Point   = true;  // X-axis labels
Pego1.PeUserInterface.HotSpot.Size    = HotSpotSize.Large;

Wiring the pointer event in WinUI:

// WPF used MouseMove="Pego1_MouseMove" as a XAML attribute. In WinUI the chart
// control forwards pointer input to the native engine and marks the routed event
// Handled, so subscribe with handledEventsToo = true rather than a plain "+=".
Pego1.AddHandler(Microsoft.UI.Xaml.UIElement.PointerMovedEvent,
                 new Microsoft.UI.Xaml.Input.PointerEventHandler(Pego1_MouseMove),
                 true);

Cursor Snap

Pego1.PeUserInterface.Cursor.Mode                         = CursorMode.DataCross;
Pego1.PeUserInterface.Cursor.MouseCursorControl            = true;
Pego1.PeUserInterface.Cursor.MouseCursorControlClosestPoint = true;

MouseCursorControlClosestPoint = true makes the crosshair cursor snap to the nearest data point as the mouse moves, without requiring a click.


Data

4 subsets × 24 monthly points (Jan 2023 – Dec 2024) of synthetic regional sales data:

Subset Series Axis Color
0 North Left Y (units) Cyan
1 South Left Y (units) Green
2 West Left Y (units) Red
3 Market Share Right Y (%) Gold

Controls

Input Action
Mouse move Status bar identifies element under cursor
Mouse hover Tooltip shows both Y-axis values at cursor
Left-click drag Zoom box
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:PegoWinUI x:Name="Pego1" />) 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.


How to Run

1. Clone this repository
2. Open MouseInteractionHotspots.sln in Visual Studio 2026
3. Build → Rebuild Solution (NuGet restore is automatic)
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 — worth knowing before you ship:

  • 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. Alternatively 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 chart hit testing and cursor tracking, .NET 10 C# example. ConvPixelToGraph pixel-to-value tooltip on a dual-Y-axis chart · GetHotSpot identifies data points, series legends and axis labels live · ProEssentials PegoWinUI · Direct2D

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages