Implementing funnel charts in .NET MAUI

01What is it?
Implements and customize Syncfusion .NET MAUI Funnel Charts (SfFunnelChart). Use when implementing funnel charts, sales funnel visualization, conversion funnel analysis, process stage visualization, or marketing funnel. It stands out by giving implementing funnel charts in .NET MAUI a defined shape, so the agent asks for better context and returns a more usable result.
02Inputs
Context the agent needs: your goals, audience, constraints, and any source material the skill asks for.
03Output
A ready-to-use result: the analysis, copy, or recommendations the agent produces.
Install-only

Install as a package

Installs this one skill package for your coding agent, including any supporting files that skill ships with โ€” not every skill in the repository. Read the tutorial.

Terminal
$ npx skills add syncfusion/maui-toolkit-ui-components-skills --skill syncfusion-maui-toolkit-funnel-charts

Skill instructions

The instruction file for this skill. The skill also includes other files you need to install to use it.

SKILL.md

Implementing Funnel Charts in .NET MAUI

A comprehensive skill for implementing and customizing Syncfusion .NET MAUI Funnel Charts (SfFunnelChart). Funnel charts visualize data as progressively decreasing segments, ideal for representing stages in a process like sales pipelines, conversion funnels, or marketing campaigns.

When to Use This Skill

Use this skill when you need to:

  • Create funnel charts to visualize process stages (sales, marketing, conversion)
  • Display hierarchical data with progressively narrowing segments
  • Show conversion rates or drop-off analysis
  • Implement customizable funnel visualizations with data labels and legends
  • Export funnel charts as images

Component Overview

SfFunnelChart is a .NET MAUI control that creates beautiful funnel segments to analyze various stages in a process. Key capabilities include:

  • User Interaction: Selection, tooltips, and legend toggling
  • Data Labels: Display values with customizable placement and styling
  • Legend Support: Scrollable legends with item identification
  • Customization: Appearance, colors, gradients, spacing, and effects
  • Orientation: Vertical or horizontal funnel display
  • Exporting: Save charts as images

Documentation and Navigation Guide

Getting Started

