---
name: "Implementing funnel charts in .NET MAUI"
repo: https://github.com/syncfusion/maui-ui-components-skills
source: https://github.com/syncfusion/maui-ui-components-skills/blob/HEAD/skills/syncfusion-maui-funnel-charts/SKILL.md
license: not specified
install: "npx skills add syncfusion/maui-ui-components-skills --skill syncfusion-maui-funnel-charts"
page: https://100xlab.com/resources/agent-skills/syncfusion-maui-ui-components-skills--syncfusion-maui-funnel-charts--10magld
---

# 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

> **Notice:** After Volume 1 2025 (Mid March 2025), feature enhancements for this control will no longer be available in the Syncfusion package. Please switch to the **Syncfusion Toolkit for .NET MAUI** for continued support.

## Documentation and Navigation Guide

### Getting Started
📄 **Read:** [references/getting-started.md](references/getting-started.md)
- NuGet package installation (`Syncfusion.Maui.Charts`)
- 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](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](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](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](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](references/advanced-features.md)
- Orientation (Vertical vs Horizontal)
- Segment spacing configuration
- Liquid Glass Effect implementation
- Gap ratio and size settings
- Visual effects and polish

### Exporting
📄 **Read:** [references/exporting.md](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, segment spacing, and the modern Liquid Glass Effect for enhanced visual appeal.

## Table of Contents
- [Orientation](#orientation)
- [Segment Spacing](#segment-spacing)
- [Liquid Glass Effect](#liquid-glass-effect)

## 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
```xaml
<chart:SfFunnelChart Orientation="Horizontal"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

### C#
```csharp
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

```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts">
    
    <VerticalStackLayout Spacing="20" Padding="10">
        
        <!-- Vertical Funnel -->
        <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>
        
        <!-- Horizontal Funnel -->
        <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
```xaml
<chart:SfFunnelChart GapRatio="0.2"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

### C#
```csharp
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)
```xaml
<chart:SfFunnelChart GapRatio="0"/>
```
- Segments touch each other
- Traditional funnel appearance
- Best for emphasizing flow

#### Small Gap
```xaml
<chart:SfFunnelChart GapRatio="0.1"/>
```
- Subtle separation
- Maintains funnel shape
- Slightly improved segment distinction

#### Medium Gap
```xaml
<chart:SfFunnelChart GapRatio="0.2"/>
```
- Noticeable separation
- Good balance between flow and distinction
- Recommended for most use cases

#### Large Gap
```xaml
<chart:SfFunnelChart GapRatio="0.5"/>
```
- Significant separation
- Individual segments stand out
- May lose funnel metaphor

### Segment Spacing with Visual Enhancements

```xaml
<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>
```

## Liquid Glass Effect

The Liquid Glass Effect is a modern design style providing a sleek, minimalist appearance with smooth rounded corners and sophisticated visual treatments. It creates a polished, professional look for your charts.

> **Platform Requirements:**
> - **.NET 10** or later
> - **iOS 26+** or **macOS 26+**
> - Not supported on Android or Windows

### Features
- **Tooltip**: Applies a glassy appearance to tooltips
- **Chart Background**: Blurred or clear glass effect using `SfGlassEffectView`

### Enable Liquid Glass Effect for Tooltip

Set `EnableLiquidGlassEffect` and `EnableTooltip` to `true`:

#### XAML
```xaml
<chart:SfFunnelChart EnableLiquidGlassEffect="True"
                     EnableTooltip="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

#### C#
```csharp
SfFunnelChart chart = new SfFunnelChart();
chart.ItemsSource = viewModel.Data;
chart.XBindingPath = "XValue";
chart.YBindingPath = "YValue";
chart.EnableLiquidGlassEffect = true;
chart.EnableTooltip = true;

this.Content = chart;
```

### Apply Glass Effect to Chart Background

Wrap the `SfFunnelChart` inside an `SfGlassEffectView` (from `Syncfusion.Maui.Core` package):

#### XAML
```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts"
             xmlns:core="clr-namespace:Syncfusion.Maui.Core;assembly=Syncfusion.Maui.Core">

    <core:SfGlassEffectView CornerRadius="20"
                            Padding="12"
                            EffectType="Regular"
                            EnableShadowEffect="True">

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

    </core:SfGlassEffectView>

</ContentPage>
```

#### C#
```csharp
using Syncfusion.Maui.Charts;
using Syncfusion.Maui.Core;

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

var glassView = new SfGlassEffectView
{
    CornerRadius = 20,
    Padding = 12,
    EffectType = GlassEffectType.Regular, // Regular (blurrier) or Clear (glassy)
    EnableShadowEffect = true,
    Content = chart
};

this.Content = glassView;
```

### SfGlassEffectView Properties

| Property | Type | Description |
|----------|------|-------------|
| `EffectType` | GlassEffectType | `Regular` (blurrier) or `Clear` (glassy) |
| `CornerRadius` | double | Rounded corner radius |
| `Padding` | Thickness | Inner padding |
| `EnableShadowEffect` | bool | Enable drop shadow |

### Effect Type Comparison

**Regular Effect:**
- More blurred background
- Softer appearance
- Better for colorful backgrounds
- Creates stronger depth perception

**Clear Effect:**
- Crisper, glassy look
- Subtle blur
- Better for simple backgrounds
- More modern aesthetic

### Complete Liquid Glass Example

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

    <!-- Background Image -->
    <Grid>
        <Image Source="background_gradient.png" 
               Aspect="AspectFill"/>
        
        <core:SfGlassEffectView CornerRadius="20"
                                Padding="15"
                                Margin="20"
                                EffectType="Regular"
                                EnableShadowEffect="True"
                                VerticalOptions="Center"
                                HorizontalOptions="Center">

            <chart:SfFunnelChart ItemsSource="{Binding Data}"
                                 XBindingPath="Stage"
                                 YBindingPath="Value"
                                 EnableLiquidGlassEffect="True"
                                 EnableTooltip="True"
                                 ShowDataLabels="True"
                                 WidthRequest="400"
                                 HeightRequest="500">

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

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

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

            </chart:SfFunnelChart>

        </core:SfGlassEffectView>
    </Grid>

</ContentPage>
```

### Best Practices for Liquid Glass Effect

1. **Background Selection:**
   - Use images or colorful backgrounds for maximum effect
   - Plain backgrounds reduce glass effect visibility
   - Gradient backgrounds work exceptionally well

2. **Effect Type:**
   - Use `Regular` for vibrant, colorful backgrounds
   - Use `Clear` for subtle, minimalist designs
   - Test both on your specific background

3. **Corner Radius & Padding:**
   - Balance content density with visual polish
   - Typical values: `CornerRadius="15-25"`, `Padding="12-20"`
   - Adjust based on chart size

4. **Custom Tooltip Template:**
   - When using `TooltipTemplate`, set background to `Transparent`
   - This allows the glass effect to show through
   - Avoid opaque backgrounds in custom tooltips

5. **Platform Compatibility:**
   - Check platform version before enabling
   - Provide fallback styling for unsupported platforms
   - Test on actual iOS/macOS devices

### Liquid Glass with Custom Tooltip Template

```xaml
<Grid.Resources>
    <DataTemplate x:Key="glassTooltip">
        <!-- Use transparent background to show glass effect -->
        <Frame Background="Transparent" Padding="10">
            <VerticalStackLayout Spacing="5">
                <Label Text="{Binding Item.XValue}"
                       TextColor="White"
                       FontSize="16"
                       FontAttributes="Bold"/>
                <Label Text="{Binding Item.YValue, StringFormat='{0:N0}'}"
                       TextColor="White"
                       FontSize="14"/>
            </VerticalStackLayout>
        </Frame>
    </DataTemplate>
</Grid.Resources>

<chart:SfFunnelChart EnableLiquidGlassEffect="True"
                     EnableTooltip="True"
                     TooltipTemplate="{StaticResource glassTooltip}"/>
```

## Combining Advanced Features

### Example: Horizontal Funnel with Spacing and Glass Effect

```xaml
<core:SfGlassEffectView CornerRadius="20"
                        Padding="15"
                        EffectType="Clear"
                        EnableShadowEffect="True">

    <chart:SfFunnelChart ItemsSource="{Binding Data}"
                         XBindingPath="Stage"
                         YBindingPath="Value"
                         Orientation="Horizontal"
                         GapRatio="0.15"
                         EnableLiquidGlassEffect="True"
                         EnableTooltip="True"
                         ShowDataLabels="True">

        <chart:SfFunnelChart.DataLabelSettings>
            <chart:FunnelDataLabelSettings LabelPlacement="Center"/>
        </chart:SfFunnelChart.DataLabelSettings>

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

    </chart:SfFunnelChart>

</core:SfGlassEffectView>
```

## Performance Considerations

1. **Liquid Glass Effect:**
   - May impact performance on lower-end devices
   - Test on target devices
   - Consider disabling for complex layouts

2. **Segment Spacing:**
   - Minimal performance impact
   - Safe to use in all scenarios

3. **Orientation:**
   - No performance difference between orientations
   - Choose based on design requirements

## Troubleshooting

**Liquid Glass Effect not visible:**
- Verify platform requirements (.NET 10, iOS/macOS 26+)
- Ensure `EnableLiquidGlassEffect="True"` is set
- Check that chart is on a colorful background
- Confirm `Syncfusion.Maui.Core` package is installed

**Segments appear disconnected:**
- `GapRatio` might be too high
- Reduce value (e.g., from 0.5 to 0.2)
- Consider if spacing suits your design intent

**Orientation not changing:**
- Verify spelling: `Orientation="Horizontal"` (not `Horizontal`)
- Ensure property is set on `SfFunnelChart`
- Check that chart has sufficient space to render

**Glass effect looks wrong:**
- Try switching between `Regular` and `Clear` effect types
- Adjust `CornerRadius` and `Padding`
- Verify background provides sufficient contrast

---

## 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

```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue"
                     PaletteBrushes="{Binding CustomBrushes}">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

### ViewModel with Custom Colors

```csharp
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

```csharp
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

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

#### ViewModel with Linear Gradients

```csharp
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

```csharp
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

```csharp
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

```csharp
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

```csharp
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

```csharp
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

```csharp
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
```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts"
             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

```csharp
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](#enable-data-labels)
- [Data Label Customization](#data-label-customization)
- [Label Placement](#label-placement)
- [Label Context](#label-context)
- [UseSeriesPalette](#useseriespalette)
- [Label Style Properties](#label-style-properties)
- [Complete Examples](#complete-examples)

## Enable Data Labels

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

### XAML
```xaml
<chart:SfFunnelChart ShowDataLabels="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

### C#
```csharp
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

```xaml
<chart:SfFunnelChart ShowDataLabels="True">
    <chart:SfFunnelChart.DataLabelSettings>
        <chart:FunnelDataLabelSettings LabelPlacement="Outer" 
                                       Context="XValue" 
                                       UseSeriesPalette="True"/>
    </chart:SfFunnelChart.DataLabelSettings>
</chart:SfFunnelChart>
```

```csharp
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:

| Placement | Description |
|-----------|-------------|
| `Auto` | Automatically determines the best position (default) |
| `Inner` | Labels appear inside segments |
| `Center` | Labels appear at the center of segments |
| `Outer` | Labels appear outside segments |

### Auto Placement (Default)
```xaml
<chart:FunnelDataLabelSettings LabelPlacement="Auto"/>
```

### Inner Placement
```xaml
<chart:FunnelDataLabelSettings LabelPlacement="Inner"/>
```

```csharp
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Inner
};
```

### Center Placement
```xaml
<chart:FunnelDataLabelSettings LabelPlacement="Center"/>
```

```csharp
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Center
};
```

### Outer Placement
```xaml
<chart:FunnelDataLabelSettings LabelPlacement="Outer"/>
```

```csharp
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    LabelPlacement = DataLabelPlacement.Outer
};
```

## Label Context

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

| Context | Description |
|---------|-------------|
| `YValue` | Display the Y-axis value (default) |
| `XValue` | Display the X-axis label/category |

### Display Y Values (Numeric Data)
```xaml
<chart:FunnelDataLabelSettings Context="YValue"/>
```

```csharp
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    Context = FunnelDataLabelContext.YValue
};
```

### Display X Values (Category Labels)
```xaml
<chart:FunnelDataLabelSettings Context="XValue"/>
```

```csharp
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
```xaml
<chart:FunnelDataLabelSettings UseSeriesPalette="True"/>
```

### C#
```csharp
chart.DataLabelSettings = new FunnelDataLabelSettings()
{
    UseSeriesPalette = true
};
```

## Label Style Properties

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

| Property | Type | Description |
|----------|------|-------------|
| `Margin` | Thickness | Spacing around the label |
| `Background` | Brush | Label background color |
| `FontAttributes` | FontAttributes | Font style (Bold, Italic, None) |
| `FontSize` | double | Font size |
| `Stroke` | Brush | Border color |
| `StrokeWidth` | double | Border thickness |
| `CornerRadius` | CornerRadius | Rounded corners |
| `TextColor` | Color | Text color |

### Basic Label Styling

```xaml
<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

```xaml
<chart:ChartDataLabelStyle Margin="8"
                          FontSize="16"
                          TextColor="White"
                          FontAttributes="Bold"
                          Background="#2196F3"
                          Stroke="#1976D2"
                          StrokeWidth="2"
                          CornerRadius="8"/>
```

```csharp
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

```xaml
<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

```csharp
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

```xaml
<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

```csharp
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)
```csharp
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)
```csharp
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

```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts">
    <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>
```

```csharp
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:

| Platform | Default Location |
|----------|------------------|
| **Android** | `Pictures` directory in file system |
| **Windows** | `Pictures` directory in file system |
| **iOS** | `Photos/Album` directory |
| **macOS** | `Pictures` directory in file system |

## Platform-Specific Permissions

### Android

Add file writing permissions in `AndroidManifest.xml`:

```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:

```xml
<application android:requestLegacyExternalStorage="true">
```

### iOS

Add permission descriptions in `Info.plist`:

```xml
<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

```csharp
Task<Stream> GetStreamAsync(ImageFileFormat format)
```

### Supported Formats
- `ImageFileFormat.Jpeg`
- `ImageFileFormat.Png`

### Basic Usage

```csharp
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

```csharp
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

```csharp
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

```csharp
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

```csharp
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
```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.Charts;assembly=Syncfusion.Maui.Charts"
             xmlns:model="clr-namespace:YourApp.ViewModels">

    <Grid RowDefinitions="*, Auto">
        
        <!-- Chart -->
        <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>
        
        <!-- Export Controls -->
        <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
```csharp
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.Charts` 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.Charts`
3. Install the latest version
4. Ensure dependencies are installed and the project is restored

### Option 2: .NET CLI
```bash
dotnet add package Syncfusion.Maui.Charts
```

### Option 3: Package Manager Console
```powershell
Install-Package Syncfusion.Maui.Charts
```

> **Note:** `Syncfusion.Maui.Core` is automatically installed as a required dependency. Ensure handler registration is configured in `MauiProgram.cs` (see parent library's [getting-started](../../getting-started/) guide).

### Step 2: Register the Syncfusion Handler

**CRITICAL:** The `Syncfusion.Maui.Core` NuGet is a dependent package for all Syncfusion controls. You MUST register the handler in `MauiProgram.cs`.

**File:** `MauiProgram.cs`

```csharp
using Syncfusion.Maui.Core.Hosting;

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

            return builder.Build();
        }
    }
}
```

**Important:** Without `ConfigureSyncfusionCore()`, the chart control will not work.

## Step 3: Import the Namespace

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

### XAML
```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.Charts;assembly=Syncfusion.Maui.Charts">
    <!-- Chart goes here -->
