How to visualize the empty points segments in FastLineSeries for .NET MAUI Toolkit Charts?
This article explains how to visualize gaps for empty points in the FastLineSeries of the .NET MAUI Toolkit SfCartesianChart.
By default, FastLineSeries excludes null or double.NaN values, as built-in support for Empty Points is limited in fast-rendering series types to maintain performance. As a result, representing visual breaks in fast line series data can be challenging.
Follow the step-by-step instructions to effectively address the limitation, ensuring both high rendering performance and visual clarity when plotting fast line charts with missing values.
Step 1: Create a CustomFastLineChart class by extending the SfCartesianChart control.
C#
public class CustomFastLineChart : SfCartesianChart
{
}
Step 2: Define the required bindable properties: ItemsSource, XBindingPath, and YBindingPath, along with their corresponding property changed handlers. These properties allow the chart to bind dynamically to external data sources and respond to changes in the dataset or binding paths.
C#
public class CustomFastLineChart : SfCartesianChart
{
/// <summary>
/// Identifies the ItemsSource bindable property.
/// </summary>
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(CustomFastLineChart), null,
propertyChanged: OnItemsSourcePropertyChanged);
/// <summary>
/// Identifies the XBindingPath bindable property.
/// </summary>
public static readonly BindableProperty XBindingPathProperty =
BindableProperty.Create(nameof(XBindingPath), typeof(string), typeof(CustomFastLineChart), null,
propertyChanged: OnBindingPathPropertyChanged);
/// <summary>
/// Identifies the YBindingPath bindable property.
/// </summary>
public static readonly BindableProperty YBindingPathProperty =
BindableProperty.Create(nameof(YBindingPath), typeof(string), typeof(CustomFastLineChart), null,
propertyChanged: OnBindingPathPropertyChanged);
/// <summary>
/// Gets or sets the items source for the chart
/// </summary>
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
/// <summary>
/// Gets or sets the XBindingPath for data points
/// </summary>
public string XBindingPath
{
get { return (string)GetValue(XBindingPathProperty); }
set { SetValue(XBindingPathProperty, value); }
}
/// <summary>
/// Gets or sets the YBindingPath for data points
/// </summary>
public string YBindingPath
{
get { return (string)GetValue(YBindingPathProperty); }
set { SetValue(YBindingPathProperty, value); }
}
}
Step 3: Implement the GenerateSeries method to process the data source and render valid segments as individual FastLineSeries instances by adding them to the Series collection of the SfCartesianChart. This method is invoked whenever the ItemsSource, XBindingPath, or YBindingPath properties change.
C#
private void GenerateSeries()
{
if (ItemsSource == null || string.IsNullOrEmpty(XBindingPath) || string.IsNullOrEmpty(YBindingPath))
return;
Series.Clear();
// Split the data into segments based on NaN values
var segments = SplitDataByNaNValues();
// Create FastLineSeries for each segment with valid values
foreach (var segment in segments)
{
if (segment.Count > 0)
{
var fastLineSeries = new FastLineSeries
{
ItemsSource = segment,
XBindingPath = XBindingPath,
YBindingPath = YBindingPath,
StrokeWidth = 2,
Fill = Colors.RoyalBlue
};
Series.Add(fastLineSeries);
}
}
}
Step 4: Construct the SplitDataByNaNValues method to split the data based on NaN values and generate valid individual segments, which are used within the GenerateSeries method to create separate FastLineSeries instances, as described in Step 3.
C#
/// <summary>
/// Splits the data into segments based on NaN values.
/// </summary>
private List<ObservableCollection<object>> SplitDataByNaNValues()
{
var segments = new List<ObservableCollection<object>>();
var currentSegment = new ObservableCollection<object>();
foreach (var item in ItemsSource)
{
// Get the Y value using reflection
var property = item.GetType().GetProperty(YBindingPath);
var yValue = property?.GetValue(item);
// Check if the value is NaN
bool isNaN = yValue != null &&
yValue is double doubleValue &&
double.IsNaN(doubleValue);
if (isNaN)
{
// When we hit a NaN value, finalize the current segment if it has items
if (currentSegment.Count > 0)
{
segments.Add(currentSegment);
currentSegment = new ObservableCollection<object>();
}
}
else
{
// Add the item to the current segment
currentSegment.Add(item);
}
}
// Add the last segment if it has items
if (currentSegment.Count > 0)
{
segments.Add(currentSegment);
}
return segments;
}
Step 5: Configure the CustomFastLineChart with chart axes in XAML by binding it to the data source and specifying the appropriate binding paths. For more detailed guidance on initializing a .NET MAUI Cartesian chart, refer to the official getting started documentation.
XAML
<local:CustomFastLineChart ItemsSource="{Binding DataSource}"
XBindingPath="Date"
YBindingPath="Metric">
<local:CustomFastLineChart.XAxes>
<chart:DateTimeAxis />
</local:CustomFastLineChart.XAxes>
<local:CustomFastLineChart.YAxes>
<chart:NumericalAxis />
</local:CustomFastLineChart.YAxes>
</local:CustomFastLineChart>
Output
Refer to the GitHub sample to examine the full working implementation.
Conclusion:
Hope you enjoyed learning how to visualize gaps for empty points in a FastLineSeries by creating a custom chart control with the .NET MAUI SfCartesianChart.
You can refer to our .NET MAUI Cartesian Charts feature tour page to learn about its other groundbreaking feature representations and documentation to understand how to present and manipulate data.
For current customers, check out our components from the License and Downloads page. If you are new to Syncfusion®, try our 30-day free trial to check out our other controls.
Please let us know in the comments section if you have any queries or require clarification. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!