๐Ÿ“„ Read: references/getting-started.md

  • NuGet package installation (Syncfusion.Maui.Toolkit)
  • Basic SfFunnelChart implementation (XAML and C#)
  • Creating view models and data models
  • Data binding with ItemsSource, XBindingPath, YBindingPath
  • Adding title, legend, tooltips, and data labels
  • Complete working example

Data Labels

๐Ÿ“„ Read: references/data-labels.md

  • Enabling data labels (ShowDataLabels property)
  • Label placement options (Auto, Inner, Center, Outer)
  • Context configuration (XValue, YValue display)
  • Label style customization (font, colors, margins, borders)
  • UseSeriesPalette for segment-colored labels

Appearance and Customization

๐Ÿ“„ Read: references/appearance.md

  • Custom PaletteBrushes for segment colors
  • Applying gradients (LinearGradientBrush, RadialGradientBrush)
  • Creating custom color schemes
  • GradientStops configuration
  • Visual design best practices

Legend

๐Ÿ“„ Read: references/legend.md

  • Defining and initializing ChartLegend
  • Legend visibility and placement (Top, Bottom, Left, Right)
  • Label style customization
  • Legend icon types
  • Floating legend with OffsetX/OffsetY
  • Toggle series visibility
  • Items layout and ItemTemplate
  • LegendItemCreated event

Tooltip

๐Ÿ“„ Read: references/tooltip.md

  • Enabling tooltips (EnableTooltip property)
  • Tooltip template customization
  • Binding context and data formatting
  • Custom tooltip appearance

Advanced Features

๐Ÿ“„ Read: references/advanced-features.md

  • Orientation (Vertical vs Horizontal)
  • Segment spacing configuration
  • Gap ratio and size settings
  • Visual effects and polish

Exporting

๐Ÿ“„ Read: references/exporting.md

  • Export chart as image
  • Export format options
  • Sharing and saving charts

Supporting file: references/advanced-features.md

Advanced Features in .NET MAUI Funnel Chart

This guide covers advanced customization features for SfFunnelChart, including orientation control, and segment spacing.

Table of Contents

Orientation

The Orientation property controls the rendering direction of funnel segments. The default is Vertical (bottom to top), but you can switch to Horizontal (right to left).

Available Orientations

  • Vertical (default): Segments arranged from bottom to top
  • Horizontal: Segments arranged from right to left

XAML

<chart:SfFunnelChart Orientation="Horizontal"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";
chart.Orientation = ChartOrientation.Horizontal;

this.Content = chart;

When to Use Each Orientation

Vertical (Default):

  • Traditional funnel representation
  • Best for top-to-bottom process flows
  • Works well with bottom-placed legends
  • Ideal for portrait layouts

Horizontal:

  • Left-to-right reading patterns
  • Better for landscape orientations
  • Works well with left/right-placed legends
  • Suitable for timeline-style visualizations

Complete Orientation Example

<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit">
    
    <VerticalStackLayout Spacing="20" Padding="10">
        
        
        <Border Stroke="Gray" StrokeThickness="1" Padding="10">
            <VerticalStackLayout>
                <Label Text="Vertical Orientation" 
                       FontSize="16" 
                       FontAttributes="Bold"
                       HorizontalOptions="Center"/>
                <chart:SfFunnelChart ItemsSource="{Binding Data}"
                                     XBindingPath="Stage"
                                     YBindingPath="Value"
                                     Orientation="Vertical"
                                     HeightRequest="300">
                    <chart:SfFunnelChart.Legend>
                        <chart:ChartLegend Placement="Bottom"/>
                    </chart:SfFunnelChart.Legend>
                </chart:SfFunnelChart>
            </VerticalStackLayout>
        </Border>
        
        
        <Border Stroke="Gray" StrokeThickness="1" Padding="10">
            <VerticalStackLayout>
                <Label Text="Horizontal Orientation" 
                       FontSize="16" 
                       FontAttributes="Bold"
                       HorizontalOptions="Center"/>
                <chart:SfFunnelChart ItemsSource="{Binding Data}"
                                     XBindingPath="Stage"
                                     YBindingPath="Value"
                                     Orientation="Horizontal"
                                     HeightRequest="300">
                    <chart:SfFunnelChart.Legend>
                        <chart:ChartLegend Placement="Right"/>
                    </chart:SfFunnelChart.Legend>
                </chart:SfFunnelChart>
            </VerticalStackLayout>
        </Border>
        
    </VerticalStackLayout>
    
</ContentPage>

Segment Spacing

The GapRatio property controls the gap between funnel segments. This creates visual separation, making individual stages more distinct.

Properties

  • GapRatio (double): Value between 0 and 1
    • 0: No gap (default)
    • 1: Maximum gap

XAML

<chart:SfFunnelChart GapRatio="0.2"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";
chart.GapRatio = 0.2;

this.Content = chart;

Gap Ratio Examples

No Gap (Default)

<chart:SfFunnelChart GapRatio="0"/>
  • Segments touch each other
  • Traditional funnel appearance
  • Best for emphasizing flow

Small Gap

<chart:SfFunnelChart GapRatio="0.1"/>
  • Subtle separation
  • Maintains funnel shape
  • Slightly improved segment distinction

Medium Gap

<chart:SfFunnelChart GapRatio="0.2"/>
  • Noticeable separation
  • Good balance between flow and distinction
  • Recommended for most use cases

Large Gap

<chart:SfFunnelChart GapRatio="0.5"/>
  • Significant separation
  • Individual segments stand out
  • May lose funnel metaphor

Segment Spacing with Visual Enhancements

<chart:SfFunnelChart ItemsSource="{Binding Data}"
                     XBindingPath="Stage"
                     YBindingPath="Count"
                     GapRatio="0.15"
                     ShowDataLabels="True">
    
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Center">
            <chart:FunnelDataLabelSettings.LabelStyle>
                <chart:ChartDataLabelStyle FontSize="14"
                                          FontAttributes="Bold"
                                          TextColor="White"/>
            </chart:FunnelDataLabelSettings.LabelStyle>
        </chart:FunnelDataLabelSettings>
    </chart:SfFunnelChart.DataLabelSettings>
    
</chart:SfFunnelChart>

Supporting file: references/appearance.md

Appearance Customization in .NET MAUI Funnel Chart

Customize the visual appearance of your funnel chart by defining custom color palettes and applying gradients. The SfFunnelChart provides flexible styling options to match your application's branding and design requirements.

Custom PaletteBrushes

The PaletteBrushes property allows you to define custom colors for funnel segments. By default, the chart uses a predefined color palette, but you can override it with your own color scheme.

XAML with ViewModel Binding

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue"
                     PaletteBrushes="{Binding CustomBrushes}">
    
</chart:SfFunnelChart>

ViewModel with Custom Colors

public class FunnelChartViewModel
{
    public ObservableCollection<FunnelDataModel> Data { get; set; }
    public List<Brush> CustomBrushes { get; set; }

    public FunnelChartViewModel()
    {
        // Define custom color palette
        CustomBrushes = new List<Brush>
        {
            new SolidColorBrush(Color.FromRgb(38, 198, 218)),
            new SolidColorBrush(Color.FromRgb(0, 188, 212)),
            new SolidColorBrush(Color.FromRgb(0, 172, 193)),
            new SolidColorBrush(Color.FromRgb(0, 151, 167)),
            new SolidColorBrush(Color.FromRgb(0, 131, 143))
        };

        // Initialize data
        Data = new ObservableCollection<FunnelDataModel>
        {
            new FunnelDataModel { XValue = "Prospects", YValue = 320 },
            new FunnelDataModel { XValue = "Inquiries", YValue = 290 },
            new FunnelDataModel { XValue = "Applicants", YValue = 245 },
            new FunnelDataModel { XValue = "Admits", YValue = 190 },
            new FunnelDataModel { XValue = "Enrolled", YValue = 175 }
        };
    }
}

public class FunnelDataModel
{
    public string XValue { get; set; }
    public double YValue { get; set; }
}

C# Direct Assignment

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

chart.PaletteBrushes = new List<Brush>
{
    new SolidColorBrush(Color.FromRgb(38, 198, 218)),
    new SolidColorBrush(Color.FromRgb(0, 188, 212)),
    new SolidColorBrush(Color.FromRgb(0, 172, 193)),
    new SolidColorBrush(Color.FromRgb(0, 151, 167)),
    new SolidColorBrush(Color.FromRgb(0, 131, 143))
};

this.Content = chart;

Applying Gradients

Enhance your funnel chart with gradient effects using LinearGradientBrush or RadialGradientBrush. Gradients add depth and visual interest to segments.

Linear Gradient Example

XAML with ViewModel Binding

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue"
                     PaletteBrushes="{Binding GradientBrushes}">
</chart:SfFunnelChart>

ViewModel with Linear Gradients

public class FunnelChartViewModel
{
    public ObservableCollection<FunnelDataModel> Data { get; set; }
    public List<Brush> GradientBrushes { get; set; }

    public FunnelChartViewModel()
    {
        GradientBrushes = new List<Brush>();

        // Gradient 1: Blue shades
        LinearGradientBrush gradient1 = new LinearGradientBrush();
        gradient1.GradientStops = new GradientStopCollection()
        {
            new GradientStop { Offset = 1, Color = Color.FromArgb("#a3bded") },
            new GradientStop { Offset = 0, Color = Color.FromArgb("#6991c7") }
        };

        // Gradient 2: Purple shades
        LinearGradientBrush gradient2 = new LinearGradientBrush();
        gradient2.GradientStops = new GradientStopCollection()
        {
            new GradientStop { Offset = 1, Color = Color.FromArgb("#A5678E") },
            new GradientStop { Offset = 0, Color = Color.FromArgb("#E8B7D4") }
        };

        // Gradient 3: Pink shades
        LinearGradientBrush gradient3 = new LinearGradientBrush();
        gradient3.GradientStops = new GradientStopCollection()
        {
            new GradientStop { Offset = 1, Color = Color.FromArgb("#FFCAD4") },
            new GradientStop { Offset = 0, Color = Color.FromArgb("#FB7B8E") }
        };

        // Gradient 4: Orange shades
        LinearGradientBrush gradient4 = new LinearGradientBrush();
        gradient4.GradientStops = new GradientStopCollection()
        {
            new GradientStop { Offset = 1, Color = Color.FromArgb("#FDC094") },
            new GradientStop { Offset = 0, Color = Color.FromArgb("#FFE5D8") }
        };

        // Gradient 5: Green shades
        LinearGradientBrush gradient5 = new LinearGradientBrush();
        gradient5.GradientStops = new GradientStopCollection()
        {
            new GradientStop { Offset = 1, Color = Color.FromArgb("#CFF4D2") },
            new GradientStop { Offset = 0, Color = Color.FromArgb("#56C596") }
        };

        GradientBrushes.Add(gradient1);
        GradientBrushes.Add(gradient2);
        GradientBrushes.Add(gradient3);
        GradientBrushes.Add(gradient4);
        GradientBrushes.Add(gradient5);

        // Initialize data
        Data = new ObservableCollection<FunnelDataModel>
        {
            new FunnelDataModel { XValue = "Prospects", YValue = 320 },
            new FunnelDataModel { XValue = "Inquiries", YValue = 290 },
            new FunnelDataModel { XValue = "Applicants", YValue = 245 },
            new FunnelDataModel { XValue = "Admits", YValue = 190 },
            new FunnelDataModel { XValue = "Enrolled", YValue = 175 }
        };
    }
}

C# Direct Gradient Assignment

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

List<Brush> gradients = new List<Brush>();

// Create gradient 1
LinearGradientBrush gradient1 = new LinearGradientBrush
{
    GradientStops = new GradientStopCollection
    {
        new GradientStop { Offset = 1, Color = Color.FromArgb("#a3bded") },
        new GradientStop { Offset = 0, Color = Color.FromArgb("#6991c7") }
    }
};

// Create gradient 2
LinearGradientBrush gradient2 = new LinearGradientBrush
{
    GradientStops = new GradientStopCollection
    {
        new GradientStop { Offset = 1, Color = Color.FromArgb("#A5678E") },
        new GradientStop { Offset = 0, Color = Color.FromArgb("#E8B7D4") }
    }
};

gradients.Add(gradient1);
gradients.Add(gradient2);
// Add more gradients as needed...

chart.PaletteBrushes = gradients;
this.Content = chart;

Radial Gradient Example

RadialGradientBrush radialGradient = new RadialGradientBrush
{
    Center = new Point(0.5, 0.5),
    Radius = 0.5,
    GradientStops = new GradientStopCollection
    {
        new GradientStop { Offset = 0, Color = Color.FromArgb("#FFD700") },
        new GradientStop { Offset = 1, Color = Color.FromArgb("#FFA500") }
    }
};

List<Brush> brushes = new List<Brush> { radialGradient };
chart.PaletteBrushes = brushes;

Color Scheme Examples

Professional Blue Theme

CustomBrushes = new List<Brush>
{
    new SolidColorBrush(Color.FromRgb(13, 71, 161)),   // Dark blue
    new SolidColorBrush(Color.FromRgb(25, 118, 210)),  // Medium blue
    new SolidColorBrush(Color.FromRgb(66, 165, 245)),  // Light blue
    new SolidColorBrush(Color.FromRgb(144, 202, 249)), // Lighter blue
    new SolidColorBrush(Color.FromRgb(187, 222, 251))  // Lightest blue
};

Warm Sunset Theme

CustomBrushes = new List<Brush>
{
    new SolidColorBrush(Color.FromRgb(230, 74, 25)),   // Deep orange
    new SolidColorBrush(Color.FromRgb(244, 143, 177)), // Pink
    new SolidColorBrush(Color.FromRgb(255, 179, 0)),   // Amber
    new SolidColorBrush(Color.FromRgb(255, 213, 79)),  // Yellow
    new SolidColorBrush(Color.FromRgb(255, 238, 88))   // Light yellow
};

Corporate Green Theme

CustomBrushes = new List<Brush>
{
    new SolidColorBrush(Color.FromRgb(27, 94, 32)),    // Dark green
    new SolidColorBrush(Color.FromRgb(56, 142, 60)),   // Medium green
    new SolidColorBrush(Color.FromRgb(102, 187, 106)), // Light green
    new SolidColorBrush(Color.FromRgb(165, 214, 167)), // Lighter green
    new SolidColorBrush(Color.FromRgb(200, 230, 201))  // Lightest green
};

Monochrome Gray Theme

CustomBrushes = new List<Brush>
{
    new SolidColorBrush(Color.FromRgb(33, 33, 33)),    // Very dark gray
    new SolidColorBrush(Color.FromRgb(97, 97, 97)),    // Dark gray
    new SolidColorBrush(Color.FromRgb(158, 158, 158)), // Medium gray
    new SolidColorBrush(Color.FromRgb(189, 189, 189)), // Light gray
    new SolidColorBrush(Color.FromRgb(224, 224, 224))  // Very light gray
};

Complete Example with Custom Appearance

XAML

<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit"
             xmlns:model="clr-namespace:YourApp.ViewModels">

    <chart:SfFunnelChart ItemsSource="{Binding Data}" 
                         XBindingPath="Stage"
                         YBindingPath="Count"
                         PaletteBrushes="{Binding CustomBrushes}"
                         ShowDataLabels="True">

        <chart:SfFunnelChart.Title>
            <Label Text="Sales Conversion Funnel"
                   FontSize="20"
                   FontAttributes="Bold"
                   HorizontalTextAlignment="Center"/>
        </chart:SfFunnelChart.Title>

        <chart:SfFunnelChart.BindingContext>
            <model:FunnelChartViewModel/>
        </chart:SfFunnelChart.BindingContext>

        <chart:SfFunnelChart.Legend>
            <chart:ChartLegend Placement="Bottom"/>
        </chart:SfFunnelChart.Legend>

    </chart:SfFunnelChart>

</ContentPage>

C# Complete Implementation

public class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        SfFunnelChart chart = new SfFunnelChart();
        
        // Set title
        chart.Title = new Label
        {
            Text = "Sales Conversion Funnel",
            FontSize = 20,
            FontAttributes = FontAttributes.Bold,
            HorizontalTextAlignment = TextAlignment.Center
        };

        // Create ViewModel
        FunnelChartViewModel viewModel = new FunnelChartViewModel();
        chart.BindingContext = viewModel;

        // Bind data
        chart.ItemsSource = viewModel.Data;
        chart.XBindingPath = "Stage";
        chart.YBindingPath = "Count";

        // Apply custom colors
        chart.PaletteBrushes = viewModel.CustomBrushes;

        // Enable data labels
        chart.ShowDataLabels = true;

        // Add legend
        chart.Legend = new ChartLegend { Placement = LegendPlacement.Bottom };

        this.Content = chart;
    }
}