</ContentPage>
```

### C#
```csharp
using Syncfusion.Maui.Charts;
```

## Step 4: Initialize SfFunnelChart

### XAML Approach
```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts">
    <chart:SfFunnelChart/>
</ContentPage>
```

### C# Approach
```csharp
using Syncfusion.Maui.Charts;

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:

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

Create a ViewModel that provides the data collection:

```csharp
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
```xaml
<ContentPage xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts"
             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
```csharp
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
```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue" 
                     YBindingPath="YValue">
    
    <chart:SfFunnelChart.Title>
        <Label Text="School Admission Funnel"/>
    </chart:SfFunnelChart.Title>
    
</chart:SfFunnelChart>
```

### C#
```csharp
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
```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue" 
                     YBindingPath="YValue"
                     ShowDataLabels="True"
                     EnableTooltip="True">
    <!-- Other chart configurations -->
</chart:SfFunnelChart>
```

### C#
```csharp
chart.ShowDataLabels = true;
chart.EnableTooltip = true;
```

## Step 9: Add Legend

Display a legend to help users identify each funnel segment:

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

### C#
```csharp
chart.Legend = new ChartLegend();
```

## Complete Working Example

### XAML
```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.Charts;assembly=Syncfusion.Maui.Charts"
             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
```csharp
using Syncfusion.Maui.Charts;

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
```csharp
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

| Property | Type | Description |
|----------|------|-------------|
| `ItemsSource` | IEnumerable | Data collection for the chart |
| `XBindingPath` | string | Property name for segment labels (category) |
| `YBindingPath` | string | Property name for segment values |
| `ShowDataLabels` | bool | Enable/disable data labels |
| `EnableTooltip` | bool | Enable/disable tooltips |
| `Title` | Label | Chart title |
| `Legend` | ChartLegend | Legend configuration |

## Next Steps

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

- **[Data Labels](data-labels.md)** - Customize label placement, context, and styling
- **[Appearance](appearance.md)** - Apply custom colors and gradients
- **[Legend](legend.md)** - Configure legend placement, icons, and templates
- **[Tooltip](tooltip.md)** - Customize tooltip templates and behavior
- **[Advanced Features](advanced-features.md)** - Orientation, spacing, and visual effects

## Troubleshooting

**Chart not displaying:**
- Verify the NuGet package is installed correctly
- Ensure `ConfigureSyncfusionCore()` 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](#defining-the-legend)
- [Legend Visibility](#legend-visibility)
- [Customizing Labels](#customizing-labels)
- [Legend Icon](#legend-icon)
- [Placement](#placement)
- [Floating Legend](#floating-legend)
- [Toggle Series Visibility](#toggle-series-visibility)
- [Legend Maximum Size Request](#legend-maximum-size-request)
- [Items Layout](#items-layout)
- [Item Template](#item-template)
- [LegendItemCreated Event](#legenditemcreated-event)
- [Limitations](#limitations)

## Defining the Legend

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

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

### C#
```csharp
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
```xaml
<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend IsVisible="True"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C#
```csharp
chart.Legend = new ChartLegend()
{ 
    IsVisible = true 
};
```

## Customizing Labels

Customize legend label appearance using the `LabelStyle` property with `ChartLegendLabelStyle`:

### Available Properties

| Property | Type | Description |
|----------|------|-------------|
| `TextColor` | Color | Color of the legend text |
| `FontFamily` | string | Font family for legend labels |
| `FontAttributes` | FontAttributes | Font style (Bold, Italic, None) |
| `FontSize` | double | Font size for legend labels |
| `Margin` | Thickness | Margin around legend labels |

### XAML Example
```xaml
<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
```csharp
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
```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"
                     YBindingPath="YValue"
                     LegendIcon="Diamond">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C#
