Copied RSS Feed

Chart of the week

Unlock Insights on Export Trends with a .NET MAUI Toolkit Stacked Area Chart

TL;DR: Learn to visualize Saudi Arabia’s export trends across continents using the .NET MAUI Toolkit Stacked Area Chart with series highlighting, trackball integration, and DataGrid synchronization. This guide covers implementing these features to provide users with real-time updates, better insights, and interactive data exploration.

Welcome to this week’s edition of the Chart of the Week blog series!

Effectively analyzing multi-series data in charts can be challenging, especially when multiple series overlap or have closely placed data points. Highlighting a series based on user interaction allows users to focus on a specific data series, improving clarity and making comparisons more intuitive. This enhances the user experience by reducing visual clutter and making key trends stand out.

By implementing series highlighting, users can seamlessly track specific data points, compare different series, and gain deeper insights. Additionally, integrating a trackball feature helps display precise values for the highlighted series, making data analysis more efficient.

In this blog, we’ll use the Syncfusion .NET MAUI Toolkit Stacked Area Chart to visualize Saudi Arabia’s export trends across continents with the above mentioned features.

Practical use cases for series highlighting

Series highlighting is particularly beneficial in scenarios such as:

  • Financial data analysis: Easily track stock price movements and compare different investments.
  • Sales performance monitoring: Focus on the sales trend of particular products.
  • IoT data visualization: Monitor real-time sensor readings from multiple devices.
  • Website analytics: Analyze and emphasize specific traffic sources.
  • Healthcare data tracking: Highlight critical health parameters across different datasets.

Explore Syncfusion .NET MAUI Toolkit

Syncfusion’s .NET MAUI Toolkit is a powerful solution for building interactive and visually rich data visualizations. It supports real-time data updates and offers various customization options across multiple controls. As an open-source tool, it is available to developers free of cost.

Here, we’ll use our .NET MAUI Toolkit Stacked Area Chart for GDP Analysis.

Key features covered

  • Highlighting a series when interacting with the chart.
  • Dynamically updating a DataGrid to reflect the selected data segment.
  • Synchronizing the trackball and DataGrid to highlight relevant data.
  • Programmatically triggering the trackball from the DataGrid.
  • Exporting the chart as an image for easy sharing and reporting.
  • Dynamically changing the continent selection and updating the chart data accordingly.

Refer to the following image.

Now, let’s explore the implementation steps!

Step 1: Collecting the data

First, gather data on Saudi Arabia’s global exports by region. The extracted data is available as a CSV file on our GitHub repository.

Step 2: Configure the .NET MAUI Toolkit Stacked Area Chart

Step 3: Adding a Stacked Area series

Let’s use the StackedAreaSeries to display multiple series in the chart.

<chart:SfCartesianChart x:Name="chart" Margin="10, 0, 0, 5">

 <chart:SfCartesianChart.XAxes>
  <chart:NumericalAxis>
  </chart:NumericalAxis>
 </chart:SfCartesianChart.XAxes>

 <chart:SfCartesianChart.YAxes>
  <chart:NumericalAxis>
  </chart:NumericalAxis>
 </chart:SfCartesianChart.YAxes>

 <chart:StackingAreaSeries x:Name="series1" ItemsSource="{Binding ExportData}" XBindingPath="Year" Label="Oceania" />
 <chart:StackingAreaSeries x:Name="series2" ItemsSource="{Binding ExportData}" XBindingPath="Year" Label="Eastern Europe" />
 <chart:StackingAreaSeries x:Name="series3" ItemsSource="{Binding ExportData}" XBindingPath="Year" Label="Africa" />
 <chart:StackingAreaSeries x:Name="series4" ItemsSource="{Binding ExportData}" XBindingPath="Year" Label="South America" />
 <chart:StackingAreaSeries x:Name="series5" ItemsSource="{Binding ExportData}" XBindingPath="Year" Label="North America" YBindingPath="NorthAmerica" />
 <chart:StackingAreaSeries x:Name="series6" ItemsSource="{Binding ExportData}" XBindingPath="Year" YBindingPath="WesternEurope" />
 <chart:StackingAreaSeries x:Name="series7" ItemsSource="{Binding ExportData}" XBindingPath="Year" YBindingPath="Asia" />

</chart:SfCartesianChart>

These stacked series will represent different data categories(continents).

Step 4: Highlighting series on interaction

To enhance user interaction, highlight the series when hovering (for desktop) or long-pressing (for mobile devices).