Best Practices for Appearance Customization

  1. Color Selection:

    • Choose colors that align with your brand identity
    • Ensure sufficient contrast between adjacent segments
    • Use color progression to show hierarchy or flow
  2. Gradients:

    • Use gradients sparingly for visual interest without overwhelming
    • Keep gradient transitions smooth (similar hues)
    • Test gradients on different screen sizes and resolutions
  3. Accessibility:

    • Avoid red-green combinations for colorblind users
    • Provide sufficient contrast ratios (WCAG guidelines)
    • Don't rely solely on color to convey information
  4. Consistency:

    • Use the same color palette across related charts
    • Maintain consistent segment colors for the same categories
    • Match chart colors to your application's theme
  5. Performance:

    • Limit the number of gradient stops for better performance
    • Use solid colors when gradients aren't necessary
    • Test appearance on target devices

Troubleshooting

Custom colors not appearing:

  • Verify PaletteBrushes is correctly bound or assigned
  • Ensure the list contains enough colors for all segments
  • Check that colors are defined with valid RGB/Hex values

Gradients look incorrect:

  • Verify GradientStop offsets are between 0 and 1
  • Check gradient direction (linear vs radial)
  • Ensure GradientStopCollection is properly initialized

Colors conflict with data labels:

  • Adjust DataLabelSettings TextColor for contrast
  • Use UseSeriesPalette carefully with custom colors
  • Consider using Background in LabelStyle for readability

Supporting file: references/data-labels.md

Data Labels in .NET MAUI Funnel Chart

Data labels display values related to funnel chart segments, helping users quickly identify segment data without hovering. You can display values from data points (x, y) or other custom properties, with extensive customization options for placement, styling, and context.

Table of Contents

Enable Data Labels

Set the ShowDataLabels property to true on the SfFunnelChart to display data labels. The default value is false.

XAML

<chart:SfFunnelChart ShowDataLabels="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";
chart.ShowDataLabels = true;

this.Content = chart;

Data Label Customization

Customize data labels using the DataLabelSettings property with a FunnelDataLabelSettings instance. This provides control over placement, context, styling, and more.

Basic Customization

<chart:SfFunnelChart ShowDataLabels="True">
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Outer" 
                                       Context="XValue" 
                                       UseSeriesPalette="True"/>
    </chart:SfFunnelChart.DataLabelSettings>
</chart:SfFunnelChart>
chart.ShowDataLabels = true;
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Outer,
    Context = FunnelDataLabelContext.XValue,
    UseSeriesPalette = true
};

Label Placement

The LabelPlacement property controls where data labels appear relative to funnel segments. Available options:

PlacementDescription
AutoAutomatically determines the best position (default)
InnerLabels appear inside segments
CenterLabels appear at the center of segments
OuterLabels appear outside segments

Auto Placement (Default)

<chart:FunnelDataLabelSettings LabelPlacement="Auto"/>

Inner Placement

<chart:FunnelDataLabelSettings LabelPlacement="Inner"/>
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Inner
};

Center Placement

<chart:FunnelDataLabelSettings LabelPlacement="Center"/>
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Center
};

Outer Placement

<chart:FunnelDataLabelSettings LabelPlacement="Outer"/>
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Outer
};

Label Context

The Context property determines what data to display in the label. Options include:

ContextDescription
YValueDisplay the Y-axis value (default)
XValueDisplay the X-axis label/category

Display Y Values (Numeric Data)

<chart:FunnelDataLabelSettings Context="YValue"/>
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    Context = FunnelDataLabelContext.YValue
};

Display X Values (Category Labels)

<chart:FunnelDataLabelSettings Context="XValue"/>
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    Context = FunnelDataLabelContext.XValue
};

UseSeriesPalette

Set UseSeriesPalette to true to apply the segment's color to the data label background, creating visual consistency.

XAML

<chart:FunnelDataLabelSettings UseSeriesPalette="True"/>

C#

chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    UseSeriesPalette = true
};

Label Style Properties

The LabelStyle property provides fine-grained control over label appearance through ChartDataLabelStyle:

PropertyTypeDescription
MarginThicknessSpacing around the label
BackgroundBrushLabel background color
FontAttributesFontAttributesFont style (Bold, Italic, None)
FontSizedoubleFont size
StrokeBrushBorder color
StrokeWidthdoubleBorder thickness
CornerRadiusCornerRadiusRounded corners
TextColorColorText color

Basic Label Styling

<chart:SfFunnelChart ShowDataLabels="True">
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Outer">
            <chart:FunnelDataLabelSettings.LabelStyle>
                <chart:ChartDataLabelStyle Margin="5"
                                          FontSize="14"
                                          TextColor="Black"
                                          FontAttributes="Bold"/>
            </chart:FunnelDataLabelSettings.LabelStyle>
        </chart:FunnelDataLabelSettings>
    </chart:SfFunnelChart.DataLabelSettings>
</chart:SfFunnelChart>

Advanced Label Styling with Background and Border

<chart:ChartDataLabelStyle Margin="8"
                          FontSize="16"
                          TextColor="White"
                          FontAttributes="Bold"
                          Background="#2196F3"
                          Stroke="#1976D2"
                          StrokeWidth="2"
                          CornerRadius="8"/>
ChartDataLabelStyle labelStyle = new ChartDataLabelStyle()
{
    Margin = 8,
    FontSize = 16,
    TextColor = Colors.White,
    FontAttributes = FontAttributes.Bold,
    Background = new SolidColorBrush(Color.FromArgb("#2196F3")),
    Stroke = new SolidColorBrush(Color.FromArgb("#1976D2")),
    StrokeWidth = 2,
    CornerRadius = new CornerRadius(8)
};

chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Outer,
    LabelStyle = labelStyle
};

Complete Examples

Example 1: Outer Labels with Segment Colors

<chart:SfFunnelChart ShowDataLabels="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="Stage"
                     YBindingPath="Count">
    
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Outer" 
                                       Context="YValue" 
                                       UseSeriesPalette="True">
            <chart:FunnelDataLabelSettings.LabelStyle>
                <chart:ChartDataLabelStyle Margin="5"
                                          FontSize="14"
                                          TextColor="White"
                                          FontAttributes="Bold"/>
            </chart:FunnelDataLabelSettings.LabelStyle>
        </chart:FunnelDataLabelSettings>
    </chart:SfFunnelChart.DataLabelSettings>
    
</chart:SfFunnelChart>

Example 2: Inner Labels with Custom Background

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "Stage";
chart.YBindingPath = "Count";
chart.ShowDataLabels = true;

ChartDataLabelStyle labelStyle = new ChartDataLabelStyle()
{
    Margin = 3,
    FontSize = 12,
    TextColor = Colors.White,
    Background = new SolidColorBrush(Colors.Black.WithAlpha(0.7f)),
    CornerRadius = new CornerRadius(4)
};

chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Inner,
    Context = FunnelDataLabelContext.YValue,
    LabelStyle = labelStyle
};

this.Content = chart;

Example 3: Center Labels Showing Category Names

<chart:SfFunnelChart ShowDataLabels="True">
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Center" 
                                       Context="XValue">
            <chart:FunnelDataLabelSettings.LabelStyle>
                <chart:ChartDataLabelStyle FontSize="16"
                                          TextColor="White"
                                          FontAttributes="Bold"/>
            </chart:FunnelDataLabelSettings.LabelStyle>
        </chart:FunnelDataLabelSettings>
    </chart:SfFunnelChart.DataLabelSettings>
</chart:SfFunnelChart>

Example 4: Auto Placement with Bordered Labels

chart.ShowDataLabels = true;

ChartDataLabelStyle labelStyle = new ChartDataLabelStyle()
{
    Margin = 6,
    FontSize = 15,
    TextColor = Colors.Black,
    FontAttributes = FontAttributes.Bold,
    Background = new SolidColorBrush(Colors.White),
    Stroke = new SolidColorBrush(Colors.Gray),
    StrokeWidth = 1,
    CornerRadius = new CornerRadius(6)
};

chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Auto,
    Context = FunnelDataLabelContext.YValue,
    LabelStyle = labelStyle
};

Best Practices

  1. Choose Appropriate Placement:

    • Use Outer for cleaner segments with external labels
    • Use Inner or Center when space is limited
    • Use Auto to let the chart decide optimal placement
  2. Context Selection:

    • Display YValue when numeric data is important (counts, percentages)
    • Display XValue when category names need emphasis
    • Consider using tooltips for detailed information instead of cluttering labels
  3. Color Contrast:

    • Ensure TextColor contrasts well with Background or segment colors
    • Use UseSeriesPalette with cautionโ€”verify text remains readable
  4. Font Sizing:

    • Keep FontSize between 12-16 for readability
    • Adjust based on segment size and label count
  5. Avoid Overlap:

    • If labels overlap with Outer placement, consider Inner or reduce FontSize
    • Use Margin to add spacing between labels and segments

Troubleshooting

Labels not visible:

  • Verify ShowDataLabels="True" is set on SfFunnelChart
  • Check that TextColor contrasts with background
  • Ensure FontSize is not too small

Labels overlap:

  • Try different LabelPlacement options
  • Reduce FontSize or label Margin
  • Consider showing fewer segments or increasing chart height

Label colors don't match segments:

  • Set UseSeriesPalette="True" to match segment colors
  • Or manually set Background in LabelStyle to specific colors

Supporting file: references/exporting.md

Exporting in .NET MAUI Funnel Chart

Export your funnel charts as images for sharing, reporting, or embedding in other documents. The SfFunnelChart supports exporting to JPEG and PNG formats, as well as retrieving chart content as a stream.

Export as an Image

Use the SaveAsImage method to export the chart view as an image file in JPEG or PNG format.

Prerequisites

  • The chart must be added to the visual tree before exporting
  • File writing permissions may be required on some platforms

Supported Formats

  • JPEG (.jpeg, .jpg)
  • PNG (.png) - Default format if no extension specified

Basic Export

C# (PNG Format - Default)

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

this.Content = chart;

// Export as PNG (default)
chart.SaveAsImage("FunnelChart.png");

C# (JPEG Format)

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

this.Content = chart;

// Export as JPEG
chart.SaveAsImage("FunnelChart.jpeg");

Export from Button Click

<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit">
    <VerticalStackLayout>
        
        <chart:SfFunnelChart x:Name="funnelChart"
                             ItemsSource="{Binding Data}"
                             XBindingPath="Stage"
                             YBindingPath="Value">
            <chart:SfFunnelChart.Title>
                <Label Text="Sales Funnel"/>
            </chart:SfFunnelChart.Title>
        </chart:SfFunnelChart>
        
        <HorizontalStackLayout Spacing="10" Padding="10">
            <Button Text="Export as PNG" 
                    Clicked="OnExportAsPngClicked"/>
            <Button Text="Export as JPEG" 
                    Clicked="OnExportAsJpegClicked"/>
        </HorizontalStackLayout>
        
    </VerticalStackLayout>
</ContentPage>
private void OnExportAsPngClicked(object sender, EventArgs e)
{
    funnelChart.SaveAsImage("SalesFunnel.png");
    DisplayAlert("Success", "Chart exported as PNG", "OK");
}

private void OnExportAsJpegClicked(object sender, EventArgs e)
{
    funnelChart.SaveAsImage("SalesFunnel.jpeg");
    DisplayAlert("Success", "Chart exported as JPEG", "OK");
}

Export File Locations

Exported images are saved in platform-specific directories:

PlatformDefault Location
AndroidPictures directory in file system
WindowsPictures directory in file system
iOSPhotos/Album directory
macOSPictures directory in file system

Platform-Specific Permissions

Android

Add file writing permissions in AndroidManifest.xml:

<manifest>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

For Android 10+ (API level 29+), you may need to handle scoped storage:

<application android:requestLegacyExternalStorage="true">

iOS

Add permission descriptions in Info.plist:

<dict>
    <key>NSPhotoLibraryUsageDescription</key>    
    <string>This app needs permission to access Photos</string>    
    <key>NSPhotoLibraryAddUsageDescription</key>    
    <string>This app needs permission to save charts to Photos</string> 
</dict>

Windows

Typically no special permissions needed for Pictures folder.

Get Chart as Stream

The GetStreamAsync method retrieves the chart as a stream asynchronously, useful for passing to other components (PDF, Excel, Word, etc.) or uploading to cloud services.

Method Signature

Task<Stream> GetStreamAsync(ImageFileFormat format)

Supported Formats

  • ImageFileFormat.Jpeg
  • ImageFileFormat.Png

Basic Usage

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

this.Content = chart;

// Get chart as PNG stream
Stream chartStream = await chart.GetStreamAsync(ImageFileFormat.Png);

Example: Save Stream to File

private async Task ExportChartToCustomLocationAsync()
{
    try
    {
        // Get chart as stream
        Stream chartStream = await funnelChart.GetStreamAsync(ImageFileFormat.Png);
        
        // Define custom file path
        string fileName = $"FunnelChart_{DateTime.Now:yyyyMMdd_HHmmss}.png";
        string filePath = Path.Combine(FileSystem.AppDataDirectory, fileName);
        
        // Write stream to file
        using (FileStream fileStream = File.Create(filePath))
        {
            await chartStream.CopyToAsync(fileStream);
        }
        
        await DisplayAlert("Success", $"Chart saved to: {filePath}", "OK");
    }
    catch (Exception ex)
    {
        await DisplayAlert("Error", $"Failed to export: {ex.Message}", "OK");
    }
}

Example: Upload Chart to Server

private async Task UploadChartToServerAsync()
{
    try
    {
        // Get chart as JPEG stream
        Stream chartStream = await funnelChart.GetStreamAsync(ImageFileFormat.Jpeg);
        
        // Create multipart form content
        using (var content = new MultipartFormDataContent())
        {
            var streamContent = new StreamContent(chartStream);
            streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg");
            content.Add(streamContent, "chart", "funnel-chart.jpeg");
            
            // Upload to server
            using (var httpClient = new HttpClient())
            {
                var response = await httpClient.PostAsync("https://api.example.com/upload", content);
                
                if (response.IsSuccessStatusCode)
                {
                    await DisplayAlert("Success", "Chart uploaded successfully", "OK");
                }
            }
        }
    }
    catch (Exception ex)
    {
        await DisplayAlert("Error", $"Upload failed: {ex.Message}", "OK");
    }
}

Example: Embed in PDF Document

private async Task EmbedChartInPdfAsync()
{
    try
    {
        // Get chart as PNG stream
        Stream chartStream = await funnelChart.GetStreamAsync(ImageFileFormat.Png);
        
        // Use a PDF library (e.g., Syncfusion PDF, iTextSharp)
        // This is a conceptual example
        
        // Convert stream to byte array
        using (MemoryStream ms = new MemoryStream())
        {
            await chartStream.CopyToAsync(ms);
            byte[] chartBytes = ms.ToArray();
            
            // Create PDF and embed image
            // (Implementation depends on your PDF library)
            
            await DisplayAlert("Success", "Chart embedded in PDF", "OK");
        }
    }
    catch (Exception ex)
    {
        await DisplayAlert("Error", $"PDF generation failed: {ex.Message}", "OK");
    }
}

Example: Share Chart via Platform Share Sheet

private async Task ShareChartAsync()
{
    try
    {
        // Get chart as stream
        Stream chartStream = await funnelChart.GetStreamAsync(ImageFileFormat.Png);
        
        // Save to temporary file
        string fileName = "FunnelChart.png";
        string filePath = Path.Combine(FileSystem.CacheDirectory, fileName);
        
        using (FileStream fileStream = File.Create(filePath))
        {
            await chartStream.CopyToAsync(fileStream);
        }
        
        // Share using .NET MAUI Share API
        await Share.RequestAsync(new ShareFileRequest
        {
            Title = "Share Funnel Chart",
            File = new ShareFile(filePath)
        });
    }
    catch (Exception ex)
    {
        await DisplayAlert("Error", $"Sharing failed: {ex.Message}", "OK");
    }
}

Complete Export Example with UI

XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit"
             xmlns:model="clr-namespace:YourApp.ViewModels">

    <Grid RowDefinitions="*, Auto">
        
        
        <chart:SfFunnelChart x:Name="funnelChart"
                             Grid.Row="0"
                             ItemsSource="{Binding Data}"
                             XBindingPath="Stage"
                             YBindingPath="Value"
                             ShowDataLabels="True">
            
            <chart:SfFunnelChart.Title>
                <Label Text="Sales Conversion Funnel" 
                       FontSize="20" 
                       FontAttributes="Bold"/>
            </chart:SfFunnelChart.Title>
            
            <chart:SfFunnelChart.BindingContext>
                <model:SalesFunnelViewModel/>
            </chart:SfFunnelChart.BindingContext>
            
            <chart:SfFunnelChart.Legend>
                <chart:ChartLegend Placement="Bottom"/>
            </chart:SfFunnelChart.Legend>
            
        </chart:SfFunnelChart>
        
        
        <VerticalStackLayout Grid.Row="1" 
                            Padding="15" 
                            Spacing="10"
                            BackgroundColor="LightGray">
            
            <Label Text="Export Options" 
                   FontSize="16" 
                   FontAttributes="Bold"/>
            
            <HorizontalStackLayout Spacing="10">
                <Button Text="Save as PNG" 
                        Clicked="OnSaveAsPngClicked"
                        BackgroundColor="DodgerBlue"/>
                <Button Text="Save as JPEG" 
                        Clicked="OnSaveAsJpegClicked"
                        BackgroundColor="DodgerBlue"/>
                <Button Text="Share" 
                        Clicked="OnShareClicked"
                        BackgroundColor="Green"/>
            </HorizontalStackLayout>
            
        </VerticalStackLayout>
        
    </Grid>

</ContentPage>

C# Code-Behind

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void OnSaveAsPngClicked(object sender, EventArgs e)
    {
        try
        {
            string fileName = $"FunnelChart_{DateTime.Now:yyyyMMdd_HHmmss}.png";
            funnelChart.SaveAsImage(fileName);
            DisplayAlert("Success", $"Chart saved as {fileName}", "OK");
        }
        catch (Exception ex)
        {
            DisplayAlert("Error", $"Failed to save: {ex.Message}", "OK");
        }
    }

    private void OnSaveAsJpegClicked(object sender, EventArgs e)
    {
        try
        {
            string fileName = $"FunnelChart_{DateTime.Now:yyyyMMdd_HHmmss}.jpeg";
            funnelChart.SaveAsImage(fileName);
            DisplayAlert("Success", $"Chart saved as {fileName}", "OK");
        }
        catch (Exception ex)
        {
            DisplayAlert("Error", $"Failed to save: {ex.Message}", "OK");
        }
    }

    private async void OnShareClicked(object sender, EventArgs e)
    {
        try
        {
            // Get chart as stream
            Stream chartStream = await funnelChart.GetStreamAsync(ImageFileFormat.Png);
            
            // Save to cache
            string fileName = "FunnelChart.png";
            string filePath = Path.Combine(FileSystem.CacheDirectory, fileName);
            
            using (FileStream fileStream = File.Create(filePath))
            {
                await chartStream.CopyToAsync(fileStream);
            }
            
            // Share
            await Share.RequestAsync(new ShareFileRequest
            {
                Title = "Share Funnel Chart",
                File = new ShareFile(filePath)
            });
        }
        catch (Exception ex)
        {
            await DisplayAlert("Error", $"Sharing failed: {ex.Message}", "OK");
        }
    }
}

Best Practices

  1. Timing:

    • Export only after the chart is fully rendered
    • Ensure Content is set and chart is in visual tree
    • Wait for data binding to complete
  2. File Naming:

    • Use descriptive, unique filenames
    • Include timestamps to avoid overwriting
    • Use appropriate file extensions (.png, .jpeg)
  3. Error Handling:

    • Wrap export calls in try-catch blocks
    • Validate chart state before exporting
    • Handle permission denials gracefully
  4. Format Selection:

    • Use PNG for charts with transparency or sharp text
    • Use JPEG for smaller file sizes (no transparency)
    • PNG is generally recommended for charts
  5. Permissions:

    • Request permissions before exporting
    • Provide clear permission descriptions
    • Handle permission denials appropriately
  6. Stream Management:

    • Dispose of streams after use
    • Use using statements for automatic disposal
    • Close file handles promptly

Troubleshooting

Export fails silently:

  • Verify chart is added to visual tree (this.Content = chart)
  • Ensure chart has finished rendering
  • Check for platform-specific permissions

Permission denied errors:

  • Add required permissions to platform manifest files
  • Request runtime permissions if needed (Android 6+)
  • Verify permission descriptions in Info.plist (iOS)

File not found after export:

  • Check platform-specific save locations
  • Verify file system permissions
  • Look in device's Pictures/Photos folders

Stream is null or empty:

  • Ensure chart is visible and rendered
  • Wait for async operations to complete
  • Verify chart contains data

Poor image quality:

  • PNG provides better quality than JPEG for charts
  • Ensure chart has sufficient size before export
  • Check that chart isn't being scaled down

Supporting file: references/getting-started.md

Getting Started with .NET MAUI Funnel Chart

This guide walks you through setting up and implementing your first Syncfusion .NET MAUI Funnel Chart (SfFunnelChart). Funnel charts are ideal for visualizing data as progressively decreasing segments, commonly used for sales pipelines, conversion funnels, and process stages.

Step 1: Install the NuGet Package

Install the Syncfusion.Maui.Toolkit package in your .NET MAUI project:

Option 1: NuGet Package Manager UI

  1. In Solution Explorer, right-click the project and choose Manage NuGet Packages
  2. Search for Syncfusion.Maui.Toolkit
  3. Install the latest version
  4. Ensure dependencies are installed and the project is restored

Option 2: .NET CLI

dotnet add package Syncfusion.Maui.Toolkit

Option 3: Package Manager Console

Install-Package Syncfusion.Maui.Toolkit

Step 2: Register the Syncfusion Handler

CRITICAL: In the MauiProgram.cs file, register the handler for Syncfusionยฎ Toolkit.

File: MauiProgram.cs

using Syncfusion.Maui.Toolkit.Hosting;

namespace MyCardApp
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureSyncfusionToolkit()  // Register Syncfusion handler
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });

            return builder.Build();
        }
    }
}

Important: Place .ConfigureSyncfusionToolkit() immediately after .UseMauiApp<App>() to ensure proper initialization.

Step 3: Import the Namespace

Import the Syncfusion.Maui.Toolkit.Charts namespace in your XAML or C# code:

XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit">
    
</ContentPage>

C#

using Syncfusion.Maui.Toolkit.Hosting;

Step 4: Initialize SfFunnelChart

XAML Approach

<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit">
    <chart:SfFunnelChart/>
</ContentPage>

C# Approach

using Syncfusion.Maui.Toolkit.Hosting;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        
        SfFunnelChart chart = new SfFunnelChart();
        this.Content = chart;
    }
}

Step 5: Create Data Models and ViewModels

Define a data model representing each segment in the funnel:

public class FunnelDataModel
{
    public string XValue { get; set; }
    public double YValue { get; set; }
}

Create a ViewModel that provides the data collection:

public class SalesFunnelViewModel
{
    public List<FunnelDataModel> Data { get; set; }

    public SalesFunnelViewModel()
    {
        Data = new List<FunnelDataModel>()
        {
            new FunnelDataModel { XValue = "Prospects", YValue = 320 },
            new FunnelDataModel { XValue = "Inquiries", YValue = 290 },
            new FunnelDataModel { XValue = "Applicants", YValue = 245 },
            new FunnelDataModel { XValue = "Admits", YValue = 190 },
            new FunnelDataModel { XValue = "Enrolled", YValue = 175 }
        };
    }
}

Step 6: Bind Data to the Chart

Set the chart's BindingContext to the ViewModel and bind data using ItemsSource, XBindingPath, and YBindingPath:

XAML with BindingContext

<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit"
             xmlns:model="clr-namespace:YourNamespace.ViewModels">

    <chart:SfFunnelChart ItemsSource="{Binding Data}" 
                         XBindingPath="XValue" 
                         YBindingPath="YValue">
        
        <chart:SfFunnelChart.BindingContext>
            <model:SalesFunnelViewModel/>
        </chart:SfFunnelChart.BindingContext>
        
    </chart:SfFunnelChart>
    
</ContentPage>

C# Approach

SfFunnelChart chart = new SfFunnelChart();
SalesFunnelViewModel viewModel = new SalesFunnelViewModel();
chart.BindingContext = viewModel;

chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";

this.Content = chart;

Step 7: Add Chart Title

Provide context to your chart with a descriptive title using the Title property:

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue" 
                     YBindingPath="YValue">
    
    <chart:SfFunnelChart.Title>
        <Label Text="School Admission Funnel"/>
    </chart:SfFunnelChart.Title>
    
</chart:SfFunnelChart>

C#

chart.Title = new Label()
{
    Text = "School Admission Funnel"
};

Step 8: Enable Data Labels and Tooltips

Make your chart more informative by enabling data labels and tooltips:

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue" 
                     YBindingPath="YValue"
                     ShowDataLabels="True"
                     EnableTooltip="True">
    
</chart:SfFunnelChart>

C#

chart.ShowDataLabels = true;
chart.EnableTooltip = true;

Step 9: Add Legend

Display a legend to help users identify each funnel segment:

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue" 
                     YBindingPath="YValue">
    
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend/>
    </chart:SfFunnelChart.Legend>
    
</chart:SfFunnelChart>

C#

chart.Legend = new ChartLegend();

Complete Working Example

XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FunnelChartDemo.MainPage"
             xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit"
             xmlns:model="clr-namespace:FunnelChartDemo.ViewModels">

    <chart:SfFunnelChart ItemsSource="{Binding Data}" 
                         XBindingPath="XValue" 
                         YBindingPath="YValue"
                         ShowDataLabels="True" 
                         EnableTooltip="True">

        <chart:SfFunnelChart.Title>
            <Label Text="School Admission Funnel"/>
        </chart:SfFunnelChart.Title>

        <chart:SfFunnelChart.BindingContext>
            <model:SalesFunnelViewModel/>
        </chart:SfFunnelChart.BindingContext>

        <chart:SfFunnelChart.Legend>
            <chart:ChartLegend/>
        </chart:SfFunnelChart.Legend>

    </chart:SfFunnelChart>

</ContentPage>

C# Code-Behind

using Syncfusion.Maui.Toolkit.Hosting;

namespace FunnelChartDemo;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        
        SfFunnelChart chart = new SfFunnelChart();
        
        chart.Title = new Label { Text = "School Admission Funnel" };
        chart.Legend = new ChartLegend();
        
        SalesFunnelViewModel viewModel = new SalesFunnelViewModel();
        chart.BindingContext = viewModel;
        
        chart.ItemsSource = viewModel.Data;
        chart.XBindingPath = "XValue";
        chart.YBindingPath = "YValue";
        chart.EnableTooltip = true;
        chart.ShowDataLabels = true;
        
        this.Content = chart;
    }
}

ViewModel

using System.Collections.Generic;

namespace FunnelChartDemo.ViewModels
{
    public class SalesFunnelViewModel
    {
        public List<FunnelDataModel> Data { get; set; }

        public SalesFunnelViewModel()
        {
            Data = new List<FunnelDataModel>()
            {
                new FunnelDataModel { XValue = "Prospects", YValue = 320 },
                new FunnelDataModel { XValue = "Inquiries", YValue = 290 },
                new FunnelDataModel { XValue = "Applicants", YValue = 245 },
                new FunnelDataModel { XValue = "Admits", YValue = 190 },
                new FunnelDataModel { XValue = "Enrolled", YValue = 175 }
            };
        }
    }

    public class FunnelDataModel
    {
        public string XValue { get; set; }
        public double YValue { get; set; }
    }
}

Key Properties Reference

PropertyTypeDescription
ItemsSourceIEnumerableData collection for the chart
XBindingPathstringProperty name for segment labels (category)
YBindingPathstringProperty name for segment values
ShowDataLabelsboolEnable/disable data labels
EnableTooltipboolEnable/disable tooltips
TitleLabelChart title
LegendChartLegendLegend configuration

Next Steps

Now that you have a basic funnel chart running, explore these advanced features:

Troubleshooting

Chart not displaying:

  • Verify the NuGet package is installed correctly
  • Ensure ConfigureSyncfusionToolkit() is called in MauiProgram.cs (see parent library getting-started)
  • Check that ItemsSource, XBindingPath, and YBindingPath are set
  • Verify your ViewModel is correctly bound to the chart

Data not showing:

  • Ensure the ViewModel's Data property is populated before binding
  • Verify property names in XBindingPath and YBindingPath match your model
  • Check for binding errors in the debug output

Build errors:

  • Run dotnet restore to restore NuGet packages
  • Clean and rebuild the solution
  • Verify you're targeting .NET 9 or later

Supporting file: references/legend.md

Legend in .NET MAUI Funnel Chart

The legend provides a visual guide to identify funnel chart segments, displaying a list of data points with corresponding icons and labels. This comprehensive guide covers legend initialization, customization, placement, interactivity, and advanced features.

Table of Contents

Defining the Legend

Initialize a ChartLegend instance and assign it to the Legend property of SfFunnelChart:

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    ItemsSource = new ViewModel().Data,
    XBindingPath = "XValue",
    YBindingPath = "YValue",
};

chart.Legend = new ChartLegend();
this.Content = chart;

Legend Visibility

Control legend visibility using the IsVisible property. The default value is true.

XAML

<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend IsVisible="True"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

chart.Legend = new ChartLegend()
{ 
    IsVisible = true 
};

Customizing Labels

Customize legend label appearance using the LabelStyle property with ChartLegendLabelStyle:

Available Properties

PropertyTypeDescription
TextColorColorColor of the legend text
FontFamilystringFont family for legend labels
FontAttributesFontAttributesFont style (Bold, Italic, None)
FontSizedoubleFont size for legend labels
MarginThicknessMargin around legend labels

XAML Example

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend>
            <chart:ChartLegend.LabelStyle>
                <chart:ChartLegendLabelStyle TextColor="Blue" 
                                            Margin="5" 
                                            FontSize="18" 
                                            FontAttributes="Bold" 
                                            FontFamily="PlaywriteAR-Regular"/>
            </chart:ChartLegend.LabelStyle>
        </chart:ChartLegend>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C# Example

SfFunnelChart chart = new SfFunnelChart()
{
    XBindingPath = "XValue",
    YBindingPath = "YValue",
    ItemsSource = new ViewModel().Data,
};

chart.Legend = new ChartLegend();
ChartLegendLabelStyle labelStyle = new ChartLegendLabelStyle()
{
    TextColor = Colors.Blue,
    FontSize = 18,
    FontAttributes = FontAttributes.Bold,
    Margin = 5,
    FontFamily = "PlaywriteAR-Regular"
};
chart.Legend.LabelStyle = labelStyle;

this.Content = chart;

Legend Icon

Customize legend icons using the LegendIcon property on SfFunnelChart. The default is Circle.

Available Icon Types

  • Circle (default)
  • Diamond
  • Rectangle
  • Pentagon
  • Triangle
  • InvertedTriangle
  • Cross
  • Plus
  • Hexagon
  • SeriesType

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue"
                     LegendIcon="Diamond">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    ItemsSource = new ViewModel().Data,
    XBindingPath = "XValue",
    YBindingPath = "YValue",
    LegendIcon = ChartLegendIconType.Diamond
};
chart.Legend = new ChartLegend();

this.Content = chart;

Placement

Position the legend relative to the chart area using the Placement property. The default is Top.

Available Placements

  • Top (default)
  • Bottom
  • Left
  • Right

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"  
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend Placement="Bottom"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    XBindingPath = "XValue",
    YBindingPath = "YValue",
    ItemsSource = new ViewModel().Data,
};
   
chart.Legend = new ChartLegend()
{ 
    Placement = LegendPlacement.Bottom 
};

this.Content = chart;

Floating Legend

Position the legend inside the chart area using IsFloating, OffsetX, and OffsetY properties. When IsFloating is true, the legend floats inside the chart based on the defined placement and offset values.

Properties

  • IsFloating (bool): Enable floating legend (default: false)
  • OffsetX (double): Horizontal distance from placement position
  • OffsetY (double): Vertical distance from placement position

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"  
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend Placement="Right"
                           IsFloating="True" 
                           OffsetX="-250" 
                           OffsetY="-100"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    XBindingPath = "XValue",
    YBindingPath = "YValue",
    ItemsSource = new ViewModel().Data,
};
   
chart.Legend = new ChartLegend()
{ 
    Placement = LegendPlacement.Top,
    IsFloating = true,
    OffsetX = -170,
    OffsetY = 30
};

this.Content = chart;

Toggle Series Visibility

Enable interactive segment visibility toggling by tapping legend items using the ToggleSeriesVisibility property. The default value is false.

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"         
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend ToggleSeriesVisibility="True"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    ItemsSource = viewModel.Data,
    XBindingPath = "XValue",
    YBindingPath = "YValue"
};

chart.Legend = new ChartLegend()
{
    ToggleSeriesVisibility = true
};

this.Content = chart;

Legend Maximum Size Request

Override the GetMaximumSizeCoefficient method in a custom ChartLegend class to control the maximum size of the legend view. The value should be between 0 and 1, representing the proportion of the chart area.

XAML

<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <local:LegendExt/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C# Custom Legend Class

public class LegendExt : ChartLegend
{
    protected override double GetMaximumSizeCoefficient()
    {
        return 0.7; // Legend can use up to 70% of chart area
    }
}

// Usage
SfFunnelChart chart = new SfFunnelChart();
chart.Legend = new LegendExt();
this.Content = chart;

Items Layout

Customize the arrangement of legend items using the ItemsLayout property. This accepts any layout type (e.g., FlexLayout, Grid, StackLayout).

FlexLayout Example (Wrapping Items)

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"  
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend>
            <chart:ChartLegend.ItemsLayout>
                <FlexLayout Wrap="Wrap" WidthRequest="400"/>
            </chart:ChartLegend.ItemsLayout>
        </chart:ChartLegend>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    ItemsSource = new ViewModel().Data,
    XBindingPath = "XValue",
    YBindingPath = "YValue",
};

ChartLegend legend = new ChartLegend();
legend.ItemsLayout = new FlexLayout()
{
    Wrap = FlexWrap.Wrap,
    WidthRequest = 400
};

chart.Legend = legend;
this.Content = chart;

Grid Layout Example