```csharp
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
```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"  
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend Placement="Bottom"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C#
```csharp
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
```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#
```csharp
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
```xaml
<chart:SfFunnelChart ItemsSource="{Binding Data}" 
                     XBindingPath="XValue"         
                     YBindingPath="YValue">
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend ToggleSeriesVisibility="True"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C#
```csharp
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
```xaml
<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <local:LegendExt/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C# Custom Legend Class
```csharp
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
```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#
```csharp
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

```csharp
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
```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#
```csharp
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

| Property | Type | Description |
|----------|------|-------------|
| `Text` | string | Legend item text |
| `TextColor` | Color | Text color |
| `FontFamily` | string | Font family |
| `FontAttributes` | FontAttributes | Font style |
| `FontSize` | double | Font size |
| `TextMargin` | Thickness | Text margin |
| `IconBrush` | Brush | Icon color |
| `IconType` | ChartLegendIconType | Icon type |
| `IconHeight` | double | Icon height |
| `IconWidth` | double | Icon width |
| `IsToggled` | bool | Toggle state |
| `DisableBrush` | Brush | Color when toggled off |
| `Index` | int | Item index |
| `Item` | object | Associated data item |

### XAML
```xaml
<chart:SfFunnelChart>
    <chart:SfFunnelChart.Legend>
        <chart:ChartLegend LegendItemCreated="OnLegendItemCreated"/>
    </chart:SfFunnelChart.Legend>
</chart:SfFunnelChart>
```