XAML

<chart:SfCartesianChart>

 … 

 <chart:SfCartesianChart.InteractiveBehavior>
  <local:InteractionExt />
 </chart:SfCartesianChart.InteractiveBehavior>

</chart:SfCartesianChart>

C#

public class InteractionExt : ChartInteractiveBehavior
{
    protected override void OnTouchMove(ChartBase chart, float pointX, float pointY)
    {
        base.OnTouchMove(chart, pointX, pointY);
        bool isSeriesTouched = false;

        if (chart is SfCartesianChart stackedAreaChart)
        {
            var series = stackedAreaChart.Series;

            for (int i = 0; i < series.Count; i++)
            {
                var seriesItem = series[i];

                if (seriesItem != null)
                {
                    var index = seriesItem.GetDataPointIndex(pointX, pointY);

                    if (index != -1)
                    {
                        seriesItem.Opacity = 1;
                        isSeriesTouched = true;
                    }
                    else
                    {
                        seriesItem.Opacity = 0.33;
                    }
                }
            }

            if (!isSeriesTouched)
            {
                foreach (var item in series)
                {
                    item.Opacity = 1;
                }
            }
        }
    }
}

This reduces the visibility of unselected series while keeping the highlighted series fully visible.

Step 5: Integrating trackball to show selected data

The trackball is used to display precise data values when interacting with the chart. The trackballgets highlighted for the currently selected series, while the visibility of other labels is reduced. Here, the trackball is implemented using a trackball template.

XAML

<chart:SfCartesianChart x:Name="chart">

 <chart:SfCartesianChart.Resources>
  <local:TrackballLabelConverter x:Key="labelConverter"/>
  <local:TrackballColorConverter x:Key="colorConverter"/>

  <DataTemplate x:Key="trackballLabelTemplate">
   <Border Stroke="Black" Background="LightYellow" StrokeThickness="2" StrokeShape="RoundRectangle 20" Padding="10">
    <Grid ColumnSpacing="5" RowSpacing="5" RowDefinitions="Auto, Auto, Auto, Auto ,Auto, Auto, Auto, 1, Auto">
     <Grid.ColumnDefinitions>
      <ColumnDefinition Width="{OnPlatform Android='8', Default='15'}"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="Auto"/>
     </Grid.ColumnDefinitions>

     <BoxView Grid.Row="0" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}" Opacity="{Binding Source={x:Reference series1}, Path=Opacity}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=0}" />
     <Label Grid.Row="0" Grid.Column="1" Text="Export to Oceania" TextColor="Black" Opacity="{Binding Source={x:Reference series1}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="0" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=0}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series1}, Path=Opacity}"/>

     <BoxView Grid.Row="1" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}" Opacity="{Binding Source={x:Reference series2}, Path=Opacity}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=1}" />
     <Label Grid.Row="1" Grid.Column="1" Text="Export to Eastern Europe" TextColor="Black" Opacity="{Binding Source={x:Reference series2}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="1" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=1}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series2}, Path=Opacity}"/>

     <BoxView Grid.Row="2" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}" Opacity="{Binding Source={x:Reference series3}, Path=Opacity}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=2}" />
     <Label Grid.Row="2" Grid.Column="1" Text="Export to Africa" TextColor="Black" Opacity="{Binding Source={x:Reference series3}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="2" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=2}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series3}, Path=Opacity}"/>

     <BoxView Grid.Row="3" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=3}" Opacity="{Binding Source={x:Reference series4}, Path=Opacity}" />
     <Label Grid.Row="3" Grid.Column="1" Text="Export to South America" TextColor="Black" Opacity="{Binding Source={x:Reference series4}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="3" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=3}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series4}, Path=Opacity}"/>

     <BoxView Grid.Row="4" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=4}" Opacity="{Binding Source={x:Reference series5}, Path=Opacity}"/>
     <Label Grid.Row="4" Grid.Column="1" Text="Export to North America" TextColor="Black" Opacity="{Binding Source={x:Reference series5}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="4" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=4}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series5}, Path=Opacity}"/>

     <BoxView Grid.Row="5" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=5}" Opacity="{Binding Source={x:Reference series6}, Path=Opacity}"/>
     <Label Grid.Row="5" Grid.Column="1" Text="Export to Western Europe" TextColor="Black" Opacity="{Binding Source={x:Reference series6}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="5" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=5}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series6}, Path=Opacity}"/>

     <BoxView Grid.Row="6" Grid.Column="0" WidthRequest="{OnPlatform Android=8, Default=10}" HeightRequest="{OnPlatform Android=8, Default=10}"
      BackgroundColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter=6}" Opacity="{Binding Source={x:Reference series7}, Path=Opacity}"/>
     <Label Grid.Row="6" Grid.Column="1" Text="Export to Asia" TextColor="Black" Opacity="{Binding Source={x:Reference series7}, Path=Opacity}" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="6" Grid.Column="2" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=6}" TextColor="Black" FontSize="{OnPlatform Android=12}" Opacity="{Binding Source={x:Reference series7}, Path=Opacity}"/>

     <BoxView Grid.Row="7" Grid.ColumnSpan="3" HeightRequest="1" BackgroundColor="LightGray"/>

     <Label Grid.Row="8" Grid.Column="1" Text="Total" FontAttributes="Bold" FontSize="{OnPlatform Android=12}"/>
     <Label Grid.Row="8" Grid.Column="2" FontSize="{OnPlatform Android=12}" Text="{Binding ., Converter={StaticResource labelConverter}, ConverterParameter=7}" FontAttributes="Bold"/>
    </Grid>
   </Border>
  </DataTemplate>

  <DataTemplate x:Key="axisLabelTemplate">
   <Label HorizontalTextAlignment="Center" BackgroundColor="LightYellow" Text="{Binding }" TextColor="Black" FontSize ="{OnPlatform Android=12}"/>
  </DataTemplate>

 </chart:SfCartesianChart.Resources>

 <chart:SfCartesianChart.XAxes>
  <chart:NumericalAxis TrackballLabelTemplate="{StaticResource axisLabelTemplate}" ShowTrackballLabel="True">
  </chart:NumericalAxis>
 </chart:SfCartesianChart.XAxes>

 <chart:SfCartesianChart.YAxes>
  … 
 </chart:SfCartesianChart.YAxes>

 <chart:SfCartesianChart.TrackballBehavior>
  <local:TrackballExt x:Name="trackball">
   <local:TrackballExt.LabelStyle>
    <chart:ChartLabelStyle Background="Transparent"/>
   </local:TrackballExt.LabelStyle>
  </local:TrackballExt>
 </chart:SfCartesianChart.TrackballBehavior>

 <chart:StackingAreaSeries x:Name="series1" />
 <chart:StackingAreaSeries x:Name="series2" />
 <chart:StackingAreaSeries x:Name="series3" />
 <chart:StackingAreaSeries x:Name="series4" />
 <chart:StackingAreaSeries x:Name="series5" TrackballLabelTemplate="{StaticResource trackballLabelTemplate}" />
 <chart:StackingAreaSeries x:Name="series6" />
 <chart:StackingAreaSeries x:Name="series7" />