ChartLegend legend = new ChartLegend();
Grid grid = new Grid
{
    ColumnDefinitions =
    {
        new ColumnDefinition { Width = GridLength.Auto },
        new ColumnDefinition { Width = GridLength.Auto }
    }
};
legend.ItemsLayout = grid;
chart.Legend = legend;

Item Template

Customize the appearance of individual legend items using the ItemTemplate property with a DataTemplate.

Note: The BindingContext of the template is the ChartLegendItem provided by the legend.

XAML

<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     x:Name="chart"
                     XBindingPath="XValue"  
                     YBindingPath="YValue">
    
    <chart:SfFunnelChart.Resources>
        <DataTemplate x:Key="legendTemplate">
            <StackLayout Orientation="Horizontal">
                <Rectangle HeightRequest="12" 
                           WidthRequest="12" 
                           Margin="3"
                           Background="{Binding IconBrush}"/>
                <Label Text="{Binding XValue}" 
                       Margin="3"
                       VerticalOptions="Center"/>
            </StackLayout>
        </DataTemplate>
    </chart:SfFunnelChart.Resources>  
    
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend ItemTemplate="{StaticResource legendTemplate}"/>
    </chart:SfFunnelChart.Legend>
    
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart()
{
    ItemsSource = new ViewModel().Data,
    XBindingPath = "XValue",
    YBindingPath = "YValue",
};
     
ChartLegend legend = new ChartLegend();
legend.ItemTemplate = chart.Resources["legendTemplate"] as DataTemplate;
chart.Legend = legend;

this.Content = chart;

LegendItemCreated Event

The LegendItemCreated event fires when each legend item is created, allowing runtime customization of legend items.

Event Arguments Properties

PropertyTypeDescription
TextstringLegend item text
TextColorColorText color
FontFamilystringFont family
FontAttributesFontAttributesFont style
FontSizedoubleFont size
TextMarginThicknessText margin
IconBrushBrushIcon color
IconTypeChartLegendIconTypeIcon type
IconHeightdoubleIcon height
IconWidthdoubleIcon width
IsToggledboolToggle state
DisableBrushBrushColor when toggled off
IndexintItem index
ItemobjectAssociated data item

XAML

<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend LegendItemCreated="OnLegendItemCreated"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>

C# Event Handler

private void OnLegendItemCreated(object sender, LegendItemEventArgs e)
{
    // Customize the first legend item
    if (e.LegendItem.Index == 0)
    {
        e.LegendItem.IconBrush = new SolidColorBrush(Colors.Red);
        e.LegendItem.FontSize = 16;
        e.LegendItem.FontAttributes = FontAttributes.Bold;
    }
    
    // Make specific items stand out
    if (e.LegendItem.Text == "Prospects")
    {
        e.LegendItem.TextColor = Colors.Green;
        e.LegendItem.IconType = ChartLegendIconType.Diamond;
    }
}

Limitations

When using ItemsLayout and ItemTemplate:

  1. Do not add items explicitly to the layout
  2. Do not bind ItemsSource explicitly when using BindableLayouts
  3. Orientation recommendations:
    • Vertical arrangement for Left/Right placements
    • Horizontal arrangement for Top/Bottom placements
  4. Scrolling behavior:
    • Scrolling enabled if layout exceeds MaximumHeightRequest
  5. MaximumHeightRequest:
    • If set to 1 and layout is larger than chart, series may not render properly

Complete Examples

Example 1: Bottom-Placed Legend with Custom Styling

<chart:SfFunnelChart ItemsSource="{Binding Data}"
                     XBindingPath="Stage"
                     YBindingPath="Value"
                     LegendIcon="Pentagon">
    
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend Placement="Bottom">
            <chart:ChartLegend.LabelStyle>
                <chart:ChartLegendLabelStyle FontSize="14"
                                            FontAttributes="Bold"
                                            TextColor="DarkSlateGray"
                                            Margin="8"/>
            </chart:ChartLegend.LabelStyle>
        </chart:ChartLegend>
    </chart:SfFunnelChart.Legend>
    
</chart:SfFunnelChart>

Example 2: Floating Legend with Toggle

chart.Legend = new ChartLegend()
{
    Placement = LegendPlacement.Right,
    IsFloating = true,
    OffsetX = -200,
    OffsetY = -80,
    ToggleSeriesVisibility = true
};

Example 3: Custom Legend Template

<DataTemplate x:Key="customLegendTemplate">
    <Border Padding="8"
            Background="LightGray"
            Stroke="Gray"
            StrokeThickness="1">
        <StackLayout Orientation="Horizontal" Spacing="8">
            <BoxView Color="{Binding IconBrush}" 
                     WidthRequest="16" 
                     HeightRequest="16"
                     CornerRadius="8"/>
            <Label Text="{Binding Text}" 
                   FontSize="14"
                   FontAttributes="Bold"
                   VerticalOptions="Center"/>
        </StackLayout>
    </Border>
</DataTemplate>

Best Practices

  1. Placement:

    • Use Bottom/Top for horizontal charts
    • Use Left/Right for vertical charts
    • Avoid overlapping chart content
  2. Visibility:

    • Enable ToggleSeriesVisibility for interactive exploration
    • Keep toggle behavior intuitive
  3. Styling:

    • Ensure text is readable against backgrounds
    • Use consistent icon types across charts
    • Match font styles to your application theme
  4. Floating Legends:

    • Test offsets on different screen sizes
    • Ensure floating legend doesn't obscure critical data
  5. Performance:

    • Use simple templates for better rendering performance
    • Avoid complex layouts with many legend items

Troubleshooting

Legend not appearing:

  • Verify Legend property is set to a ChartLegend instance
  • Ensure IsVisible is true (default)
  • Check that data is bound correctly

Legend items cut off:

  • Adjust MaximumSizeCoefficient to allow more space
  • Use ItemsLayout with wrapping
  • Consider different placement

Toggle not working:

  • Set ToggleSeriesVisibility="True"
  • Verify legend items are clickable (not obscured)

Custom template not showing:

  • Ensure template resource key matches reference
  • Verify BindingContext properties exist on ChartLegendItem
  • Check for binding errors in output window

Supporting file: references/tooltip.md

Tooltip in .NET MAUI Funnel Chart

Tooltips provide additional information when hovering over funnel segments, enhancing user interaction and data comprehension. By default, tooltips display the Y value (segment value), but you can customize appearance and content extensively.

Enable Tooltip

Set the EnableTooltip property to true on SfFunnelChart to enable tooltips. The default value is false.

XAML

<chart:SfFunnelChart EnableTooltip="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";
chart.EnableTooltip = true;

this.Content = chart;

Tooltip Behavior Customization

Use ChartTooltipBehavior to customize tooltip appearance and behavior. Create an instance and assign it to the TooltipBehavior property.

Available Properties

PropertyTypeDescription
BackgroundBrushBackground color of tooltip
FontAttributesFontAttributesFont style (Bold, Italic, None)
FontFamilystringFont family for tooltip text
FontSizefloatFont size
DurationintDisplay duration in seconds
MarginThicknessMargin around tooltip content
TextColorColorText color

XAML

<chart:SfFunnelChart EnableTooltip="True">
    <chart:SfFunnelChart.TooltipBehavior>
        <chart:ChartTooltipBehavior Duration="4"
                                   Background="LightBlue"
                                   TextColor="Black"
                                   FontSize="14"
                                   FontAttributes="Bold"
                                   Margin="10"/>
    </chart:SfFunnelChart.TooltipBehavior>
</chart:SfFunnelChart>

C#

SfFunnelChart chart = new SfFunnelChart();
chart.EnableTooltip = true;

chart.TooltipBehavior = new ChartTooltipBehavior()
{
    Duration = 4,
    Background = new SolidColorBrush(Colors.LightBlue),
    TextColor = Colors.Black,
    FontSize = 14,
    FontAttributes = FontAttributes.Bold,
    Margin = new Thickness(10)
};

this.Content = chart;

Tooltip Template

Use TooltipTemplate to create custom tooltip layouts that display additional information beyond the default Y value.

Template Binding Context

The tooltip template's binding context provides access to:

  • Item.XValue - The segment's X-axis value (category/label)
  • Item.YValue - The segment's Y-axis value (numeric data)

XAML with Resource Dictionary

<Grid x:Name="grid">
    <Grid.Resources>
        <DataTemplate x:Key="tooltipTemplate">
            <StackLayout Orientation="Horizontal">
                <Label Text="{Binding Item.XValue}"
                       TextColor="White"
                       FontAttributes="Bold"
                       HorizontalOptions="Center"
                       VerticalOptions="Center"/>
                <Label Text="{Binding Item.YValue, StringFormat=': {0}'}"
                       TextColor="White"
                       FontAttributes="Bold"
                       HorizontalOptions="Center"
                       VerticalOptions="Center"/>
            </StackLayout>
        </DataTemplate>
    </Grid.Resources>

    <chart:SfFunnelChart EnableTooltip="True"
                         TooltipTemplate="{StaticResource tooltipTemplate}">
        
    </chart:SfFunnelChart>
