
Syncfusion Maui Cartesian Charts
- 135 installs
- 60 repo stars
- Updated July 6, 2026
- syncfusion/maui-ui-components-skills
Use syncfusion-maui-cartesian-charts for development tasks
About
syncfusion-maui-cartesian-charts: A skill for development. This provides functionality for development workflows.
- syncfusion-maui-cartesian-charts
Syncfusion Maui Cartesian Charts by the numbers
- 135 all-time installs (skills.sh)
- +6 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #2,688 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/maui-ui-components-skills --skill syncfusion-maui-cartesian-chartsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 135 |
|---|---|
| repo stars | ★ 60 |
| Last updated | July 6, 2026 |
| Repository | syncfusion/maui-ui-components-skills ↗ |
What it does
Use syncfusion-maui-cartesian-charts for development tasks
Files
Implementing .NET MAUI Cartesian Charts
Guide users to implement the Syncfusion .NET MAUI Cartesian Chart (SfCartesianChart), a comprehensive data visualization solution with over 20 chart types, interactive features, and extensive customization options. Use this skill to implement charts ranging from simple line graphs to complex financial and statistical visualizations.
When to Use This Skill
Use this skill when the user needs to:
- Visualize Data: Display quantitative data with line, area, column, bar, or scatter charts
- Financial Analysis: Create candle or OHLC charts for stock price visualization
- Statistical Data: Plot box-and-whisker, histogram, or error bar charts
- Comparative Analysis: Use stacked charts (area, column, line) for comparing multiple datasets
- Range Visualization: Show high-low data with range area or range column charts
- Interactive Dashboards: Implement zooming, panning, selection, and trackball features
- Time-Series Data: Plot temporal data with datetime axes and auto-scrolling
- Custom Visualizations: Add annotations, plotbands, trendlines, and custom styling
Component Overview
The SfCartesianChart control provides:
- 20+ Chart Types: Line, Area, Column, Bar, Scatter, Bubble, Candle, OHLC, Histogram, Box-and-Whisker, Stacked variations, Range charts, Waterfall, and more
- Flexible Axes: Category, Numerical, DateTime, Logarithmic with full customization
- Interactive Features: Zooming, panning, selection, tooltips, trackball, crosshair
- Rich Customization: Data labels, legends, annotations, plotbands, trendlines, appearance
- Data Handling: Empty point modes, data binding, dynamic updates
- Export & Localization: Image export, multi-language support
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- NuGet package installation (
Syncfusion.Maui.Charts) - Basic SfCartesianChart initialization in XAML and C#
- Creating data models and view models
- Axis setup (XAxes, YAxes)
- Adding your first series with data binding
- Complete working example
Chart Types
Basic Chart Types
📄 Read: references/basic-chart-types.md
- Line, Area, Column, Bar, Scatter, Bubble charts
- When to use each chart type
- Implementation examples
- Common properties and styling
Financial Charts
📄 Read: references/financial-charts.md
- Candle charts (candlestick visualization)
- OHLC (Open-High-Low-Close) charts
- Financial data structure and binding
- Bullish/bearish styling
Statistical Charts
📄 Read: references/statistical-charts.md
- Box and Whisker charts
- Histogram charts
- Error Bar charts
- Statistical data requirements
Stacked Charts
📄 Read: references/stacked-charts.md
- Stacked Area (normal and 100%)
- Stacked Column (normal and 100%)
- Stacked Line (normal and 100%)
- Grouping series for stacking
- Percentage vs absolute values
Range Charts
📄 Read: references/range-charts.md
- Range Area charts
- Range Column charts
- Spline Range Area charts
- High-Low data binding
Advanced Chart Types
📄 Read: references/advanced-chart-types.md
- Fastline (optimized for large datasets)
- Step Area and Step Line
- Waterfall charts
- Performance considerations
Axis Configuration
Axis Basics
📄 Read: references/axis-configuration.md
- Axis types (Category, Numerical, DateTime, Logarithmic)
- XAxes and YAxes collections
- Axis labels and formatting
- Axis titles
- Multiple axes setup
- Custom label customization
Axis Customization
📄 Read: references/axis-customization.md
- Gridlines (major, minor) styling
- Tick lines configuration
- Axis padding
- Range padding
- Auto-scrolling delta
- Axis positioning
Data Visualization & Interaction
Data Labels
📄 Read: references/data-labels.md
- Enabling and positioning data labels
- Label placement (Inner, Outer, Auto)
- Label formatting and templates
- Styling and appearance
- Release mode display configuration
Tooltips and Interactive Features
📄 Read: references/tooltips-and-interaction.md
- Tooltip configuration and customization
- Trackball feature for multi-series comparison
- Crosshair for precise value reading
- Tooltip templates
- Interactive display modes
Zooming and Panning
📄 Read: references/zooming-and-panning.md
- Zoom modes (Pinch, Selection, MouseWheel)
- Panning configuration
- ZoomPanBehavior setup
- Programmatic zoom control
- Reset zoom functionality
Selection
📄 Read: references/selection.md
- Selection types (Single, Multiple, Series)
- DataPointSelectionBehavior
- SeriesSelectionBehavior
- Selection events
- Custom selection styling
Customization & Styling
Legend and Appearance
📄 Read: references/legend-and-appearance.md
- Legend configuration and positioning
- Legend item templates
- Chart appearance customization
- Color palettes
- Themes and liquid glass effect
Annotations and PlotBands
📄 Read: references/annotations-and-plotbands.md
- Annotation types (Text, View, Shape)
- Adding and positioning annotations
- PlotBand configuration for highlighting regions
- Use cases and examples
Custom Styling
📄 Read: references/customization-and-styling.md
- Series appearance customization
- Adding custom labels
- Color and gradient fills
- Border and corner radius
- Template customization
Data Handling & Advanced Features
Trendlines
📄 Read: references/trendlines.md
- Trendline types (Linear, Exponential, Logarithmic, Polynomial, Power, Moving Average)
- Adding trendlines to series
- Forecast and backcast
- Trendline customization
Data Point Management
📄 Read: references/data-handling.md
- Empty points handling
- Empty point modes (Gap, Zero, Average, Drop)
- Getting data points by region
- Touch position detection
- Data manipulation
Export and Localization
📄 Read: references/exporting-and-localization.md
- Exporting charts as images
- Export formats and options
- Localization configuration
- Culture-specific formatting
- Resource files
Advanced Chart Types
Table of Contents
Overview
Advanced chart types provide specialized visualization capabilities for specific data representation needs. These chart types offer performance optimization, step-based visualization, and financial analysis capabilities.
Available Advanced Chart Types:
- Fast Line: Optimized for large datasets (thousands of points)
- Step Area: Displays stepwise changes with filled area
- Step Line: Shows discrete value changes with step patterns
- Waterfall: Visualizes cumulative effects of sequential values
Fast Line Chart
Fast line chart is optimized for rendering large datasets with thousands of data points efficiently. It's ideal for real-time data visualization and performance-critical scenarios.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:FastLineSeries ItemsSource="{Binding LargeData}"
XBindingPath="Time"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
DateTimeAxis primaryAxis = new DateTimeAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
FastLineSeries series = new FastLineSeries()
{
ItemsSource = new ViewModel().LargeData,
XBindingPath = "Time",
YBindingPath = "Value"
};
chart.Series.Add(series);
this.Content = chart;Performance Data Model
public class TimeSeriesData
{
public DateTime Time { get; set; }
public double Value { get; set; }
}
public class ViewModel
{
public ObservableCollection<TimeSeriesData> LargeData { get; set; }
public ViewModel()
{
LargeData = new ObservableCollection<TimeSeriesData>();
GenerateLargeDataset();
}
private void GenerateLargeDataset()
{
Random random = new Random();
DateTime startDate = DateTime.Now.AddDays(-1000);
// Generate 10,000 data points
for (int i = 0; i < 10000; i++)
{
LargeData.Add(new TimeSeriesData
{
Time = startDate.AddMinutes(i),
Value = random.NextDouble() * 100
});
}
}
}Dashed Fast Line
<chart:SfCartesianChart>
<chart:SfCartesianChart.Resources>
<DoubleCollection x:Key="dashArray">
<x:Double>5</x:Double>
<x:Double>2</x:Double>
</DoubleCollection>
</chart:SfCartesianChart.Resources>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:FastLineSeries ItemsSource="{Binding LargeData}"
XBindingPath="Time"
YBindingPath="Value"
StrokeDashArray="{StaticResource dashArray}"/>
</chart:SfCartesianChart>DoubleCollection dashArray = new DoubleCollection { 5, 2 };
FastLineSeries series = new FastLineSeries()
{
ItemsSource = new ViewModel().LargeData,
XBindingPath = "Time",
YBindingPath = "Value",
StrokeDashArray = dashArray
};Anti-Aliasing
Enable anti-aliasing to reduce jagged edges:
<chart:FastLineSeries ItemsSource="{Binding LargeData}"
XBindingPath="Time"
YBindingPath="Value"
EnableAntiAliasing="True"/>FastLineSeries series = new FastLineSeries()
{
ItemsSource = new ViewModel().LargeData,
XBindingPath = "Time",
YBindingPath = "Value",
EnableAntiAliasing = true
};Note: Enabling anti-aliasing may slightly reduce performance but improves visual quality.
Step Area Chart
Step area charts display data changes over time with horizontal and vertical lines creating steps, with the area beneath filled.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:StepAreaSeries ItemsSource="{Binding ProductionData}"
XBindingPath="Month"
YBindingPath="Units"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
DateTimeAxis primaryAxis = new DateTimeAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
StepAreaSeries series = new StepAreaSeries()
{
ItemsSource = new ViewModel().ProductionData,
XBindingPath = "Month",
YBindingPath = "Units"
};
chart.Series.Add(series);
this.Content = chart;Data Model
public class ProductionModel
{
public DateTime Month { get; set; }
public double Units { get; set; }
}
public class ViewModel
{
public ObservableCollection<ProductionModel> ProductionData { get; set; }
public ViewModel()
{
ProductionData = new ObservableCollection<ProductionModel>
{
new ProductionModel { Month = new DateTime(2024, 1, 1), Units = 1200 },
new ProductionModel { Month = new DateTime(2024, 2, 1), Units = 1200 },
new ProductionModel { Month = new DateTime(2024, 3, 1), Units = 1500 },
new ProductionModel { Month = new DateTime(2024, 4, 1), Units = 1500 },
new ProductionModel { Month = new DateTime(2024, 5, 1), Units = 1800 },
new ProductionModel { Month = new DateTime(2024, 6, 1), Units = 1800 }
};
}
}Enable Markers
<chart:StepAreaSeries ItemsSource="{Binding ProductionData}"
XBindingPath="Month"
YBindingPath="Units"
ShowMarkers="True"/>StepAreaSeries series = new StepAreaSeries()
{
ItemsSource = new ViewModel().ProductionData,
XBindingPath = "Month",
YBindingPath = "Units",
ShowMarkers = true
};Marker Customization
<chart:StepAreaSeries ItemsSource="{Binding ProductionData}"
XBindingPath="Month"
YBindingPath="Units"
ShowMarkers="True">
<chart:StepAreaSeries.MarkerSettings>
<chart:ChartMarkerSettings Type="Diamond"
Fill="Orange"
Stroke="DarkOrange"
StrokeWidth="2"
Height="10"
Width="10"/>
</chart:StepAreaSeries.MarkerSettings>
</chart:StepAreaSeries>ChartMarkerSettings markerSettings = new ChartMarkerSettings()
{
Type = ShapeType.Diamond,
Fill = Colors.Orange,
Stroke = Colors.DarkOrange,
StrokeWidth = 2,
Height = 10,
Width = 10
};
StepAreaSeries series = new StepAreaSeries()
{
ItemsSource = new ViewModel().ProductionData,
XBindingPath = "Month",
YBindingPath = "Units",
ShowMarkers = true,
MarkerSettings = markerSettings
};Step Line Chart
Step line charts connect data points with horizontal and vertical lines, creating a stepped appearance ideal for showing discrete value changes.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:StepLineSeries ItemsSource="{Binding PriceData}"
XBindingPath="Date"
YBindingPath="Price"
Label="Product A"/>
<chart:StepLineSeries ItemsSource="{Binding PriceData2}"
XBindingPath="Date"
YBindingPath="Price"
Label="Product B"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
DateTimeAxis primaryAxis = new DateTimeAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
StepLineSeries series1 = new StepLineSeries()
{
ItemsSource = new ViewModel().PriceData,
XBindingPath = "Date",
YBindingPath = "Price",
Label = "Product A"
};
StepLineSeries series2 = new StepLineSeries()
{
ItemsSource = new ViewModel().PriceData2,
XBindingPath = "Date",
YBindingPath = "Price",
Label = "Product B"
};
chart.Series.Add(series1);
chart.Series.Add(series2);
this.Content = chart;Dashed Step Line
<chart:SfCartesianChart>
<chart:SfCartesianChart.Resources>
<DoubleCollection x:Key="dashArray">
<x:Double>5</x:Double>
<x:Double>3</x:Double>
</DoubleCollection>
</chart:SfCartesianChart.Resources>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:StepLineSeries ItemsSource="{Binding PriceData}"
XBindingPath="Date"
YBindingPath="Price"
StrokeDashArray="{StaticResource dashArray}"/>
</chart:SfCartesianChart>DoubleCollection dashArray = new DoubleCollection { 5, 3 };
StepLineSeries series = new StepLineSeries()
{
ItemsSource = new ViewModel().PriceData,
XBindingPath = "Date",
YBindingPath = "Price",
StrokeDashArray = dashArray
};Vertical Step Line
Render step line vertically using the IsTransposed property:
<chart:SfCartesianChart IsTransposed="True">
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:StepLineSeries ItemsSource="{Binding PriceData}"
XBindingPath="Date"
YBindingPath="Price"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
chart.IsTransposed = true;
DateTimeAxis primaryAxis = new DateTimeAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
StepLineSeries series = new StepLineSeries()
{
ItemsSource = new ViewModel().PriceData,
XBindingPath = "Date",
YBindingPath = "Price"
};
chart.Series.Add(series);
this.Content = chart;Waterfall Chart
Waterfall charts visualize the cumulative effect of sequential positive and negative values, commonly used in financial analysis.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:WaterfallSeries ItemsSource="{Binding FinancialData}"
XBindingPath="Category"
YBindingPath="Value"
SummaryBindingPath="IsSummary"
AllowAutoSum="True"
ShowConnectorLine="True"
NegativePointsBrush="Red"
SummaryPointsBrush="RoyalBlue"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
CategoryAxis primaryAxis = new CategoryAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
WaterfallSeries series = new WaterfallSeries()
{
ItemsSource = new ViewModel().FinancialData,
XBindingPath = "Category",
YBindingPath = "Value",
SummaryBindingPath = "IsSummary",
AllowAutoSum = true,
ShowConnectorLine = true,
NegativePointsBrush = new SolidColorBrush(Colors.Red),
SummaryPointsBrush = new SolidColorBrush(Colors.RoyalBlue)
};
chart.Series.Add(series);
this.Content = chart;Data Model for Waterfall
public class FinancialModel
{
public string Category { get; set; }
public double Value { get; set; }
public bool IsSummary { get; set; }
}
public class ViewModel
{
public ObservableCollection<FinancialModel> FinancialData { get; set; }
public ViewModel()
{
FinancialData = new ObservableCollection<FinancialModel>
{
new FinancialModel { Category = "Sales", Value = 10000, IsSummary = false },
new FinancialModel { Category = "Marketing", Value = -2000, IsSummary = false },
new FinancialModel { Category = "Development", Value = -3000, IsSummary = false },
new FinancialModel { Category = "Operations", Value = -1500, IsSummary = false },
new FinancialModel { Category = "Q1 Total", Value = 3500, IsSummary = true },
new FinancialModel { Category = "Support", Value = -500, IsSummary = false },
new FinancialModel { Category = "Net Total", Value = 3000, IsSummary = true }
};
}
}Waterfall Properties
AllowAutoSum: Automatically calculates cumulative totals
<chart:WaterfallSeries ItemsSource="{Binding FinancialData}"
XBindingPath="Category"
YBindingPath="Value"
AllowAutoSum="True"
SummaryBindingPath="IsSummary"/>WaterfallSeries series = new WaterfallSeries()
{
ItemsSource = new ViewModel().FinancialData,
XBindingPath = "Category",
YBindingPath = "Value",
AllowAutoSum = true, // Enable automatic sum calculation
SummaryBindingPath = "IsSummary"
};ShowConnectorLine: Display/hide connector lines between segments
<chart:WaterfallSeries ItemsSource="{Binding FinancialData}"
XBindingPath="Category"
YBindingPath="Value"
ShowConnectorLine="True"/>WaterfallSeries series = new WaterfallSeries()
{
ItemsSource = new ViewModel().FinancialData,
XBindingPath = "Category",
YBindingPath = "Value",
ShowConnectorLine = true // Default is true
};Connector Line Customization
<chart:WaterfallSeries ItemsSource="{Binding FinancialData}"
XBindingPath="Category"
YBindingPath="Value">
<chart:WaterfallSeries.ConnectorLineStyle>
<chart:ChartLineStyle Stroke="DarkViolet"
StrokeWidth="2"/>
</chart:WaterfallSeries.ConnectorLineStyle>
</chart:WaterfallSeries>ChartLineStyle connectorStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.DarkViolet),
StrokeWidth = 2
};
WaterfallSeries series = new WaterfallSeries()
{
ItemsSource = new ViewModel().FinancialData,
XBindingPath = "Category",
YBindingPath = "Value",
ConnectorLineStyle = connectorStyle
};Complete Waterfall Example
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis>
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Amount ($)"/>
</chart:NumericalAxis.Title>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
<chart:WaterfallSeries ItemsSource="{Binding FinancialData}"
XBindingPath="Category"
YBindingPath="Value"
SummaryBindingPath="IsSummary"
AllowAutoSum="True"
ShowConnectorLine="True"
Fill="#4CAF50"
NegativePointsBrush="#F44336"
SummaryPointsBrush="#2196F3">
<chart:WaterfallSeries.ConnectorLineStyle>
<chart:ChartLineStyle Stroke="Gray" StrokeWidth="1"/>
</chart:WaterfallSeries.ConnectorLineStyle>
</chart:WaterfallSeries>
</chart:SfCartesianChart>Best Practices
Fast Line Chart
When to Use:
- Datasets with 1,000+ data points
- Real-time data visualization
- Performance-critical scenarios
- Time-series data
Optimization Tips: 1. Disable animations for large datasets 2. Use DateTimeAxis for time-based data 3. Enable anti-aliasing only when necessary 4. Limit simultaneous series to 2-3 5. Consider data sampling for extremely large datasets (>100k points)
Step Area Chart
When to Use:
- Discrete value changes
- Production/inventory levels
- State transitions
- When exact change points matter
Guidelines: 1. Ideal for 10-50 data points 2. Use with CategoryAxis or DateTimeAxis 3. Markers help identify exact change points 4. Combine with tooltips for value details
Step Line Chart
When to Use:
- Price changes
- Status transitions
- Multi-level comparisons
- Discrete value tracking
Guidelines: 1. Limit to 3-5 series for clarity 2. Use contrasting colors 3. Dashed lines help distinguish series 4. Consider vertical orientation for readability
Waterfall Chart
When to Use:
- Financial statements
- Variance analysis
- Sequential impact visualization
- Profit and loss analysis
Guidelines: 1. Clearly mark summary points 2. Use distinct colors for positive/negative/summary 3. Limit categories to <15 for readability 4. Ensure connector lines are visible 5. Add data labels for exact values
Common Gotchas
Fast Line:
- Markers not supported (performance trade-off)
- No data label support
- Animation may cause lag with large data
Step Charts:
- Data points must be ordered by X-value
- Sharp transitions may appear abrupt
- Not suitable for smooth trend analysis
Waterfall:
- Summary points must be marked in data model
- Negative values appear below baseline
- Connector line visibility depends on column height
- AutoSum calculation requires proper IsSummary flags
Performance Comparison
| Chart Type | Optimal Data Points | Update Speed | Memory Usage |
|---|---|---|---|
| Fast Line | 1,000 - 100,000 | Excellent | Low |
| Step Area | 10 - 100 | Good | Medium |
| Step Line | 10 - 200 | Good | Low |
| Waterfall | 5 - 30 | Good | Medium |
Troubleshooting
Issue: Fast line chart appears pixelated
- Solution: Enable
EnableAntiAliasing="True"
Issue: Step chart transitions too abrupt
- Solution: Consider using spline charts for smoother transitions
Issue: Waterfall summary not calculating correctly
- Solution: Verify
IsSummarybinding path and ensure boolean values are correct
Issue: Connector lines not visible in waterfall
- Solution: Increase
StrokeWidthinConnectorLineStyle
Issue: Step line appears jagged
- Solution: Ensure data is sorted by X-value ascending
Annotations and PlotBands
Table of Contents
- Overview
- Annotations
- Adding Annotations
- Positioning Annotations
- Text Annotation
- Shape Annotations
- View Annotation
- Multiple Axes Support
- PlotBands
- Numerical PlotBand
- DateTime PlotBand
- Recursive PlotBand
- Segmented PlotBand
- Plot Lines
- Best Practices
- Troubleshooting
Overview
Annotations and PlotBands allow you to mark and highlight specific areas of interest in the chart. Annotations add text, shapes, or custom views to specific points, while PlotBands shade regions in the background at regular or custom intervals.
Annotation Types:
- Text annotations
- Shape annotations (Rectangle, Ellipse, Line, Vertical Line, Horizontal Line)
- View annotations (custom views)
PlotBand Types:
- Numerical PlotBands
- DateTime PlotBands
Annotations
Adding Annotations
Add annotations to the chart's Annotations collection:
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:SfCartesianChart.Annotations>
<chart:EllipseAnnotation X1="2" X2="4" Y1="10" Y2="15"
Text="Ellipse"
Fill="#4CAF50"
Stroke="Green"
StrokeWidth="2"/>
</chart:SfCartesianChart.Annotations>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
var ellipse = new EllipseAnnotation()
{
X1 = 2,
Y1 = 10,
X2 = 4,
Y2 = 15,
Text = "Ellipse",
Fill = new SolidColorBrush(Color.FromArgb("#4CAF50")),
Stroke = new SolidColorBrush(Colors.Green),
StrokeWidth = 2
};
chart.Annotations.Add(ellipse);Positioning Annotations
Coordinate Units:
Axis(default): Position based on axis valuesPixel: Position based on pixel coordinates
<chart:RectangleAnnotation X1="0" Y1="100" X2="300" Y2="400"
CoordinateUnit="Pixel"
Text="Pixel Position"/>var rectangle = new RectangleAnnotation()
{
X1 = 0,
Y1 = 100,
X2 = 300,
Y2 = 400,
CoordinateUnit = ChartCoordinateUnit.Pixel,
Text = "Pixel Position"
};Text Annotation
Add simple text at specific points:
<chart:SfCartesianChart>
<chart:SfCartesianChart.Annotations>
<chart:TextAnnotation X1="2" Y1="25"
Text="Important Point">
<chart:TextAnnotation.LabelStyle>
<chart:ChartAnnotationLabelStyle TextColor="Blue"
FontSize="16"
FontAttributes="Bold"
Background="LightYellow"/>
</chart:TextAnnotation.LabelStyle>
</chart:TextAnnotation>
</chart:SfCartesianChart.Annotations>
</chart:SfCartesianChart>var textAnnotation = new TextAnnotation()
{
X1 = 2,
Y1 = 25,
Text = "Important Point",
LabelStyle = new ChartAnnotationLabelStyle()
{
TextColor = Colors.Blue,
FontSize = 16,
FontAttributes = FontAttributes.Bold,
Background = new SolidColorBrush(Colors.LightYellow)
}
};Shape Annotations
Rectangle Annotation
<chart:RectangleAnnotation X1="1" Y1="40" X2="2" Y2="20"
Fill="#20FF5722"
Stroke="#FF5722"
StrokeWidth="2"
Text="Target Range"/>var rectangle = new RectangleAnnotation()
{
X1 = 1,
Y1 = 40,
X2 = 2,
Y2 = 20,
Fill = new SolidColorBrush(Color.FromArgb("#20FF5722")),
Stroke = new SolidColorBrush(Color.FromArgb("#FF5722")),
StrokeWidth = 2,
Text = "Target Range"
};Ellipse Annotation
<chart:EllipseAnnotation X1="2" X2="4" Y1="10" Y2="15"
Width="20" Height="20"
Fill="#204CAF50"
Stroke="Green"
StrokeWidth="2"
Text="Focus Area"/>var ellipse = new EllipseAnnotation()
{
X1 = 2,
Y1 = 10,
X2 = 4,
Y2 = 15,
Width = 20,
Height = 20,
Fill = new SolidColorBrush(Color.FromArgb("#204CAF50")),
Stroke = new SolidColorBrush(Colors.Green),
StrokeWidth = 2,
Text = "Focus Area"
};Line Annotation
<chart:LineAnnotation X1="0.5" Y1="10" X2="3.5" Y2="20"
Stroke="Red"
StrokeWidth="2"
StrokeDashArray="5,5"
Text="Trend Line"/>var line = new LineAnnotation()
{
X1 = 0.5,
Y1 = 10,
X2 = 3.5,
Y2 = 20,
Stroke = new SolidColorBrush(Colors.Red),
StrokeWidth = 2,
Text = "Trend Line"
};
line.StrokeDashArray = new DoubleCollection { 5, 5 };Vertical and Horizontal Line Annotations
<chart:SfCartesianChart.Annotations>
<chart:VerticalLineAnnotation X1="2.5"
Stroke="Blue"
StrokeWidth="2"
ShowAxisLabel="True"
LineCap="Arrow">
<chart:VerticalLineAnnotation.AxisLabelStyle>
<chart:ChartLabelStyle TextColor="Blue"
FontSize="12"
Background="LightBlue"/>
</chart:VerticalLineAnnotation.AxisLabelStyle>
</chart:VerticalLineAnnotation>
<chart:HorizontalLineAnnotation Y1="25"
Stroke="Red"
StrokeWidth="2"
ShowAxisLabel="True"
LineCap="Arrow"/>
</chart:SfCartesianChart.Annotations>var verticalLine = new VerticalLineAnnotation()
{
X1 = 2.5,
Stroke = new SolidColorBrush(Colors.Blue),
StrokeWidth = 2,
ShowAxisLabel = true,
LineCap = ChartLineCap.Arrow,
AxisLabelStyle = new ChartLabelStyle()
{
TextColor = Colors.Blue,
FontSize = 12,
Background = new SolidColorBrush(Colors.LightBlue)
}
};
var horizontalLine = new HorizontalLineAnnotation()
{
Y1 = 25,
Stroke = new SolidColorBrush(Colors.Red),
StrokeWidth = 2,
ShowAxisLabel = true,
LineCap = ChartLineCap.Arrow
};View Annotation
Add custom views as annotations:
<chart:SfCartesianChart>
<chart:SfCartesianChart.Annotations>
<chart:ViewAnnotation X1="3" Y1="30"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<chart:ViewAnnotation.View>
<Border BackgroundColor="White"
Stroke="Orange"
StrokeThickness="2"
Padding="10">
<VerticalStackLayout>
<Image Source="warning.png"
WidthRequest="24"
HeightRequest="24"/>
<Label Text="Warning!"
TextColor="Orange"
FontSize="12"
FontAttributes="Bold"/>
</VerticalStackLayout>
</Border>
</chart:ViewAnnotation.View>
</chart:ViewAnnotation>
</chart:SfCartesianChart.Annotations>
</chart:SfCartesianChart>var viewAnnotation = new ViewAnnotation()
{
X1 = 3,
Y1 = 30,
VerticalAlignment = ChartAlignment.Center,
HorizontalAlignment = ChartAlignment.Center,
View = new Border()
{
BackgroundColor = Colors.White,
Stroke = new SolidColorBrush(Colors.Orange),
StrokeThickness = 2,
Padding = 10,
Content = new VerticalStackLayout()
{
Children =
{
new Image() { Source = "warning.png", WidthRequest = 24, HeightRequest = 24 },
new Label() { Text = "Warning!", TextColor = Colors.Orange, FontSize = 12, FontAttributes = FontAttributes.Bold }
}
}
}
};Multiple Axes Support
Specify which axis to use for positioning:
<chart:SfCartesianChart>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
<chart:NumericalAxis Name="SecondaryAxis"
CrossesAt="{Static x:Double.MaxValue}"/>
</chart:SfCartesianChart.YAxes>
<chart:SfCartesianChart.Annotations>
<chart:EllipseAnnotation X1="2" X2="4" Y1="10" Y2="15"
YAxisName="SecondaryAxis"
Text="On Secondary Axis"/>
</chart:SfCartesianChart.Annotations>
</chart:SfCartesianChart>PlotBands
PlotBands shade specific regions in the plot area background.
Numerical PlotBand
For NumericalAxis, CategoryAxis, and DateTimeCategoryAxis:
<chart:SfCartesianChart>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis>
<chart:NumericalAxis.PlotBands>
<chart:NumericalPlotBandCollection>
<chart:NumericalPlotBand Start="24" End="28"
Fill="#20FFA500"
Stroke="Orange"
StrokeWidth="1"
Text="Target Range">
<chart:NumericalPlotBand.LabelStyle>
<chart:ChartPlotBandLabelStyle TextColor="Orange"
FontSize="12"/>
</chart:NumericalPlotBand.LabelStyle>
</chart:NumericalPlotBand>
</chart:NumericalPlotBandCollection>
</chart:NumericalAxis.PlotBands>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
</chart:SfCartesianChart>NumericalAxis numericalAxis = new NumericalAxis();
NumericalPlotBandCollection plotBands = new NumericalPlotBandCollection();
NumericalPlotBand plotBand = new NumericalPlotBand
{
Start = 24,
End = 28,
Fill = new SolidColorBrush(Color.FromArgb("#20FFA500")),
Stroke = new SolidColorBrush(Colors.Orange),
StrokeWidth = 1,
Text = "Target Range",
LabelStyle = new ChartPlotBandLabelStyle()
{
TextColor = Colors.Orange,
FontSize = 12
}
};
plotBands.Add(plotBand);
numericalAxis.PlotBands = plotBands;DateTime PlotBand
For DateTimeAxis:
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis>
<chart:DateTimeAxis.PlotBands>
<chart:DateTimePlotBandCollection>
<chart:DateTimePlotBand Start="2023-04-01"
End="2023-06-01"
Fill="#20FF5722"
Text="Q2 2023"/>
</chart:DateTimePlotBandCollection>
</chart:DateTimeAxis.PlotBands>
</chart:DateTimeAxis>
</chart:SfCartesianChart.XAxes>
</chart:SfCartesianChart>DateTimeAxis dateTimeAxis = new DateTimeAxis();
DateTimePlotBandCollection plotBands = new DateTimePlotBandCollection();
DateTimePlotBand plotBand = new DateTimePlotBand
{
Start = new DateTime(2023, 04, 01),
End = new DateTime(2023, 06, 01),
Fill = new SolidColorBrush(Color.FromArgb("#20FF5722")),
Text = "Q2 2023"
};
plotBands.Add(plotBand);
dateTimeAxis.PlotBands = plotBands;Recursive PlotBand
Draw plot bands at regular intervals:
<chart:NumericalAxis>
<chart:NumericalAxis.PlotBands>
<chart:NumericalPlotBandCollection>
<chart:NumericalPlotBand Start="20" End="22"
IsRepeatable="True"
RepeatEvery="4"
RepeatUntil="32"
Fill="LightGray"/>
</chart:NumericalPlotBandCollection>
</chart:NumericalAxis.PlotBands>
</chart:NumericalAxis>NumericalPlotBand plotBand = new NumericalPlotBand
{
Start = 20,
End = 22,
IsRepeatable = true,
RepeatEvery = 4,
RepeatUntil = 32,
Fill = new SolidColorBrush(Colors.LightGray)
};Segmented PlotBand
Limit plot band to specific associated axis range:
<chart:NumericalAxis>
<chart:NumericalAxis.PlotBands>
<chart:NumericalPlotBandCollection>
<chart:NumericalPlotBand Start="20" End="22"
AssociatedAxisStart="0"
AssociatedAxisEnd="2"
Fill="#B300E190"
Text="Low"/>
<chart:NumericalPlotBand Start="25" End="27"
AssociatedAxisStart="4.3"
AssociatedAxisEnd="6.8"
Fill="#B3FCD404"
Text="Average"/>
</chart:NumericalPlotBandCollection>
</chart:NumericalAxis.PlotBands>
</chart:NumericalAxis>Plot Lines
Create plot lines by setting Start = End:
<chart:NumericalPlotBand Start="24" End="24"
Stroke="Red"
StrokeWidth="2"
Text="Threshold"/>Best Practices
Annotation Usage
1. Clear Purpose: Use annotations to highlight important data 2. Avoid Clutter: Don't overuse annotations 3. Consistent Styling: Maintain visual consistency 4. Meaningful Text: Provide descriptive annotation text 5. Coordinate Units: Choose appropriate coordinate units for positioning
PlotBand Guidelines
1. Transparency: Use semi-transparent fills for better readability 2. Meaningful Ranges: Highlight significant data ranges 3. Text Labels: Add descriptive text to explain plot bands 4. Color Contrast: Ensure plot bands are visible against background 5. Recursive Bands: Use for periodic patterns in data
Common Patterns
Threshold Marking:
<chart:HorizontalLineAnnotation Y1="100"
Stroke="Red"
StrokeWidth="2"
ShowAxisLabel="True"
Text="Maximum Threshold"/>Region Highlighting:
<chart:NumericalPlotBand Start="80" End="100"
Fill="#2000E190"
Text="Optimal Range"/>Troubleshooting
Issue: Annotation not visible
- Solution: Check X1, Y1 coordinates are within axis range
- Solution: Verify
IsVisibleproperty is true - Solution: Ensure annotation is added to Annotations collection
Issue: PlotBand not showing
- Solution: Verify Start/End values are within axis range
- Solution: Check Fill has opacity (alpha channel)
- Solution: Ensure PlotBands added to correct axis
Issue: Annotation positioned incorrectly
- Solution: Verify
CoordinateUnitsetting (Axis vs Pixel) - Solution: Check axis names for multi-axis charts
- Solution: Ensure axis visible range includes annotation coordinates
Issue: Text not readable in annotation
- Solution: Adjust LabelStyle TextColor for contrast
- Solution: Add Background color to label
- Solution: Increase FontSize for visibility
Issue: PlotBand text cut off
- Solution: Use shorter text or adjust LabelStyle properties
- Solution: Consider using OffsetX/OffsetY for positioning
- Solution: Adjust HorizontalTextAlignment and VerticalTextAlignment
Axis Configuration
Table of Contents
- Overview
- Axis Types
- Numerical Axis
- Category Axis
- DateTime Axis
- DateTimeCategory Axis
- Logarithmic Axis
- Axis Labels
- Axis Title
- Custom Labels
- Best Practices
Overview
Chart axes are fundamental components that define the coordinate system for plotting data. Cartesian charts typically use two axes: a horizontal (X) axis and a vertical (Y) axis to measure and categorize data points.
Key Features:
- Multiple axis types (Numerical, Category, DateTime, Logarithmic)
- Customizable intervals, ranges, and labels
- Support for multiple axes in a single chart
- Extensive styling and formatting options
Axis Types
Syncfusion .NET MAUI Cartesian Chart supports five axis types:
1. NumericalAxis: Plots numerical values with linear scale 2. CategoryAxis: Plots categorical data using index-based positioning 3. DateTimeAxis: Plots datetime values with timeline scale 4. DateTimeCategoryAxis: Combines datetime and category features 5. LogarithmicAxis: Plots values on logarithmic scale
Numerical Axis
NumericalAxis displays numerical values with linear intervals, suitable for continuous data.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
NumericalAxis primaryAxis = new NumericalAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue"
};
chart.Series.Add(series);
this.Content = chart;Interval Customization
<chart:NumericalAxis Interval="10"
Minimum="0"
Maximum="100"/>NumericalAxis axis = new NumericalAxis()
{
Interval = 10,
Minimum = 0,
Maximum = 100
};Range Configuration
<chart:NumericalAxis Maximum="2750"
Minimum="250"
Interval="250"/>NumericalAxis axis = new NumericalAxis()
{
Maximum = 2750,
Minimum = 250,
Interval = 250
};Category Axis
CategoryAxis is index-based, plotting values based on the data point collection index with equal spacing.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
CategoryAxis primaryAxis = new CategoryAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
ColumnSeries series = new ColumnSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Category",
YBindingPath = "Value"
};
chart.Series.Add(series);
this.Content = chart;Label Placement
<chart:CategoryAxis LabelPlacement="BetweenTicks"/>CategoryAxis axis = new CategoryAxis()
{
LabelPlacement = LabelPlacement.BetweenTicks
};Options:
OnTicks: Labels appear on tick marks (default)BetweenTicks: Labels appear between tick marks
DateTime Axis
DateTimeAxis plots datetime values along a timeline with appropriate intervals.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding TimeSeriesData}"
XBindingPath="Date"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
DateTimeAxis primaryAxis = new DateTimeAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().TimeSeriesData,
XBindingPath = "Date",
YBindingPath = "Value"
};
chart.Series.Add(series);
this.Content = chart;Interval Types
<chart:DateTimeAxis IntervalType="Months"
Interval="1"/>DateTimeAxis axis = new DateTimeAxis()
{
IntervalType = DateTimeIntervalType.Months,
Interval = 1
};IntervalType Options:
Auto: Automatically determines intervalYears: Yearly intervalsMonths: Monthly intervalsDays: Daily intervalsHours: Hourly intervalsMinutes: Minute intervalsSeconds: Second intervalsMilliseconds: Millisecond intervals
Date Format
<chart:DateTimeAxis LabelFormat="MMM-yyyy"/>DateTimeAxis axis = new DateTimeAxis()
{
LabelFormat = "MMM-yyyy" // e.g., "Jan-2024"
};Range Configuration
<chart:DateTimeAxis Minimum="2024-01-01"
Maximum="2024-12-31"
IntervalType="Months"
Interval="1"/>DateTimeAxis axis = new DateTimeAxis()
{
Minimum = new DateTime(2024, 1, 1),
Maximum = new DateTime(2024, 12, 31),
IntervalType = DateTimeIntervalType.Months,
Interval = 1
};DateTimeCategory Axis
DateTimeCategoryAxis combines features of both DateTime and Category axes, ideal for datetime data with irregular intervals.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeCategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding IrregularData}"
XBindingPath="Date"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
DateTimeCategoryAxis primaryAxis = new DateTimeCategoryAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().IrregularData,
XBindingPath = "Date",
YBindingPath = "Value"
};
chart.Series.Add(series);
this.Content = chart;Label Format
<chart:DateTimeCategoryAxis LabelFormat="dd-MMM"
Interval="1"/>DateTimeCategoryAxis axis = new DateTimeCategoryAxis()
{
LabelFormat = "dd-MMM",
Interval = 1
};Logarithmic Axis
LogarithmicAxis uses logarithmic scale, useful for data with wide value ranges.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:LogarithmicAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding ExponentialData}"
XBindingPath="X"
YBindingPath="Y"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
NumericalAxis primaryAxis = new NumericalAxis();
chart.XAxes.Add(primaryAxis);
LogarithmicAxis secondaryAxis = new LogarithmicAxis();
chart.YAxes.Add(secondaryAxis);
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().ExponentialData,
XBindingPath = "X",
YBindingPath = "Y"
};
chart.Series.Add(series);
this.Content = chart;Logarithmic Base
<chart:LogarithmicAxis LogarithmicBase="10"/>LogarithmicAxis axis = new LogarithmicAxis()
{
LogarithmicBase = 10 // Default is 10
};Axis Labels
Label Style
<chart:NumericalAxis>
<chart:NumericalAxis.LabelStyle>
<chart:ChartAxisLabelStyle TextColor="Blue"
FontSize="14"
FontAttributes="Bold"
Margin="5"/>
</chart:NumericalAxis.LabelStyle>
</chart:NumericalAxis>ChartAxisLabelStyle labelStyle = new ChartAxisLabelStyle()
{
TextColor = Colors.Blue,
FontSize = 14,
FontAttributes = FontAttributes.Bold,
Margin = new Thickness(5)
};
NumericalAxis axis = new NumericalAxis()
{
LabelStyle = labelStyle
};Label Format
Format axis labels using standard format strings:
<chart:NumericalAxis>
<chart:NumericalAxis.LabelStyle>
<chart:ChartAxisLabelStyle LabelFormat="N2"/>
</chart:NumericalAxis.LabelStyle>
</chart:NumericalAxis>
<chart:NumericalAxis />ChartAxisLabelStyle labelStyle = new ChartAxisLabelStyle()
{
LabelFormat = "N2" // Two decimal places
};
NumericalAxis axis = new NumericalAxis()
{
LabelStyle = labelStyle
};Common Formats:
N0: Number with no decimalsN2: Number with 2 decimalsC: CurrencyP: Percentagedd-MMM-yyyy: Date format
Label Rotation
<chart:CategoryAxis LabelRotation="45"/>CategoryAxis axis = new CategoryAxis()
{
LabelRotation = 45
};Edge Labels Visibility
<chart:NumericalAxis EdgeLabelsDrawingMode="Shift"/>NumericalAxis axis = new NumericalAxis()
{
EdgeLabelsDrawingMode = EdgeLabelsDrawingMode.Shift
};Options:
Center: Center edge labelsShift: Shift edge labels insideHide: Hide edge labels
Axis Title
Basic Title
<chart:NumericalAxis>
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Sales (in thousands)"/>
</chart:NumericalAxis.Title>
</chart:NumericalAxis>ChartAxisTitle title = new ChartAxisTitle()
{
Text = "Sales (in thousands)"
};
NumericalAxis axis = new NumericalAxis()
{
Title = title
};Title Customization
<chart:NumericalAxis>
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Revenue"
TextColor="Red"
FontSize="16"
FontAttributes="Bold"
Margin="10"/>
</chart:NumericalAxis.Title>
</chart:NumericalAxis>ChartAxisTitle title = new ChartAxisTitle()
{
Text = "Revenue",
TextColor = Colors.Red,
FontSize = 16,
FontAttributes = FontAttributes.Bold,
Margin = new Thickness(10)
};
NumericalAxis axis = new NumericalAxis()
{
Title = title
};Custom Labels
Add custom text labels to chart axes for better context.
Adding Custom Labels to Axis
// In code-behind or ViewModel
CategoryAxis xAxis = new CategoryAxis();
// Add custom labels
xAxis.LabelCreated += (sender, e) =>
{
// Customize labels based on position
if (e.Position == 0)
e.LabelStyle = new ChartAxisLabelStyle { TextColor = Colors.Red };
else if (e.Position == 5)
e.LabelStyle = new ChartAxisLabelStyle { TextColor = Colors.Green };
};Custom Label Formatting
NumericalAxis yAxis = new NumericalAxis();
yAxis.LabelCreated += (sender, e) =>
{
// Format as currency
if (double.TryParse(e.Label, out double value))
{
e.Label = $"${value:N0}";
}
};
chart.YAxes.Add(yAxis);Category-Specific Styling
CategoryAxis xAxis = new CategoryAxis();
xAxis.LabelCreated += (sender, e) =>
{
// Highlight weekend labels
if (e.Label == "Saturday" || e.Label == "Sunday")
{
e.LabelStyle = new ChartAxisLabelStyle
{
TextColor = Colors.Blue,
FontAttributes = FontAttributes.Bold
};
}
};Best Practices
Axis Type Selection
Use NumericalAxis when:
- Data consists of continuous numeric values
- Need linear scale representation
- X and Y values are both numeric
Use CategoryAxis when:
- Data has distinct categories
- Equal spacing between points is desired
- Index-based positioning is preferred
Use DateTimeAxis when:
- Data has datetime values
- Timeline visualization is needed
- Automatic date interval calculation is required
Use DateTimeCategoryAxis when:
- Data has irregular datetime intervals
- Both datetime and categorical features needed
- Non-uniform time gaps exist
Use LogarithmicAxis when:
- Data spans multiple orders of magnitude
- Exponential growth patterns
- Scientific or statistical data
Common Guidelines
1. Interval Setting: Set appropriate intervals for readability 2. Range Definition: Define min/max when auto-range is insufficient 3. Label Format: Use consistent, readable formats 4. Title Clarity: Add descriptive axis titles 5. Multiple Axes: Use when comparing different scales
Performance Tips
1. Limit custom labels to necessary positions 2. Use appropriate interval to reduce label count 3. Avoid excessive label rotation 4. Consider label visibility with large datasets
Troubleshooting
Issue: Labels overlapping
- Solution: Increase interval, rotate labels, or reduce font size
Issue: Axis not showing all data
- Solution: Set explicit Minimum/Maximum values
Issue: DateTime labels showing incorrectly
- Solution: Verify LabelFormat and IntervalType settings
Issue: Logarithmic axis showing gaps
- Solution: Ensure all values are positive and non-zero
Axis Customization
Table of Contents
- Overview
- Grid Lines
- Tick Lines
- Axis Line
- Axis Padding
- Range Padding
- Auto Scrolling Delta
- Custom Axis Labels
- Best Practices
Overview
Axis customization in Syncfusion .NET MAUI Cartesian Chart allows you to style and configure various visual elements including grid lines, tick lines, axis lines, and spacing. These customizations enhance chart readability and visual appeal.
Grid Lines
Grid lines are horizontal and vertical lines that help identify data point values on the axis.
Basic Grid Line Configuration
<chart:NumericalAxis ShowMajorGridLines="True"
ShowMinorGridLines="True"/>NumericalAxis axis = new NumericalAxis()
{
ShowMajorGridLines = true,
ShowMinorGridLines = true
};Major Grid Line Styling
<chart:NumericalAxis ShowMajorGridLines="True">
<chart:NumericalAxis.MajorGridLineStyle>
<chart:ChartLineStyle Stroke="Gray"
StrokeWidth="1"
StrokeDashArray="5,3"/>
</chart:NumericalAxis.MajorGridLineStyle>
</chart:NumericalAxis>ChartLineStyle majorGridStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.Gray),
StrokeWidth = 1,
StrokeDashArray = new double[] { 5, 3 }
};
NumericalAxis axis = new NumericalAxis()
{
ShowMajorGridLines = true,
MajorGridLineStyle = majorGridStyle
};Minor Grid Line Styling
<chart:NumericalAxis ShowMinorGridLines="True"
MinorTicksPerInterval="4">
<chart:NumericalAxis.MinorGridLineStyle>
<chart:ChartLineStyle Stroke="LightGray"
StrokeWidth="0.5"
StrokeDashArray="2,2"/>
</chart:NumericalAxis.MinorGridLineStyle>
</chart:NumericalAxis>ChartLineStyle minorGridStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.LightGray),
StrokeWidth = 0.5,
StrokeDashArray = new double[] { 2, 2 }
};
NumericalAxis axis = new NumericalAxis()
{
ShowMinorGridLines = true,
MinorTicksPerInterval = 4,
MinorGridLineStyle = minorGridStyle
};Complete Grid Line Example
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis ShowMajorGridLines="True">
<chart:CategoryAxis.MajorGridLineStyle>
<chart:ChartLineStyle Stroke="#E0E0E0" StrokeWidth="1"/>
</chart:CategoryAxis.MajorGridLineStyle>
</chart:CategoryAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis ShowMajorGridLines="True"
ShowMinorGridLines="True"
MinorTicksPerInterval="4">
<chart:NumericalAxis.MajorGridLineStyle>
<chart:ChartLineStyle Stroke="Gray" StrokeWidth="1"/>
</chart:NumericalAxis.MajorGridLineStyle>
<chart:NumericalAxis.MinorGridLineStyle>
<chart:ChartLineStyle Stroke="LightGray"
StrokeWidth="0.5"
StrokeDashArray="2,2"/>
</chart:NumericalAxis.MinorGridLineStyle>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
</chart:SfCartesianChart>Tick Lines
Tick lines are small lines on the axis that indicate data point values.
Major Tick Lines
<chart:NumericalAxis ShowMajorTickLines="True"
MajorTickLineSize="8"/>NumericalAxis axis = new NumericalAxis()
{
ShowMajorTickLines = true,
MajorTickLineSize = 8
};Major Tick Line Styling
<chart:NumericalAxis ShowMajorTickLines="True"
MajorTickLineSize="8">
<chart:NumericalAxis.MajorTickLineStyle>
<chart:ChartLineStyle Stroke="Black" StrokeWidth="2"/>
</chart:NumericalAxis.MajorTickLineStyle>
</chart:NumericalAxis>ChartLineStyle tickStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.Black),
StrokeWidth = 2
};
NumericalAxis axis = new NumericalAxis()
{
ShowMajorTickLines = true,
MajorTickLineSize = 8,
MajorTickLineStyle = tickStyle
};Minor Tick Lines
<chart:NumericalAxis ShowMinorTickLines="True"
MinorTicksPerInterval="4"
MinorTickLineSize="4">
<chart:NumericalAxis.MinorTickLineStyle>
<chart:ChartLineStyle Stroke="Gray" StrokeWidth="1"/>
</chart:NumericalAxis.MinorTickLineStyle>
</chart:NumericalAxis>ChartLineStyle minorTickStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.Gray),
StrokeWidth = 1
};
NumericalAxis axis = new NumericalAxis()
{
ShowMinorTickLines = true,
MinorTicksPerInterval = 4,
MinorTickLineSize = 4,
MinorTickLineStyle = minorTickStyle
};Axis Line
The axis line is the main line of the axis.
Basic Axis Line
<chart:NumericalAxis ShowAxisLine="True"/>NumericalAxis axis = new NumericalAxis()
{
ShowAxisLine = true
};Axis Line Styling
<chart:NumericalAxis ShowAxisLine="True">
<chart:NumericalAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="Blue"
StrokeWidth="2"/>
</chart:NumericalAxis.AxisLineStyle>
</chart:NumericalAxis>ChartLineStyle axisLineStyle = new ChartLineStyle()
{
Stroke = new SolidColorBrush(Colors.Blue),
StrokeWidth = 2
};
NumericalAxis axis = new NumericalAxis()
{
ShowAxisLine = true,
AxisLineStyle = axisLineStyle
};Complete Axis Line Example
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis ShowAxisLine="True">
<chart:CategoryAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="#333333" StrokeWidth="2"/>
</chart:CategoryAxis.AxisLineStyle>
</chart:CategoryAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis ShowAxisLine="True">
<chart:NumericalAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="#333333" StrokeWidth="2"/>
</chart:NumericalAxis.AxisLineStyle>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
</chart:SfCartesianChart>Axis Padding
PlotOffset adds padding between the axis and the series.
Plot Offset Start
<chart:NumericalAxis PlotOffsetStart="20"/>NumericalAxis axis = new NumericalAxis()
{
PlotOffsetStart = 20
};Plot Offset End
<chart:NumericalAxis PlotOffsetEnd="20"/>NumericalAxis axis = new NumericalAxis()
{
PlotOffsetEnd = 20
};Combined Plot Offsets
<chart:CategoryAxis PlotOffsetStart="30"
PlotOffsetEnd="30"/>CategoryAxis axis = new CategoryAxis()
{
PlotOffsetStart = 30,
PlotOffsetEnd = 30
};Range Padding
RangePadding adds space at the edges of the axis range.
Numerical Axis Range Padding
<chart:NumericalAxis RangePadding="Auto"/>NumericalAxis axis = new NumericalAxis()
{
RangePadding = NumericalPadding.Auto
};Options:
None: No paddingNormal: Default paddingAdditional: Extra paddingRound: Round to nearest intervalAuto: Automatically determinedRoundStart: Round at start onlyRoundEnd: Round at end onlyPrependInterval: Add interval at startAppendInterval: Add interval at end
Category Axis Range Padding
<chart:CategoryAxis RangePadding="Auto"/>CategoryAxis axis = new CategoryAxis()
{
RangePadding = CategoryPadding.Auto
};Options:
None: No paddingAdditional: Extra paddingNormal: Default paddingRoundStart: Round at startRoundEnd: Round at endAuto: Automatically determined
DateTime Axis Range Padding
<chart:DateTimeAxis RangePadding="Auto"/>DateTimeAxis axis = new DateTimeAxis()
{
RangePadding = DateTimeRangePadding.Auto
};Options:
None: No paddingAdditional: Extra paddingRound: Round to intervalRoundStart: Round at startRoundEnd: Round at endAuto: Automatically determined
Range Padding Examples
No Padding:
<chart:NumericalAxis Minimum="0"
Maximum="100"
RangePadding="None"/>Normal Padding:
<chart:NumericalAxis Minimum="0"
Maximum="100"
RangePadding="Normal"/>Additional Padding:
<chart:NumericalAxis Minimum="0"
Maximum="100"
RangePadding="Additional"/>Auto Scrolling Delta
AutoScrollingDelta enables automatic scrolling with a visible range window.
Basic Auto Scrolling
<chart:DateTimeAxis AutoScrollingDelta="7"
AutoScrollingDeltaType="Days"
AutoScrollingMode="End"/>DateTimeAxis axis = new DateTimeAxis()
{
AutoScrollingDelta = 7,
AutoScrollingDeltaType = DateTimeIntervalType.Days,
AutoScrollingMode = ChartAutoScrollingMode.End
};Scrolling Modes
End (Default): Shows the most recent data:
<chart:DateTimeAxis AutoScrollingDelta="10"
AutoScrollingDeltaType="Days"
AutoScrollingMode="End"/>Start: Shows from the beginning:
<chart:DateTimeAxis AutoScrollingDelta="10"
AutoScrollingDeltaType="Days"
AutoScrollingMode="Start"/>Numerical Axis Auto Scrolling
<chart:NumericalAxis AutoScrollingDelta="50"
AutoScrollingMode="End"/>NumericalAxis axis = new NumericalAxis()
{
AutoScrollingDelta = 50,
AutoScrollingMode = ChartAutoScrollingMode.End
};Complete Auto Scrolling Example
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis AutoScrollingDelta="30"
AutoScrollingDeltaType="Days"
AutoScrollingMode="End"
IntervalType="Days"
Interval="5"/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding TimeSeriesData}"
XBindingPath="Date"
YBindingPath="Value"/>
</chart:SfCartesianChart>Custom Axis Labels
ChartAxis provides the OnCreateLabels override method to add custom axis labels. The OnCreateLabels method is called whenever new labels are generated. The following properties are available to add custom labels:
VisibleLabels- This property is used to get an Observable Collection of visible axis labels.VisibleMaximum- This property is used to get the double value that represents the maximum observable value of the axis range.VisibleMinimum- This property is used to get the double value that represents the minimum observable value of the axis range.
Example: Custom Numerical Axis
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<local:CustomNumericalAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
CustomNumericalAxis primaryAxis = new CustomNumericalAxis();
chart.XAxes.Add(primaryAxis);
NumericalAxis secondaryAxis = new NumericalAxis();
chart.YAxes.Add(secondaryAxis);
ColumnSeries series = new ColumnSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue"
};
chart.Series.Add(series);
this.Content = chart;Custom Axis Implementation
public class CustomNumericalAxis : NumericalAxis
{
// Adding custom axis labels by displaying labels only on specific x-axis values
protected override void OnCreateLabels()
{
base.OnCreateLabels();
if (VisibleLabels != null)
{
VisibleLabels.Clear();
ViewModel viewModel = BindingContext as ViewModel;
for (int i = 0; i < viewModel.Data.Count; i++)
{
var data = viewModel.Data[i];
VisibleLabels.Add(new ChartAxisLabel(data.XValue, data.XValue.ToString()));
}
}
}
}Note:
- This approach applies to all types of axes.
- Labels are rendered only if the label position presents within the visible range.
- The labels should be created only if users call the base of
OnCreateLabels.
Best Practices
Grid Lines
1. Major Grid Lines: Use for primary value divisions 2. Minor Grid Lines: Use sparingly; too many can clutter 3. Color Selection: Use subtle colors (light gray) for grids 4. Dashed Lines: Consider dashed lines for better distinction
Tick Lines
1. Visibility: Show major tick lines for clarity 2. Size: Keep tick lines proportional to axis (6-10 pixels) 3. Minor Ticks: Use 3-5 minor ticks per interval 4. Color: Match or complement axis line color
Axis Line
1. Always Visible: Axis lines should typically be visible 2. Weight: Use slightly thicker lines (2px) than grid lines 3. Color: Use darker colors for better definition
Padding and Spacing
1. PlotOffset: Use 10-30 pixels for breathing room 2. RangePadding: Use Auto or Normal for most cases 3. Additional Padding: Use when data points touch edges 4. Round Padding: Good for clean, rounded values
Auto Scrolling
1. Real-time Data: Ideal for live data streams 2. Delta Size: Choose delta based on update frequency 3. Mode Selection: Use End for recent data focus 4. Performance: Limit visible range for better performance
Common Combinations
Clean Professional Look:
<chart:NumericalAxis ShowMajorGridLines="True"
ShowAxisLine="True"
ShowMajorTickLines="True"
PlotOffsetStart="20"
PlotOffsetEnd="20"
RangePadding="Normal">
<chart:NumericalAxis.MajorGridLineStyle>
<chart:ChartLineStyle Stroke="#E0E0E0" StrokeWidth="1"/>
</chart:NumericalAxis.MajorGridLineStyle>
<chart:NumericalAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="#333333" StrokeWidth="2"/>
</chart:NumericalAxis.AxisLineStyle>
</chart:NumericalAxis>Minimal Clean Look:
<chart:NumericalAxis ShowMajorGridLines="False"
ShowAxisLine="True"
ShowMajorTickLines="False"
RangePadding="Additional">
<chart:NumericalAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="Black" StrokeWidth="1"/>
</chart:NumericalAxis.AxisLineStyle>
</chart:NumericalAxis>Troubleshooting
Issue: Grid lines too prominent
- Solution: Use lighter colors or dashed lines
Issue: Tick lines not visible
- Solution: Increase
MajorTickLineSizeor StrokeWidth
Issue: Data points cut off at edges
- Solution: Add PlotOffset or use RangePadding="Additional"
Issue: Auto scrolling not working
- Solution: Verify AutoScrollingDelta and Mode are set correctly
Issue: Too much whitespace around data
- Solution: Set RangePadding="None" or use explicit Minimum/Maximum values
Basic Chart Types
Table of Contents
- Overview
- Line Chart
- Spline Chart
- Area Chart
- Spline Area Chart
- Column Chart
- Bar Chart
- Scatter Chart
- Bubble Chart
- When to Use Each Type
Overview
Syncfusion .NET MAUI Cartesian Chart provides fundamental chart types for common data visualization scenarios. These basic chart types form the foundation of most data visualization needs, from trend analysis to comparisons and distributions.
Line Chart
Line charts connect data points with straight lines, ideal for showing trends over time or continuous data.
Basic Implementation
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"/>
</chart:SfCartesianChart>LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Month",
YBindingPath = "Sales"
};
chart.Series.Add(series);Dashed Line
Create dashed lines using the StrokeDashArray property:
<chart:SfCartesianChart>
<chart:SfCartesianChart.Resources>
<DoubleCollection x:Key="dashArray">
<x:Double>5</x:Double>
<x:Double>2</x:Double>
</DoubleCollection>
</chart:SfCartesianChart.Resources>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"
StrokeDashArray="{StaticResource dashArray}"/>
</chart:SfCartesianChart>DoubleCollection dashArray = new DoubleCollection { 5, 2 };
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Month",
YBindingPath = "Sales",
StrokeDashArray = dashArray
};Pattern: Odd values are dash length, even values are gap length (5 pixels dash, 2 pixels gap).
Line with Markers
Enable markers to highlight individual data points:
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"
ShowMarkers="True">
<chart:LineSeries.MarkerSettings>
<chart:ChartMarkerSettings Type="Diamond"
Fill="Red"
Stroke="Black"
StrokeWidth="1"
Height="10"
Width="10"/>
</chart:LineSeries.MarkerSettings>
</chart:LineSeries>LineSeries series = new LineSeries()
{
ItemsSource = data,
XBindingPath = "Month",
YBindingPath = "Sales",
ShowMarkers = true,
MarkerSettings = new ChartMarkerSettings
{
Type = ShapeType.Diamond,
Fill = Colors.Red,
Stroke = Colors.Black,
StrokeWidth = 1,
Height = 10,
Width = 10
}
};Marker Types: Circle, Cross, Diamond, Hexagon, InvertedTriangle, Pentagon, Plus, Square, Triangle
Spline Chart
Spline charts use smooth Bezier curves instead of straight lines, creating a more flowing visualization.
Basic Spline
<chart:SplineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"/>SplineSeries series = new SplineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Month",
YBindingPath = "Sales"
};Spline Types
The Type property controls the curve algorithm:
<chart:SplineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"
Type="Cardinal"/>Available Types:
- Natural (default): Natural cubic spline interpolation
- Monotonic: Preserves monotonicity of data (no overshooting)
- Cardinal: Cardinal spline with tension control
- Clamped: Clamped cubic spline with controlled endpoints
SplineSeries series = new SplineSeries()
{
ItemsSource = data,
XBindingPath = "Month",
YBindingPath = "Sales",
Type = SplineType.Cardinal
};Area Chart
Area charts fill the region between the line and the axis, emphasizing magnitude of change.
Basic Area
<chart:AreaSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"/>AreaSeries series = new AreaSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Month",
YBindingPath = "Sales"
};Area with Transparency
Use opacity to show overlapping areas:
<chart:AreaSeries ItemsSource="{Binding Data1}"
XBindingPath="Month"
YBindingPath="Sales"
Fill="#80FF0000"
Opacity="0.6"/>
<chart:AreaSeries ItemsSource="{Binding Data2}"
XBindingPath="Month"
YBindingPath="Sales"
Fill="#800000FF"
Opacity="0.6"/>Area with Markers
<chart:AreaSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"
ShowMarkers="True">
<chart:AreaSeries.MarkerSettings>
<chart:ChartMarkerSettings Type="Circle"
Fill="White"
Stroke="Blue"
StrokeWidth="2"
Height="8"
Width="8"/>
</chart:AreaSeries.MarkerSettings>
</chart:AreaSeries>Spline Area Chart
Combines spline curves with area filling:
<chart:SplineAreaSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"/>SplineAreaSeries series = new SplineAreaSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Month",
YBindingPath = "Sales"
};Column Chart
Column charts use vertical bars to compare values across categories.
Basic Column
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>ColumnSeries series = new ColumnSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "Category",
YBindingPath = "Value"
};Spacing and Width
Control bar spacing and width:
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
Spacing="0.3"
Width="0.7"/>Spacing: 0 to 1 (0 = no gap, 1 = 100% gap) Width: 0 to 1 (0 = no width, 1 = full width)
ColumnSeries series = new ColumnSeries()
{
ItemsSource = data,
XBindingPath = "Category",
YBindingPath = "Value",
Spacing = 0.3, // 30% spacing between bars
Width = 0.7 // 70% of available width
};Overlapped Columns
Place multiple series on top of each other:
<chart:SfCartesianChart EnableSideBySideSeriesPlacement="False">
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data1}"
XBindingPath="Category"
YBindingPath="Value"
Width="0.8"/>
<chart:ColumnSeries ItemsSource="{Binding Data2}"
XBindingPath="Category"
YBindingPath="Value"
Width="0.4"/>
</chart:SfCartesianChart>chart.EnableSideBySideSeriesPlacement = false;
ColumnSeries series1 = new ColumnSeries() { Width = 0.8 };
ColumnSeries series2 = new ColumnSeries() { Width = 0.4 };Bar Chart
Bar charts are horizontal columns, created by transposing the chart.
Basic Bar
<chart:SfCartesianChart IsTransposed="True">
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
chart.IsTransposed = true; // This makes columns horizontal (bar chart)
ColumnSeries series = new ColumnSeries()
{
ItemsSource = data,
XBindingPath = "Category",
YBindingPath = "Value"
};Bar with Spacing
<chart:SfCartesianChart IsTransposed="True">
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
Spacing="0.2"
Width="0.6"/>
</chart:SfCartesianChart>Scatter Chart
Scatter charts display data points as individual markers, ideal for correlation analysis.
Basic Scatter
<chart:ScatterSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"
PointHeight="10"
PointWidth="10"/>ScatterSeries series = new ScatterSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue",
PointHeight = 10,
PointWidth = 10
};Custom Point Shape
<chart:ScatterSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"
PointHeight="12"
PointWidth="12"
Fill="Orange"
Stroke="DarkOrange"
StrokeWidth="2"/>ScatterSeries series = new ScatterSeries()
{
ItemsSource = data,
XBindingPath = "XValue",
YBindingPath = "YValue",
PointHeight = 12,
PointWidth = 12,
Fill = new SolidColorBrush(Colors.Orange),
Stroke = new SolidColorBrush(Colors.DarkOrange),
StrokeWidth = 2
};Bubble Chart
Bubble charts add a third dimension (size) to scatter plots.
Basic Bubble
<chart:BubbleSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"
SizeValuePath="Size"/>BubbleSeries series = new BubbleSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue",
SizeValuePath = "Size" // Property that determines bubble size
};Data Model Example:
public class BubbleData
{
public double XValue { get; set; }
public double YValue { get; set; }
public double Size { get; set; } // Third dimension
}Size Constraints
Control minimum and maximum bubble sizes:
<chart:BubbleSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"
SizeValuePath="Size"
MinimumRadius="5"
MaximumRadius="50"/>BubbleSeries series = new BubbleSeries()
{
ItemsSource = data,
XBindingPath = "XValue",
YBindingPath = "YValue",
SizeValuePath = "Size",
MinimumRadius = 5,
MaximumRadius = 50
};Zero-Size Bubbles
Control visibility of zero-size bubbles:
<chart:BubbleSeries ItemsSource="{Binding Data}"
XBindingPath="XValue"
YBindingPath="YValue"
SizeValuePath="Size"
ShowZeroSizeBubbles="False"/>BubbleSeries series = new BubbleSeries()
{
ShowZeroSizeBubbles = false // Hide bubbles with size = 0
};When to Use Each Type
Line Chart
Use when:
- Showing trends over time
- Continuous data visualization
- Multiple series comparison
- Emphasizing rate of change
Example scenarios: Stock prices, temperature changes, sales trends
Spline Chart
Use when:
- Smoother trend visualization needed
- Data has natural curves
- Reducing visual noise from jagged lines
Example scenarios: Growth curves, demographic trends, smooth projections
Area Chart
Use when:
- Emphasizing magnitude of change
- Showing cumulative totals
- Visualizing part-to-whole relationships
- Comparing volumes over time
Example scenarios: Market share evolution, resource utilization, population growth
Column Chart
Use when:
- Comparing discrete categories
- Showing exact values
- Limited number of data points
- Vertical space available
Example scenarios: Monthly sales by product, survey results, regional comparisons
Bar Chart
Use when:
- Long category names
- Many categories to compare
- Horizontal layout preferred
- Reading convenience for labels
Example scenarios: Country rankings, feature comparisons, horizontal timelines
Scatter Chart
Use when:
- Analyzing correlation between two variables
- Identifying patterns or clusters
- Detecting outliers
- No categorical axis needed
Example scenarios: Height vs weight, price vs demand, test score correlations
Bubble Chart
Use when:
- Three variables need visualization
- Size represents important dimension
- Scatter plot needs additional context
- Comparing relative magnitudes
Example scenarios: Market analysis (price, volume, market cap), geographic data with population
Common Patterns
Multi-Series Comparison
<chart:SfCartesianChart>
<chart:SfCartesianChart.Legend>
<chart:ChartLegend/>
</chart:SfCartesianChart.Legend>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data2023}"
XBindingPath="Month"
YBindingPath="Sales"
Label="2023"
ShowMarkers="True"/>
<chart:LineSeries ItemsSource="{Binding Data2024}"
XBindingPath="Month"
YBindingPath="Sales"
Label="2024"
ShowMarkers="True"/>
</chart:SfCartesianChart>Mixed Chart Types
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<!-- Column for actual values -->
<chart:ColumnSeries ItemsSource="{Binding ActualData}"
XBindingPath="Month"
YBindingPath="Value"
Label="Actual"/>
<!-- Line for target/trend -->
<chart:LineSeries ItemsSource="{Binding TargetData}"
XBindingPath="Month"
YBindingPath="Value"
Label="Target"
StrokeDashArray="5,2"/>
</chart:SfCartesianChart>Tips and Best Practices
1. Choose appropriate chart type based on data characteristics and message 2. Use markers sparingly - only when highlighting specific points adds value 3. Limit series count - too many overlapping series reduce clarity 4. Consider color contrast - especially for overlapping area charts 5. Use legends when displaying multiple series 6. Adjust spacing/width for better visual balance 7. Match axis types to data (categorical, numerical, datetime) 8. Enable tooltips for detailed value inspection
Customization and Styling
Table of Contents
Overview
Syncfusion .NET MAUI Cartesian Chart provides extensive customization options to style charts according to your application's design requirements. You can apply custom styling to series, borders, plot area backgrounds, and more to create visually appealing and branded charts.
Series Styling
Fill and Stroke
Customize individual series appearance:
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"
Fill="Transparent"
Stroke="#2196F3"
StrokeWidth="3"/>LineSeries series = new LineSeries
{
ItemsSource = data,
XBindingPath = "Month",
YBindingPath = "Sales",
Fill = Colors.Transparent,
Stroke = new SolidColorBrush(Color.FromRgb(33, 150, 243)),
StrokeWidth = 3
};Opacity
Control transparency:
<chart:AreaSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Value"
Fill="#4CAF50"
Opacity="0.6"/>AreaSeries series = new AreaSeries
{
ItemsSource = data,
XBindingPath = "Month",
YBindingPath = "Value",
Fill = new SolidColorBrush(Color.FromRgb(76, 175, 80)),
Opacity = 0.6
};Border and Corner Radius
Series Borders
Add borders to series segments:
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
Fill="#9C27B0"
Stroke="#7B1FA2"
StrokeWidth="2"/>ColumnSeries series = new ColumnSeries
{
ItemsSource = data,
XBindingPath = "Category",
YBindingPath = "Value",
Fill = new SolidColorBrush(Color.FromRgb(156, 39, 176)),
Stroke = new SolidColorBrush(Color.FromRgb(123, 31, 162)),
StrokeWidth = 2
};Corner Radius for Columns
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
CornerRadius="10,10,0,0"/>ColumnSeries series = new ColumnSeries
{
ItemsSource = data,
XBindingPath = "Category",
YBindingPath = "Value",
CornerRadius = new CornerRadius(10, 10, 0, 0) // Top-left, Top-right, Bottom-right, Bottom-left
};Plot Area Customization
The PlotAreaBackgroundView property allows you to add custom backgrounds, watermarks, or any visual element to the chart's plot area (the area where data is rendered).
Add Background Image
<chart:SfCartesianChart>
<chart:SfCartesianChart.PlotAreaBackgroundView>
<Image Source="background.png"
Aspect="AspectFill"
Opacity="0.3"/>
</chart:SfCartesianChart.PlotAreaBackgroundView>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
Image backgroundImage = new Image
{
Source = "background.png",
Aspect = Aspect.AspectFill,
Opacity = 0.3
};
chart.PlotAreaBackgroundView = backgroundImage;Add Watermark
<chart:SfCartesianChart>
<chart:SfCartesianChart.PlotAreaBackgroundView>
<Label Text="CONFIDENTIAL"
FontSize="48"
TextColor="LightGray"
Opacity="0.2"
Rotation="-45"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</chart:SfCartesianChart.PlotAreaBackgroundView>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Value"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
Label watermark = new Label
{
Text = "CONFIDENTIAL",
FontSize = 48,
TextColor = Colors.LightGray,
Opacity = 0.2,
Rotation = -45,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
chart.PlotAreaBackgroundView = watermark;Custom Background with Gradient
<chart:SfCartesianChart>
<chart:SfCartesianChart.PlotAreaBackgroundView>
<BoxView>
<BoxView.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#E3F2FD" Offset="0.0"/>
<GradientStop Color="White" Offset="1.0"/>
</LinearGradientBrush>
</BoxView.Background>
</BoxView>
</chart:SfCartesianChart.PlotAreaBackgroundView>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:AreaSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Value"
Fill="#2196F3"
Opacity="0.6"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
LinearGradientBrush gradientBrush = new LinearGradientBrush
{
StartPoint = new Point(0, 0),
EndPoint = new Point(0, 1)
};
gradientBrush.GradientStops.Add(new GradientStop(Color.FromArgb("#E3F2FD"), 0.0f));
gradientBrush.GradientStops.Add(new GradientStop(Colors.White, 1.0f));
BoxView background = new BoxView
{
Background = gradientBrush
};
chart.PlotAreaBackgroundView = background;Complex Custom View
You can add any .NET MAUI view to the plot area background:
<chart:SfCartesianChart>
<chart:SfCartesianChart.PlotAreaBackgroundView>
<Grid>
<BoxView Color="#F5F5F5"/>
<Image Source="logo.png"
Aspect="AspectFit"
Opacity="0.1"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="200"
HeightRequest="200"/>
</Grid>
</chart:SfCartesianChart.PlotAreaBackgroundView>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Quarter"
YBindingPath="Revenue"
Label="Quarterly Revenue"/>
</chart:SfCartesianChart>Common Styling Patterns
Pattern 1: Rounded Column Chart
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
Fill="#2196F3"
CornerRadius="8,8,0,0"
Stroke="#1976D2"
StrokeWidth="2"/>
</chart:SfCartesianChart>Pattern 2: Dark Mode Chart
<chart:SfCartesianChart BackgroundColor="#1e1e1e">
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis>
<chart:CategoryAxis.LabelStyle>
<chart:ChartAxisLabelStyle TextColor="White"/>
</chart:CategoryAxis.LabelStyle>
<chart:CategoryAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="Gray"/>
</chart:CategoryAxis.AxisLineStyle>
</chart:CategoryAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis>
<chart:NumericalAxis.LabelStyle>
<chart:ChartAxisLabelStyle TextColor="White"/>
</chart:NumericalAxis.LabelStyle>
<chart:NumericalAxis.AxisLineStyle>
<chart:ChartLineStyle Stroke="Gray"/>
</chart:NumericalAxis.AxisLineStyle>
<chart:NumericalAxis.MajorGridLineStyle>
<chart:ChartLineStyle Stroke="#2d2d2d"/>
</chart:NumericalAxis.MajorGridLineStyle>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Value"
Stroke="#61DAFB"
StrokeWidth="3"
ShowMarkers="True">
<chart:LineSeries.MarkerSettings>
<chart:ChartMarkerSettings Fill="#61DAFB"
Stroke="White"
StrokeWidth="2"
Width="10"
Height="10"/>
</chart:LineSeries.MarkerSettings>
</chart:LineSeries>
</chart:SfCartesianChart>Pattern 3: Chart with Watermark
<chart:SfCartesianChart>
<chart:SfCartesianChart.PlotAreaBackgroundView>
<Grid>
<Image Source="company_logo.png"
Aspect="AspectFit"
Opacity="0.15"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="150"/>
</Grid>
</chart:SfCartesianChart.PlotAreaBackgroundView>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"
Fill="#4CAF50"/>
</chart:SfCartesianChart>Pattern 4: Multi-Series with Distinct Styles
<chart:SfCartesianChart>
<chart:SfCartesianChart.Legend>
<chart:ChartLegend/>
</chart:SfCartesianChart.Legend>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<!-- Actual values as columns -->
<chart:ColumnSeries ItemsSource="{Binding ActualData}"
XBindingPath="Month"
YBindingPath="Value"
Label="Actual"
Fill="#2196F3"
CornerRadius="5,5,0,0"/>
<!-- Target as dashed line -->
<chart:LineSeries ItemsSource="{Binding TargetData}"
XBindingPath="Month"
YBindingPath="Value"
Label="Target"
Stroke="#FF5722"
StrokeWidth="2"
StrokeDashArray="5,3"/>
</chart:SfCartesianChart>Tips and Best Practices
1. Corner Radius: Use corner radius on columns and bars for modern, polished appearance 2. Border Contrast: Add borders to series for better definition, especially on light backgrounds 3. Plot Area Backgrounds: Keep plot area backgrounds subtle (low opacity) to avoid obscuring data 4. Watermark Placement: Position watermarks centrally and rotate them to minimize data obstruction 5. Dark Mode Support: Adjust stroke colors, borders, and background elements appropriately for dark mode 6. Consistent Styling: Maintain consistent stroke widths and corner radius values across series 7. Test on Devices: Test styling appearance on actual devices as rendering may vary 8. Performance: Complex plot area backgrounds can impact performance on lower-end devices
Common Gotchas
Corner Radius and Series Types
- Corner radius only applies to column, bar, and similar rectangular series
- Not supported on line, area, or point-based series
- Order matters: Top-left, Top-right, Bottom-right, Bottom-left
Plot Area Background Layers
- Plot area background renders behind chart series
- Z-order cannot be changed - background is always behind data
- Complex views (with many children) can impact rendering performance
Stroke Width Scaling
- Stroke width does not scale with chart size automatically
- May need to adjust stroke width for different screen sizes
- Consider using responsive values for different device form factors
Opacity and Visibility
When using low opacity for backgrounds or series:
- May create unintended color blending effects
- Can reduce contrast and readability
- Test with actual data patterns to ensure clarity
Data Handling
Table of Contents
- Overview
- Empty Points
- Empty Point Mode
- Empty Point Customization
- Data Point Collection Methods
- GetDataPoints by Rectangle
- GetDataPoints by Range
- Touch Position
- OnTouchDown
- OnTouchMove
- OnTouchUp
- Best Practices
- Troubleshooting
Overview
Data handling in Cartesian Charts includes managing empty/missing data points, retrieving data points within specific regions, and capturing touch interactions. These features enable robust data visualization and user interaction.
Empty Points
Empty points represent missing or null data in a series. They can occur when data is unavailable, improperly formatted, or explicitly set as null or double.NaN.
Defining Empty Points
public class ViewModel
{
public ObservableCollection<Model> ProductSales { get; set; }
public ViewModel()
{
ProductSales = new ObservableCollection<Model>();
ProductSales.Add(new Model() { Product = "Electronics", Sales = 60 });
ProductSales.Add(new Model() { Product = "Clothing", Sales = 40 });
ProductSales.Add(new Model() { Product = "Groceries", Sales = double.NaN }); // Empty point
ProductSales.Add(new Model() { Product = "Furniture", Sales = 70 });
ProductSales.Add(new Model() { Product = "Toys", Sales = 30 });
ProductSales.Add(new Model() { Product = "Sports", Sales = double.NaN }); // Empty point
ProductSales.Add(new Model() { Product = "Books", Sales = 50 });
}
}Empty Point Mode
The EmptyPointMode property specifies how empty points are handled:
Available Modes:
None: Empty points not rendered (default)Zero: Replace empty points with zeroAverage: Replace with average of surrounding points
Zero Mode
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding ProductSales}"
XBindingPath="Product"
YBindingPath="Sales"
EmptyPointMode="Zero"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().ProductSales,
XBindingPath = "Product",
YBindingPath = "Sales",
EmptyPointMode = EmptyPointMode.Zero
};
chart.Series.Add(series);Average Mode
<chart:ColumnSeries ItemsSource="{Binding ProductSales}"
XBindingPath="Product"
YBindingPath="Sales"
EmptyPointMode="Average"/>ColumnSeries series = new ColumnSeries()
{
ItemsSource = new ViewModel().ProductSales,
XBindingPath = "Product",
YBindingPath = "Sales",
EmptyPointMode = EmptyPointMode.Average
};Empty Point Customization
Customize appearance of empty points using EmptyPointSettings:
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding ProductSales}"
XBindingPath="Product"
YBindingPath="Sales"
Fill="#3068F7"
StrokeWidth="2"
ShowMarkers="True"
ShowDataLabels="True"
EmptyPointMode="Average">
<chart:LineSeries.EmptyPointSettings>
<chart:EmptyPointSettings Fill="Orange"
Stroke="Red"
StrokeWidth="2"/>
</chart:LineSeries.EmptyPointSettings>
</chart:LineSeries>
</chart:SfCartesianChart>LineSeries series = new LineSeries()
{
ItemsSource = new ViewModel().ProductSales,
XBindingPath = "Product",
YBindingPath = "Sales",
Fill = new SolidColorBrush(Color.FromArgb("#3068F7")),
StrokeWidth = 2,
ShowMarkers = true,
ShowDataLabels = true,
EmptyPointMode = EmptyPointMode.Average
};
EmptyPointSettings emptyPointSettings = new EmptyPointSettings()
{
Fill = new SolidColorBrush(Colors.Orange),
Stroke = new SolidColorBrush(Colors.Red),
StrokeWidth = 2
};
series.EmptyPointSettings = emptyPointSettings;EmptyPointSettings Properties:
Fill: Fill color for empty pointsStroke: Stroke color for empty pointsStrokeWidth: Stroke thickness for empty points
Data Point Collection Methods
CartesianSeries provides methods to retrieve data points within specific regions.
GetDataPoints by Rectangle
Get data points that fall inside a rectangular region:
public class MainPage : ContentPage
{
private SfCartesianChart chart;
private LineSeries series;
public MainPage()
{
chart = new SfCartesianChart();
series = new LineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue"
};
chart.Series.Add(series);
// Define rectangular region
Rect rectangle = new Rect(50, 50, 200, 150);
// Get data points in region
List<object> dataPoints = series.GetDataPoints(rectangle);
// Process retrieved data points
foreach (var point in dataPoints)
{
// Handle each data point
}
Content = chart;
}
}GetDataPoints by Range
Get data points from specified axis visible range:
public class MainPage : ContentPage
{
private SfCartesianChart chart;
private LineSeries series;
public MainPage()
{
chart = new SfCartesianChart();
series = new LineSeries()
{
ItemsSource = new ViewModel().Data,
XBindingPath = "XValue",
YBindingPath = "YValue"
};
chart.Series.Add(series);
// Define coordinate ranges
double startX = 2;
double endX = 8;
double startY = 10;
double endY = 50;
// Get data points in range
List<object> dataPoints = series.GetDataPoints(startX, endX, startY, endY);
// Process retrieved data points
foreach (var point in dataPoints)
{
// Handle each data point
}
Content = chart;
}
}Using SeriesBounds
Get the visible plotting region at runtime:
// Get series visible bounds
Rect seriesBounds = chart.SeriesBounds;
// Use bounds for calculations
double width = seriesBounds.Width;
double height = seriesBounds.Height;Touch Position
Handle touch interactions using ChartInteractiveBehavior:
Custom Interactive Behavior
public class ChartInteractiveExt : ChartInteractiveBehavior
{
protected override void OnTouchDown(ChartBase chart, float pointX, float pointY)
{
base.OnTouchDown(chart, pointX, pointY);
// Handle touch down
System.Diagnostics.Debug.WriteLine($"Touch Down: X={pointX}, Y={pointY}");
}
protected override void OnTouchMove(ChartBase chart, float pointX, float pointY)
{
base.OnTouchMove(chart, pointX, pointY);
// Handle touch move
System.Diagnostics.Debug.WriteLine($"Touch Move: X={pointX}, Y={pointY}");
}
protected override void OnTouchUp(ChartBase chart, float pointX, float pointY)
{
base.OnTouchUp(chart, pointX, pointY);
// Handle touch up
System.Diagnostics.Debug.WriteLine($"Touch Up: X={pointX}, Y={pointY}");
}
}Adding Interactive Behavior
<chart:SfCartesianChart>
<chart:SfCartesianChart.InteractiveBehavior>
<local:ChartInteractiveExt/>
</chart:SfCartesianChart.InteractiveBehavior>
<chart:SfCartesianChart.XAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:LineSeries ItemsSource="{Binding Data}"
XBindingPath="X"
YBindingPath="Y"/>
</chart:SfCartesianChart>SfCartesianChart chart = new SfCartesianChart();
ChartInteractiveExt interactiveExt = new ChartInteractiveExt();
chart.InteractiveBehavior = interactiveExt;OnTouchDown
Called when user initiates touch:
protected override void OnTouchDown(ChartBase chart, float pointX, float pointY)
{
base.OnTouchDown(chart, pointX, pointY);
// Example: Highlight nearest data point
if (chart is SfCartesianChart cartesianChart)
{
var series = cartesianChart.Series[0] as CartesianSeries;
var rect = new Rect(pointX - 10, pointY - 10, 20, 20);
var points = series?.GetDataPoints(rect);
if (points?.Count > 0)
{
// Handle selection
}
}
}OnTouchMove
Called during touch drag:
protected override void OnTouchMove(ChartBase chart, float pointX, float pointY)
{
base.OnTouchMove(chart, pointX, pointY);
// Example: Update custom crosshair
UpdateCrosshair(pointX, pointY);
}
private void UpdateCrosshair(float x, float y)
{
// Custom crosshair logic
}OnTouchUp
Called when touch ends:
protected override void OnTouchUp(ChartBase chart, float pointX, float pointY)
{
base.OnTouchUp(chart, pointX, pointY);
// Example: Finalize selection
FinalizeSelection();
}
private void FinalizeSelection()
{
// Selection finalization logic
}Best Practices
Empty Point Handling
1. Choose Appropriate Mode: Select mode based on data context
Zero: When zero is a meaningful valueAverage: For smooth interpolationNone: When gaps should be visible
2. Visual Distinction: Make empty points visually distinct 3. Data Validation: Validate data before binding to chart 4. Documentation: Document how empty points are handled 5. User Communication: Inform users about missing data
Data Point Retrieval
1. Performance: Use specific regions to limit data retrieval 2. Coordinate Verification: Ensure coordinates within axis range 3. Null Checks: Always check for null/empty collections 4. Bounds Awareness: Use SeriesBounds for accurate positioning 5. Efficient Filtering: Retrieve only needed data points
Touch Interaction
1. Override Carefully: Call base methods when overriding 2. Performance: Keep touch handlers lightweight 3. Responsiveness: Provide immediate visual feedback 4. Platform Testing: Test on all target platforms 5. Gesture Conflicts: Avoid conflicts with built-in gestures
Common Patterns
Empty Point Handling with Customization:
<chart:LineSeries EmptyPointMode="Average"
ShowMarkers="True">
<chart:LineSeries.EmptyPointSettings>
<chart:EmptyPointSettings Fill="Orange" StrokeWidth="2"/>
</chart:LineSeries.EmptyPointSettings>
</chart:LineSeries>Selection by Region:
Rect selectionRect = new Rect(x - 5, y - 5, 10, 10);
List<object> selectedPoints = series.GetDataPoints(selectionRect);Troubleshooting
Issue: Empty points still showing gaps
- Solution: Set
EmptyPointModetoZeroorAverage - Solution: Verify EmptyPointMode property is set correctly
- Solution: Check data source for null values
Issue: EmptyPointSettings not applied
- Solution: Ensure EmptyPointMode is not
None - Solution: Verify EmptyPointSettings properly configured
- Solution: Check Fill/Stroke properties have values
Issue: GetDataPoints returns empty list
- Solution: Verify rectangle/range overlaps with data
- Solution: Check axis ranges include requested coordinates
- Solution: Ensure series has valid data points
Issue: Touch events not firing
- Solution: Verify InteractiveBehavior added to chart
- Solution: Call base methods in override implementations
- Solution: Check for gesture recognizer conflicts
Issue: Incorrect coordinates in touch events
- Solution: Coordinates are in pixels, not axis values
- Solution: Use appropriate conversion if needed
- Solution: Verify chart layout is complete
Issue: Empty points showing wrong color
- Solution: Set Fill property in EmptyPointSettings
- Solution: Check series PaletteBrushes not overriding
- Solution: Verify EmptyPointSettings assigned to series
Issue: Performance issues with GetDataPoints
- Solution: Limit region size for retrieval
- Solution: Cache results when appropriate
- Solution: Use specific ranges instead of large rectangles
Getting Started with .NET MAUI Cartesian Chart
This guide walks through the essential steps to install, configure, and create your first Syncfusion .NET MAUI Cartesian Chart (SfCartesianChart).
Installation
Step 1: Install NuGet Package
1. In Solution Explorer, right-click your project and choose Manage NuGet Packages 2. Search for Syncfusion.Maui.Charts 3. Install the latest version 4. Ensure all dependencies are installed correctly
Package: Syncfusion.Maui.Charts
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
using Syncfusion.Maui.Core.Hosting;
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: Call ConfigureSyncfusionCore() before Build(). Failure to register the handler will result in runtime errors.
Basic Chart Initialization
Step 1: Add Namespace
Import the Charts namespace in your XAML or C# file:
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">C#:
using Syncfusion.Maui.Charts;Step 2: Initialize SfCartesianChart
XAML:
<chart:SfCartesianChart/>C#:
SfCartesianChart chart = new SfCartesianChart();
this.Content = chart;Creating Data Model and ViewModel
Step 1: Define Data Model
Create a model class to represent your data points:
public class PersonModel
{
public string Name { get; set; }
public double Height { get; set; }
}Step 2: Create ViewModel
Create a ViewModel with observable data:
using System.Collections.ObjectModel;
public class PersonViewModel
{
public ObservableCollection<PersonModel> Data { get; set; }
public PersonViewModel()
{
Data = new ObservableCollection<PersonModel>
{
new PersonModel { Name = "David", Height = 170 },
new PersonModel { Name = "Michael", Height = 96 },
new PersonModel { Name = "Steve", Height = 65 },
new PersonModel { Name = "Joel", Height = 182 },
new PersonModel { Name = "Bob", Height = 134 }
};
}
}Step 3: Set BindingContext
XAML:
<ContentPage xmlns:model="clr-namespace:YourNamespace">
<ContentPage.BindingContext>
<model:PersonViewModel/>
</ContentPage.BindingContext>
</ContentPage>C#:
this.BindingContext = new PersonViewModel();Setting Up Axes
Cartesian charts require both X and Y axes. Use the XAxes and YAxes collections to add axes.
Common Axis Types
- CategoryAxis: For categorical data (names, months, etc.)
- NumericalAxis: For numeric values
- DateTimeAxis: For date/time data
- LogarithmicAxis: For logarithmic scale
Basic Axis Setup
XAML:
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis>
<chart:CategoryAxis.Title>
<chart:ChartAxisTitle Text="Name"/>
</chart:CategoryAxis.Title>
</chart:CategoryAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis>
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Height (cm)"/>
</chart:NumericalAxis.Title>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
</chart:SfCartesianChart>C#:
SfCartesianChart chart = new SfCartesianChart();
// X Axis
CategoryAxis primaryAxis = new CategoryAxis();
primaryAxis.Title = new ChartAxisTitle
{
Text = "Name"
};
chart.XAxes.Add(primaryAxis);
// Y Axis
NumericalAxis secondaryAxis = new NumericalAxis();
secondaryAxis.Title = new ChartAxisTitle
{
Text = "Height (cm)"
};
chart.YAxes.Add(secondaryAxis);Adding Your First Series
Series define the chart type and bind to your data. Use XBindingPath and YBindingPath to map data properties.
ColumnSeries Example
XAML:
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Name"
YBindingPath="Height"
ShowDataLabels="True"
EnableTooltip="True"/>
</chart:SfCartesianChart>C#:
ColumnSeries series = new ColumnSeries
{
ItemsSource = (new PersonViewModel()).Data,
XBindingPath = "Name",
YBindingPath = "Height",
ShowDataLabels = true,
EnableTooltip = true
};
chart.Series.Add(series);Complete Working Example
XAML Implementation
<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:YourNamespace">
<ContentPage.BindingContext>
<model:PersonViewModel/>
</ContentPage.BindingContext>
<chart:SfCartesianChart>
<chart:SfCartesianChart.Title>
<Label Text="Height Comparison" HorizontalOptions="Fill" HorizontalTextAlignment="Center"/>
</chart:SfCartesianChart.Title>
<chart:SfCartesianChart.Legend>
<chart:ChartLegend/>
</chart:SfCartesianChart.Legend>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis>
<chart:CategoryAxis.Title>
<chart:ChartAxisTitle Text="Name"/>
</chart:CategoryAxis.Title>
</chart:CategoryAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis>
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Height (cm)"/>
</chart:NumericalAxis.Title>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Name"
YBindingPath="Height"
EnableTooltip="True"
ShowDataLabels="True"
Label="Height">
<chart:ColumnSeries.DataLabelSettings>
<chart:CartesianDataLabelSettings LabelPlacement="Inner"/>
</chart:ColumnSeries.DataLabelSettings>
</chart:ColumnSeries>
</chart:SfCartesianChart>
</ContentPage>C# Implementation
using Syncfusion.Maui.Charts;
namespace ChartGettingStarted
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new PersonViewModel();
SfCartesianChart chart = new SfCartesianChart();
// Title
chart.Title = new Label
{
Text = "Height Comparison",
HorizontalOptions = LayoutOptions.Fill,
HorizontalTextAlignment = TextAlignment.Center
};
// Legend
chart.Legend = new ChartLegend();
// X Axis
CategoryAxis primaryAxis = new CategoryAxis();
primaryAxis.Title = new ChartAxisTitle { Text = "Name" };
chart.XAxes.Add(primaryAxis);
// Y Axis
NumericalAxis secondaryAxis = new NumericalAxis();
secondaryAxis.Title = new ChartAxisTitle { Text = "Height (cm)" };
chart.YAxes.Add(secondaryAxis);
// Series
ColumnSeries series = new ColumnSeries
{
ItemsSource = (new PersonViewModel()).Data,
XBindingPath = "Name",
YBindingPath = "Height",
ShowDataLabels = true,
EnableTooltip = true,
Label = "Height",
DataLabelSettings = new CartesianDataLabelSettings
{
LabelPlacement = DataLabelPlacement.Inner
}
};
chart.Series.Add(series);
this.Content = chart;
}
}
}Data Binding Concepts
ItemsSource
The ItemsSource property binds to your data collection. Use ObservableCollection<T> for automatic UI updates when data changes.
XBindingPath and YBindingPath
These properties specify which data model properties to use for X and Y values:
// Model properties
public class SalesData
{
public string Month { get; set; } // Used for XBindingPath
public double Sales { get; set; } // Used for YBindingPath
}
// Series binding
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Month"
YBindingPath="Sales"/>Common Gotchas
Missing Namespace Registration
Problem: Chart doesn't render or throws runtime errors.
Solution: Ensure you've called ConfigureSyncfusionCore() in MauiProgram.cs:
builder.ConfigureSyncfusionCore();No Data Displayed
Problem: Chart renders but shows no data points.
Solutions: 1. Verify ItemsSource has data 2. Check XBindingPath and YBindingPath match property names exactly (case-sensitive) 3. Ensure BindingContext is set correctly 4. Use ObservableCollection for dynamic data
Axes Not Visible
Problem: Chart area appears but no axes or data.
Solution: Verify both XAxes and YAxes collections have at least one axis:
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>Next Steps
After getting your basic chart running:
1. Explore Chart Types: Try LineSeries, AreaSeries, or other series types 2. Add Interactivity: Enable tooltips, trackball, zooming, and selection 3. Customize Appearance: Configure colors, legends, data labels 4. Advanced Features: Add annotations, trendlines, plotbands
Quick Reference
Minimum Required Code (XAML)
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis/>
</chart:SfCartesianChart.YAxes>
<chart:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Category"
YBindingPath="Value"/>
</chart:SfCartesianChart>Minimum Required Code (C#)
SfCartesianChart chart = new SfCartesianChart();
chart.XAxes.Add(new CategoryAxis());
chart.YAxes.Add(new NumericalAxis());
chart.Series.Add(new ColumnSeries
{
ItemsSource = data,
XBindingPath = "Category",
YBindingPath = "Value"
});
this.Content = chart;