</chart:SfCartesianChart>

C#

public class TrackballExt : ChartTrackballBehavior
{
    protected override void LabelsGenerated(List<TrackballPointInfo> pointInfos)
    {
        foreach (var item in pointInfos)
        {
            var series = item.Series;

            if (series is StackingAreaSeries stackingArea && stackingArea.YBindingPath != "NorthAmerica")
            {
                item.Label = string.Empty;
            }

            item.MarkerSettings = new ChartMarkerSettings() 
            { 
                Fill = Colors.White, 
                Stroke = series.Fill, 
                StrokeWidth = 2 
            };
        }
    }
}

This enables the trackball feature, which will help users analyze data more effectively.

Step 6: Configuring the .NET MAUI DataGrid

To provide a comprehensive data exploration experience, we’ll integrate Syncfusion .NET MAUI DataGrid into the app. To do so, install the Syncfusion.Maui.DataGrid NuGet package and configure the DataGrid by referring to the documentation.

XAML

<syncfusion:SfDataGrid x:Name="dataGrid" AutoGenerateColumnsMode="None" 
                ItemsSource="{Binding ExportData}" FrozenRowCount="0" FrozenColumnCount="1"
                Margin="{OnPlatform WinUI='5, 75, 5, 35', iOS=5, Android=5}" 
                GridLinesVisibility="Both"
                HeaderGridLinesVisibility="Both" QueryRowHeight="DataGrid_QueryRowHeight">
     
 <syncfusion:SfDataGrid.DefaultStyle>
  <syncfusion:DataGridStyle RowBackground="#66C4D4FD" CurrentCellBorderColor="LightYellow" CurrentCellBorderWidth="0" HeaderGridLineColor="Black" GridLineColor="Black"/>
 </syncfusion:SfDataGrid.DefaultStyle>
                
 <syncfusion:SfDataGrid.Resources>
  <Style TargetType="syncfusion:DataGridHeaderCell">
   <Setter Property="Background" Value="#C4D4FD"/>
   <Setter Property="FontSize" Value="12"/>
  </Style>
  <Style TargetType="syncfusion:DataGridCell">
   <Setter Property="FontSize" Value="12"/>
  </Style>
 </syncfusion:SfDataGrid.Resources>
               
 <syncfusion:SfDataGrid.Columns>
  <syncfusion:DataGridTextColumn MappingName="Year" HeaderText="Year" />
  <syncfusion:DataGridTextColumn MappingName="Oceania" HeaderText="Oceania" Format="0.00'%" />
  <syncfusion:DataGridTextColumn MappingName="EasternEurope" HeaderText="Eastern Europe" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="Africa" HeaderText="Africa" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="SouthAmerica" HeaderText="South America" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="NorthAmerica" HeaderText="North America" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="WesternEurope" HeaderText="Western Europe" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="Asia" HeaderText="Asia" Format="0.00'%"/>
  <syncfusion:DataGridTextColumn MappingName="Total" HeaderText="Total" Format="0.00'%" />
 </syncfusion:SfDataGrid.Columns>