### C# Event Handler
```csharp
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

```xaml
<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

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

### Example 3: Custom Legend Template

```xaml
<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
```xaml
<chart:SfFunnelChart EnableTooltip="True"
                     ItemsSource="{Binding Data}"
                     XBindingPath="XValue"
                     YBindingPath="YValue">
    <!-- Chart configuration -->
</chart:SfFunnelChart>
```

### C#
```csharp
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

| Property | Type | Description |
|----------|------|-------------|
| `Background` | Brush | Background color of tooltip |
| `FontAttributes` | FontAttributes | Font style (Bold, Italic, None) |
| `FontFamily` | string | Font family for tooltip text |
| `FontSize` | float | Font size |
| `Duration` | int | Display duration in seconds |
| `Margin` | Thickness | Margin around tooltip content |
| `TextColor` | Color | Text color |

### XAML
```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#
```csharp
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

```xaml
<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 configuration -->
    </chart:SfFunnelChart>
</Grid>
```

### C# with DataTemplate

```csharp
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

```xaml
<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

```xaml
<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

```xaml
<DataTemplate x:Key="iconTooltip">
    <Grid Background="#34495E" 
          Padding="12">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <!-- Icon placeholder -->
        <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

```csharp
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
```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.Charts;assembly=Syncfusion.Maui.Charts"
             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
```csharp
using Syncfusion.Maui.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)