</Grid>

C# with DataTemplate

SfFunnelChart chart = new SfFunnelChart();
chart.EnableTooltip = true;
chart.TooltipTemplate = grid.Resources["tooltipTemplate"] as DataTemplate;

this.Content = chart;

Custom Tooltip Examples

Example 1: Simple Custom Tooltip

<DataTemplate x:Key="simpleTooltip">
    <Frame Background="#2C3E50" 
           Padding="12" 
           CornerRadius="8"
           HasShadow="True">
        <Label Text="{Binding Item.YValue, StringFormat='Value: {0:N0}'}"
               TextColor="White"
               FontSize="16"
               FontAttributes="Bold"/>
    </Frame>
</DataTemplate>

Example 2: Detailed Tooltip with Multiple Values

<DataTemplate x:Key="detailedTooltip">
    <Border Background="White"
            Stroke="Gray"
            StrokeThickness="1"
            Padding="15">
        <VerticalStackLayout Spacing="8">
            <Label Text="{Binding Item.XValue}"
                   FontSize="18"
                   FontAttributes="Bold"
                   TextColor="Black"/>
            <BoxView HeightRequest="1" 
                     Background="LightGray"/>
            <HorizontalStackLayout Spacing="5">
                <Label Text="Count:"
                       FontSize="14"
                       TextColor="Gray"/>
                <Label Text="{Binding Item.YValue, StringFormat='{0:N0}'}"
                       FontSize="14"
                       FontAttributes="Bold"
                       TextColor="Black"/>
            </HorizontalStackLayout>
        </VerticalStackLayout>
    </Border>
</DataTemplate>

Example 3: Tooltip with Icon and Percentage

<DataTemplate x:Key="iconTooltip">
    <Grid Background="#34495E" 
          Padding="12">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        
        <BoxView Grid.Column="0"
                 WidthRequest="24"
                 HeightRequest="24"
                 Background="{Binding IconBrush}"
                 CornerRadius="12"
                 Margin="0,0,10,0"/>
        
        <VerticalStackLayout Grid.Column="1" Spacing="4">
            <Label Text="{Binding Item.XValue}"
                   TextColor="White"
                   FontSize="14"
                   FontAttributes="Bold"/>
            <Label Text="{Binding Item.YValue, StringFormat='{0:N0} users'}"
                   TextColor="LightGray"
                   FontSize="12"/>
        </VerticalStackLayout>
    </Grid>
</DataTemplate>

Example 4: C# Code-Behind Custom Template

public DataTemplate CreateCustomTooltipTemplate()
{
    return new DataTemplate(() =>
    {
        var frame = new Frame
        {
            BackgroundColor = Color.FromArgb("#16A085"),
            Padding = new Thickness(15),
            CornerRadius = 10,
            HasShadow = true
        };

        var stackLayout = new VerticalStackLayout { Spacing = 5 };

        var stageLabel = new Label
        {
            FontSize = 16,
            FontAttributes = FontAttributes.Bold,
            TextColor = Colors.White
        };
        stageLabel.SetBinding(Label.TextProperty, "Item.XValue");

        var valueLabel = new Label
        {
            FontSize = 14,
            TextColor = Colors.White
        };
        valueLabel.SetBinding(Label.TextProperty, new Binding("Item.YValue", stringFormat: "Count: {0:N0}"));

        stackLayout.Children.Add(stageLabel);
        stackLayout.Children.Add(valueLabel);
        frame.Content = stackLayout;

        return frame;
    });
}

// Usage
chart.TooltipTemplate = CreateCustomTooltipTemplate();

Complete Working Example

XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:chart="clr-namespace:Syncfusion.Maui.Toolkit.Charts;assembly=Syncfusion.Maui.Toolkit"
             xmlns:model="clr-namespace:YourApp.ViewModels">

    <Grid x:Name="grid">
        <Grid.Resources>
            <DataTemplate x:Key="tooltipTemplate">
                <Frame Background="#2980B9" 
                       Padding="12" 
                       CornerRadius="8">
                    <VerticalStackLayout Spacing="5">
                        <Label Text="{Binding Item.XValue}"
                               TextColor="White"
                               FontSize="16"
                               FontAttributes="Bold"/>
                        <Label Text="{Binding Item.YValue, StringFormat='Value: {0:N0}'}"
                               TextColor="White"
                               FontSize="14"/>
                    </VerticalStackLayout>
                </Frame>
            </DataTemplate>
        </Grid.Resources>

        <chart:SfFunnelChart ItemsSource="{Binding Data}"
                             XBindingPath="Stage"
                             YBindingPath="Count"
                             EnableTooltip="True"
                             TooltipTemplate="{StaticResource tooltipTemplate}">

            <chart:SfFunnelChart.BindingContext>
                <model:SalesFunnelViewModel/>
            </chart:SfFunnelChart.BindingContext>

            <chart:SfFunnelChart.TooltipBehavior>
                <chart:ChartTooltipBehavior Duration="3"/>
            </chart:SfFunnelChart.TooltipBehavior>

        </chart:SfFunnelChart>
    </Grid>

</ContentPage>

C# Code-Behind

using Syncfusion.Maui.Toolkit.Charts;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        Grid grid = new Grid();
        
        // Create custom tooltip template
        DataTemplate tooltipTemplate = new DataTemplate(() =>
        {
            var frame = new Frame
            {
                BackgroundColor = Color.FromArgb("#2980B9"),
                Padding = new Thickness(12),
                CornerRadius = 8
            };

            var stackLayout = new VerticalStackLayout { Spacing = 5 };

            var stageLabel = new Label
            {
                FontSize = 16,
                FontAttributes = FontAttributes.Bold,
                TextColor = Colors.White
            };
            stageLabel.SetBinding(Label.TextProperty, "Item.XValue");

            var valueLabel = new Label
            {
                FontSize = 14,
                TextColor = Colors.White
            };
            valueLabel.SetBinding(Label.TextProperty, 
                new Binding("Item.YValue", stringFormat: "Value: {0:N0}"));

            stackLayout.Children.Add(stageLabel);
            stackLayout.Children.Add(valueLabel);
            frame.Content = stackLayout;

            return frame;
        });

        // Create chart
        SfFunnelChart chart = new SfFunnelChart();
        SalesFunnelViewModel viewModel = new SalesFunnelViewModel();
        chart.BindingContext = viewModel;

        chart.ItemsSource = viewModel.Data;
        chart.XBindingPath = "Stage";
        chart.YBindingPath = "Count";
        chart.EnableTooltip = true;
        chart.TooltipTemplate = tooltipTemplate;

        chart.TooltipBehavior = new ChartTooltipBehavior
        {
            Duration = 3
        };

        grid.Children.Add(chart);
        this.Content = grid;
    }
}

Best Practices

  1. Content:

    • Keep tooltip content concise and relevant
    • Show the most important information first
    • Use clear labels for numeric values
  2. Styling:

    • Ensure sufficient color contrast for readability
    • Use consistent styling across your application
    • Avoid overly complex layouts that slow rendering
  3. Duration:

    • Set appropriate Duration based on content complexity
    • Default (2 seconds) works for simple tooltips
    • Increase for tooltips with more information
  4. Template Design:

    • Use padding and margins for breathing room
    • Keep template size reasonable (not too large)
    • Test on different screen sizes
  5. Accessibility:

    • Use readable font sizes (minimum 12-14)
    • Ensure text contrasts with background
    • Consider users with visual impairments

Troubleshooting

Tooltip not appearing:

  • Verify EnableTooltip="True" is set
  • Check that chart has data bound correctly
  • Ensure segments are not too small to hover over

Tooltip displays default format:

  • Confirm TooltipTemplate is properly assigned
  • Verify resource key matches in XAML
  • Check binding paths in template

Tooltip styling not applied:

  • Ensure TooltipBehavior is set before rendering
  • Verify brush/color values are valid
  • Check for binding errors in debug output

Custom template not showing data:

  • Use correct binding path: Item.XValue or Item.YValue
  • Verify ViewModel properties match binding paths
  • Check for null values in data source

Tooltip disappears too quickly:

  • Increase Duration property value
  • Duration is in seconds (e.g., Duration="5" for 5 seconds)

How do I install Implementing funnel charts in .NET MAUI in Cursor, Claude Code, or Codex?

Run npx skills add syncfusion/maui-toolkit-ui-components-skills --skill syncfusion-maui-toolkit-funnel-charts in the project where you want it, then ask your agent for the skill by name. The --skill flag installs only Implementing funnel charts in .NET MAUI, not every skill in the repository.

Where does Implementing funnel charts in .NET MAUI come from and what license is it under?

Implementing funnel charts in .NET MAUI comes from the syncfusion/maui-toolkit-ui-components-skills repository on GitHub. That repository has 39 GitHub stars. No license was detected on the source repository, so check with the author before redistributing it.

Prefer plain text? Read the Implementing funnel charts in .NET MAUI guide as markdown.