</syncfusion:SfDataGrid>

C#

private void DataGrid_QueryRowHeight(object sender, DataGridQueryRowHeightEventArgs e)
{
    if (e.RowIndex == 0)
    {
        e.Height = e.GetIntrinsicRowHeight(e.RowIndex);
        e.Handled = true;
    }
}

Step 7: Updating the DataGrid based on trackball selection

To ensure a seamless data exploration experience, synchronize the DataGrid with the selected trackball index. Refer to the following code examples to highlight the respective data in the DataGrid based on the trackball interaction.

XAML

<chart:SfCartesianChart TrackballCreated="chart_TrackballCreated" x:Name="chart">
 …
</chart:SfCartesianChart>

C#

public partial class MainPage : ContentPage
{
    private void chart_TrackballCreated(object sender, TrackballEventArgs e)
    {
        var pointInfo = e.TrackballPointsInfo;
        var model = pointInfo[0].DataItem as Model;
        var index = viewModel.ExportData.IndexOf(model);
        this.dataGrid.SelectedIndex = index + 1;
        this.dataGrid.ScrollToRowIndex(index, ScrollToPosition.Center, true);
    }
}

Step 8: Triggering trackball from DataGrid selection

To allow two-way interaction, programmatically trigger the trackball when an item is selected in the DataGrid. This ensures that the trackball updates the chart when an item is selected in the DataGrid.

XAML

<syncfusion:SfDataGrid x:Name="dataGrid" SelectionChanged="dataGrid_SelectionChanged"
                        SelectionMode="SingleDeselect">
    
 <syncfusion:SfDataGrid.DefaultStyle>
  <syncfusion:DataGridStyle SelectionBackground="LightYellow" />
 </syncfusion:SfDataGrid.DefaultStyle>
                               
 <syncfusion:SfDataGrid.Columns>
  ….
 </syncfusion:SfDataGrid.Columns>

</syncfusion:SfDataGrid>

C#

public partial class MainPage : ContentPage
{
private void dataGrid_SelectionChanged(object sender, DataGridSelectionChangedEventArgs e)
 {
     if (dataGrid.SelectedIndex > 0)
     {
         var index = this.dataGrid.SelectedIndex - 1;
         var model = viewModel.ExportData[index];
         var xPoint = chart.ValueToPoint(chart.XAxes[0], model.Year);
         var yPoint = chart.ValueToPoint(chart.YAxes[0], model.NorthAmerica);
         this.chart.TrackballBehavior.Show(xPoint, yPoint);
     }
     else
     {
         chart.TrackballBehavior.Hide();
     }
 }
}

Step 9: Exporting the chart as an image

Now, export the chart as an image for reporting and sharing purposes.

XAML

<Border HeightRequest="40" Grid.Column="1"
        Margin="0, 10, 5, 0"
        HorizontalOptions="End"
        VerticalOptions="Center"
        Background="Transparent">
    
 <Border.StrokeShape>
        <RoundRectangle CornerRadius="20" />
 </Border.StrokeShape>

 <Border.GestureRecognizers>
  <TapGestureRecognizer NumberOfTapsRequired="1"
                               Tapped="TapGestureRecognizer_Tapped_1" />
 </Border.GestureRecognizers>

 <Grid x:Name="myGrid"
          ColumnDefinitions="35,*"
          RowDefinitions="*>">
        
  <Image Source="image.png" Margin="5" WidthRequest="20" HeightRequest="20">
  </Image>
        
  <Label Grid.Column="1"
               Text="Download chart"
               HeightRequest="20"
               Margin="2, 5, 10, 5"
               HorizontalTextAlignment="Start"
               VerticalTextAlignment="Center" />
 </Grid>
    
</Border>

C#

public partial class MainPage : ContentPage
{
private void TapGestureRecognizer_Tapped_1(object sender, TappedEventArgs e)
{
    chart.SaveAsImage("Chart.png");
} 
}

This allows exporting the chart as an image, making it convenient for reports.

Step 10: Dynamically changing the continent selection

To update the chart data dynamically, provide an option to change the selected continent using SfCombox.

XAML

<HorizontalStackLayout Grid.Row="0" Grid.Column="0">
 <Label Text="Edit countries" VerticalOptions="Center" Margin="0, 5, 5, 0" />
 <editors:SfComboBox x:Name="comboBox" Margin="0, 5, 0, 0" HorizontalOptions="FillAndExpand" MinimumWidthRequest="120"
                         DisplayMemberPath="Name" TextMemberPath="Name" Placeholder="Select" IsClearButtonVisible="False"
                         ItemsSource="{Binding Countries}" TextColor="Black" SelectionChanged="comboBox_SelectionChanged" />
</HorizontalStackLayout>

C#

private void comboBox_SelectionChanged(object sender, Syncfusion.Maui.Inputs.SelectionChangedEventArgs e)
{
    var comboBox = (SfComboBox)sender;
    int index =  comboBox.SelectedIndex;
    var item = comboBox.SelectedItem as Country;
    chart.TrackballBehavior.Hide();
    viewModel.ReadCSV(item.Name);
    viewModel.SelectedCountry = item.Name;
}

This updates the chart based on the user’s selection.

Step 11: Enhancing chart style for better visualization

We’ll customize various chart styling elements such as title, gridlines, and series appearance to make the chart visually appealing.

Refer to the following image.

     
<chart:SfCartesianChart >

 <chart:SfCartesianChart.Resources>
                
  <DoubleCollection x:Key="gridLine">
   <x:Double>3</x:Double>
    <x:Double>3</x:Double>
  </DoubleCollection>

  </chart:SfCartesianChart.Resources>

  <chart:SfCartesianChart.Title>

   <Grid Margin="0, 10, 0, 10">
    <Grid.ColumnDefinitions>
     <ColumnDefinition Width="3*"/>
     <ColumnDefinition Width="{OnPlatform Android=49*,WinUI=59*,MacCatalyst=59*,iOS=49*}"/>
    </Grid.ColumnDefinitions>
    <Image Source="export.png" WidthRequest="{OnPlatform WinUI='40', Android='25', MacCatalyst='50'}" 
                        Margin="25, 0, 0, 0" HeightRequest="{OnPlatform WinUI='40', Android='25', MacCatalyst='50'}" 
                        Grid.Column="0" Grid.RowSpan="2"/>
    <VerticalStackLayout Grid.Column="1" Margin="20, 0, 0, 0">
     <Label Text="{Binding TitleText}" 
                            FontSize="{OnPlatform Default='20', Android='15', iOS='18'}" 
                            Padding="{OnPlatform Default='0,0,5,2', Android='0,0,5,0', iOS='0,0,5,0'}" 
                            HorizontalTextAlignment="Start"/>
     <Label Text="{Binding SubTitleText}" 
                            HorizontalTextAlignment="Start" FontSize="{OnPlatform Android=8,WinUI=12,MacCatalyst=16,iOS=13}" 
                            TextColor="Grey" />
    </VerticalStackLayout>
    </Grid>

  </chart:SfCartesianChart.Title>

  <chart:SfCartesianChart.XAxes>

   <chart:NumericalAxis ShowMajorGridLines="False" EdgeLabelsVisibilityMode="AlwaysVisible" EdgeLabelsDrawingMode="Center" PlotOffsetEnd="15" >
   </chart:NumericalAxis>

  </chart:SfCartesianChart.XAxes>

  <chart:SfCartesianChart.YAxes>

   <chart:NumericalAxis>
    <chart:NumericalAxis.LabelStyle>
     <chart:ChartAxisLabelStyle LabelFormat="0'%"/>
    </chart:NumericalAxis.LabelStyle>
    <chart:NumericalAxis.AxisLineStyle>
     <chart:ChartLineStyle StrokeWidth="0"/>
    </chart:NumericalAxis.AxisLineStyle>
    <chart:NumericalAxis.MajorTickStyle>
     <chart:ChartAxisTickStyle StrokeWidth="0"/>
    </chart:NumericalAxis.MajorTickStyle>
    <chart:NumericalAxis.MajorGridLineStyle>
     <chart:ChartLineStyle StrokeDashArray="{StaticResource gridLine}"/>
    </chart:NumericalAxis.MajorGridLineStyle>
   </chart:NumericalAxis>

  </chart:SfCartesianChart.YAxes>

  <chart:SfCartesianChart.TrackballBehavior>
   <local:TrackballExt x:Name="trackball">
    <local:TrackballExt.LabelStyle>
     <chart:ChartLabelStyle Background="Transparent"/>
    </local:TrackballExt.LabelStyle>
   </local:TrackballExt>
  </chart:SfCartesianChart.TrackballBehavior>


  <chart:StackingAreaSeries x:Name="series1" Fill="#910A67" Stroke="#910A67"
                               StrokeWidth="3"/>

  <chart:StackingAreaSeries x:Name="series2" Fill="#D49B54" Stroke="#D49B54" 
                   XBindingPath="Year"  StrokeWidth="3"/>
                   
  <chart:StackingAreaSeries x:Name="series3" Fill="#EB3678" Stroke="#EB3678" 
                   XBindingPath="Year"  StrokeWidth="3"/>

  <chart:StackingAreaSeries x:Name="series4" Fill="#4E9F3D" Stroke="#4E9F3D"
                   XBindingPath="Year"  StrokeWidth="3"/>
              
  <chart:StackingAreaSeries x:Name="series5" Fill="#107ee2" Stroke="#107ee2"
StrokeWidth="3"/>

  <chart:StackingAreaSeries x:Name="series6" Fill="#ef5d3d" Stroke="#ef5d3d"
                   XBindingPath="Year"   StrokeWidth="3"/>
                

   <chart:StackingAreaSeries x:Name="series7” Fill="#150485" Stroke="#150485"
StrokeWidth="3"/>

</chart:SfCartesianChart>

Step 12: Adding a legend to the chart

A legend helps users quickly identify different data series in the chart, making the visualization more intuitive. Refer to the following code example to configure and customize the legend in the chart.

<chart:SfCartesianChart>

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

 <chart:StackingAreaSeries x:Name="series1" 
        Label="Oceania" LegendIcon="SeriesType" />

 <chart:StackingAreaSeries x:Name="series2" 
        Label="Eastern Europe" LegendIcon="SeriesType" />

 <chart:StackingAreaSeries x:Name="series3" 
        Label="Africa" LegendIcon="SeriesType" />

 <chart:StackingAreaSeries x:Name="series4" 
        Label="South America" LegendIcon="SeriesType" />

 <chart:StackingAreaSeries x:Name="series5" 
        Label="North America" LegendIcon="SeriesType" />

 <chart:StackingAreaSeries x:Name="series6" 
        LegendIcon="SeriesType" 
        Label="Western Europe" />

 <chart:StackingAreaSeries x:Name="series7" 
        Label="Asia" LegendIcon="SeriesType" />

</chart:SfCartesianChart>

Refer to the following image.

Visualizing Saudi Arabia’s export trends across continents using .NET MAUI Toolkit Stacked Area Chart

GitHub reference

For more details, refer to our GitHub demo.

Supercharge your cross-platform apps with Syncfusion's robust .NET MAUI controls.

Conclusion

Thanks for reading! In this blog, we’ve explored how to use the Syncfusion .NET MAUI Toolkit Stacked Area Chart to visualize Saudi Arabia’s export trends across continents. Try out the steps discussed in this blog and leave your feedback in the comments section below.

You can also contact us through support forumssupport portal, or feedback portal. We are always happy to assist you!

Meet the Author

Vimala Thirumalai Kumar

Vimala Thirumalai Kumar has been a software developer in Syncfusion since 2022. She works on developing custom controls with improved UI for Microsoft technologies.