TL;DR: Let’s visualize annual gold price trends using Syncfusion .NET MAUI Spline Area Chart. Bind gold exchange rate data, customize tooltips, and add threshold lines for insights. A Picker enables dynamic currency switching, while annotations and a polished layout boost interactivity and usability.
Welcome to our Chart of the Week blog series!
The Syncfusion Toolkit for .NET MAUI is a robust, high-performance suite of UI controls tailored to accelerate cross-platform app development for Android, iOS, macOS, and Windows. This toolkit empowers developers to create visually stunning, feature-packed apps with minimal effort, significantly reducing development time. By leveraging Syncfusion’s comprehensive set of controls, developers can ensure a smooth, consistent, and engaging user experience across all supported platforms, simplifying the complexity of building cross-platform solutions.
In today’s post, we’ll create a Spline Area Chart using the Syncfusion .NET MAUI Chart Toolkit to track annual gold price fluctuations across major global currencies. We’ll also cover how to enhance your chart’s interactivity and visual appeal by incorporating custom tooltips, threshold lines, and dynamic series updates based on user input.
By customizing tooltips, we can deliver precise and relevant information clearly and engagingly. The charts’ TooltipTemplate property allows us to design tooltips that display vital details in a format that suits your app’s needs.
Threshold lines are useful for marking significant data points on a chart. By adding horizontal threshold lines with annotations, we can instantly highlight key information.
In this implementation, we’ll add annotations to display the highest and lowest annual growth in gold prices. These lines help users quickly identify important trends and patterns within the data. Additionally, the annotations are fully customizable, allowing you to adjust their appearance to create a more polished user interface.
To make the chart more interactive, we’ll use the Picker to allow users to select different currencies. Based on the selected currency, the chart’s spline area series will be dynamically updated to reflect the gold price fluctuations for that currency. This approach gives users flexibility, enabling them to explore the data for various currencies without needing to refresh the page or reload the chart.
Refer to the following image.
Let’s get started!
First, gather annual gold exchange rate data by currency from the GOLDPRICE site. Next, organize this information in an Excel spreadsheet, listing each year alongside its corresponding currency exchange rate. Finally, save the Excel file in CSV format.
Then, create a Model class to represent each year’s currency exchange rates for gold. Refer to the following code example.
public class Model { public DateTime Year { get; set; } public double USD { get; set; } public double AUD { get; set; } public double CAD { get; set; } public double CHF { get; set; } public double CNY { get; set; } public double EUR { get; set; } public double GBP { get; set; } public double INR { get; set; } public double JPY { get; set; } public Model(DateTime year, double usd, double aud, double cad, double chf, double cny, double eur, double gbp, double inr, double jpy) { Year = year; USD = usd; AUD = aud; CAD = cad; CHF = chf; CNY = cny; EUR = eur; GBP = gbp; INR = inr; JPY = jpy; } }
Next, create a ViewModel class to hold the collection of gold exchange rates. This ViewModel will read data from a CSV file and store each year’s exchange rates in the GoldPriceRate observable collection.
Refer to the following code example.
public class ViewModel { public ObservableCollection<Model> GoldPriceRate { get; set; } public ViewModel() { GoldPriceRate = new ObservableCollection<Model>(); ReadCSV(); } private void ReadCSV() { Assembly executingAssembly = typeof(App).GetTypeInfo().Assembly; Stream? inputStream = executingAssembly.GetManifestResourceStream("GoldPriceRateDemo.Resources.Data.AnnualGoldExchangeData.csv"); string? line; List<string> lines = new List<string>(); if (inputStream != null) { using StreamReader reader = new StreamReader(inputStream); while ((line = reader.ReadLine()) != null) { lines.Add(line); } lines.RemoveAt(0); foreach (var dataPoint in lines) { string[] data = dataPoint.Split(','); if (int.TryParse(data[0], out int yearValue)) year = new DateTime(yearValue, 1, 1); double usd = Convert.ToDouble(data[1]); double aud = Convert.ToDouble(data[2]); double cad = Convert.ToDouble(data[3]); double chf = Convert.ToDouble(data[4]); double cny = Convert.ToDouble(data[5]); double eur = Convert.ToDouble(data[6]); double gbp = Convert.ToDouble(data[7]); double inr = Convert.ToDouble(data[8]); double jpy = Convert.ToDouble(data[9]); GoldPriceRate.Add(new Model(year, usd, aud, cad, chf, cny, eur, gbp, inr, jpy)); } } }
Let’s define the layout using a Border element to create a visually appealing container. Inside the Border, we’ll use a chart and a grid to organize and position various elements.
Refer to the following code example.
<Border Stroke="Black" StrokeThickness="4" StrokeShape="{OnPlatform Default= RoundRectangle 40, Android= RoundRectangle 35}"> … </Border>
Now, configure the Syncfusion .NET MAUI Cartesian Charts control by setting up both the X- and Y-axes.
<chart:SfCartesianChart> <chart:SfCartesianChart.XAxes> <chart:DateTimeAxis/> </chart:SfCartesianChart.XAxes> <chart:SfCartesianChart.YAxes> <chart:NumericalAxis /> </chart:SfCartesianChart.YAxes> … </chart:SfCartesianChart>
In this step, we’ll bind the data to the Syncfusion .NET MAUI Spline Area series to visualize the annual gold exchange rate across different currencies.
To start, bind the ViewModel to the chart’s BindingContext, giving the chart access to the data properties in the ViewModel. Next, use the XBindingPath property to bind the year to the chart’s X axes. Then, bind the GoldPriceRate collection to the chart’s ItemsSource to display the data.
<chart:SfCartesianChart > <chart:SfCartesianChart.BindingContext> <model:ViewModel/> </chart:SfCartesianChart.BindingContext> <chart:SplineAreaSeries x:Name="series" ItemsSource="{Binding GoldPriceRate}" XBindingPath="Year"/> </chart:SfCartesianChart>
To allow users to dynamically select a currency and see the corresponding data on the chart, we’ll integrate the Picker. This Picker will let users select a currency, and the chart series will update based on the selected currency.
To achieve this, first, define a string array in the ViewModel to hold all the currency names.
public string[] CurrencyName { get; set; } public string SelectedCurrency { get; set; } ...... CurrencyName = new string[] { "USD", "AUD", "CAD", "CHF", "CNY", "EUR", "GBP", "INR", "JPY" }; SelectedCurrency = "USD";
Then, bind the CurrencyName to the Picker’s ItemsSource property.
<Picker x:Name="picker" WidthRequest="{OnPlatform Default=200, Android=130, iOS=100}" ItemsSource="{Binding CurrencyName}" SelectedItem="{Binding SelectedCurrency}"/>
Binding the SelectedItem of a Picker control directly to the YBindingPath of a chart series allows for dynamic updates of chart data based on user interaction. Refer to the following code example.
<chart:SplineAreaSeries ItemsSource="{Binding GoldPriceRate}" XBindingPath="Year" YBindingPath="{Binding Source={x:Reference picker},Path=SelectedItem}"/>
To enable and customize tooltips, set the EnableTooltip property to True. The SfCartesianChart control provides customization options for tooltips via the TooltipTemplate property.
Here, we’ll create a custom template that displays the annual currency exchange rate (in percentage) using the tooltip binding context of Item. We’ll then bind this custom template to the TooltipTemplate property. Refer to the following code example.
<chart:SplineAreaSeries EnableTooltip="True" TooltipTemplate="{StaticResource TooltipTemplate}"/>
Create a custom tooltip template, as shown in the following code example. Here, we’ll dynamically convert values using a CurrencyConverter and update the tooltip based on the Picker selection.
<chart:SfCartesianChart> <chart:SfCartesianChart.Resources> <ResourceDictionary> <local:CurrencyConverter x:Key="currencyConverter"/> <DataTemplate x:Key="TooltipTemplate"> <HorizontalStackLayout HorizontalOptions="Start"> <Path Data="{Binding Item,Converter= {StaticResource currencyConverter},ConverterParameter={Binding Source={x:Reference picker}}}" Fill="{Binding Item,Converter= {StaticResource currencyConverter},ConverterParameter={Binding Source={x:Reference picker}}}" HorizontalOptions="Start" Scale="0.6" TranslationX="-7" Margin="0,0,0,0"/> <Label Text="Annual Growth:" TextColor="White" FontSize="12" HorizontalOptions="Start" VerticalOptions="Center" Margin="-10,0,0,0"/> <Label Text="{Binding Item, Converter={StaticResource currencyConverter},ConverterParameter={Binding Source={x:Reference picker}}}" TextColor="White" FontSize="12" VerticalOptions="Center" HorizontalOptions="Start" Margin="3,0,0,0"/> </HorizontalStackLayout> </DataTemplate> </ResourceDictionary> </chart:SfCartesianChart.Resources>
The CurrencyConverter class implements the IValueConverter interface, enabling dynamic data conversion for UI elements based on context and user interaction, such as Picker selection. This converter supports multiple target types, such as Brush, string, and PathGeometry, for flexible and dynamic UI updates.
public class CurrencyConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Model model && parameter is Binding binding && binding.Source is Picker picker) { var selectedCurrency = picker.SelectedItem?.ToString()?.ToUpper(); if (string.IsNullOrEmpty(selectedCurrency) || !model.CurrencyValues.TryGetValue(selectedCurrency, out double valueForCurrency)) { return string.Empty; } if (targetType == typeof(Brush)) { return valueForCurrency > 0 ? Color.FromArgb("#62825D") : Color.FromArgb("#b30000"); } if (targetType == typeof(string)) { return valueForCurrency; } if (valueForCurrency > 0) { return new PathGeometryConverter().ConvertFromInvariantString("M15.995972,0L32,21.478999 0,21.478999z"); } else { return new PathGeometryConverter().ConvertFromInvariantString("M0,0L32,0 16,19.7z"); } } return string.Empty; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } }
We’ll use horizontal line annotations in the chart to indicate threshold levels, which visually represent the highest and lowest annual growth rates. These annotations help users easily identify significant points on the chart, such as when growth exceeds or falls below certain levels.
Initialize the HorizontalLineAnnotation class by setting the Y1 property, which specifies the value where the line should be drawn on the chart. The appearance of the line can be customized using the Stroke and StrokeDashArray property.
The Text property allows us to display annotation labels. Additionally, we can customize the annotation label’s appearance using the ChartAnnotationLabelStyle. We can also adjust properties like text color, alignment, and positioning to improve the label’s visibility and placement.
Refer to the following code example.
<chart:SfCartesianChart.Annotations> <chart:HorizontalLineAnnotation Text="Highest Annual Growth" Y1="20" Stroke="#62825D" StrokeWidth="2" StrokeDashArray="4,2,4"> <chart:HorizontalLineAnnotation.LabelStyle> <chart:ChartAnnotationLabelStyle TextColor="Black" HorizontalTextAlignment="End" VerticalTextAlignment="Start" FontSize="13"/> </chart:HorizontalLineAnnotation.LabelStyle> </chart:HorizontalLineAnnotation> <chart:HorizontalLineAnnotation Text="Lowest Annual Growth" Y1="-25" Stroke="#b30000" StrokeWidth="2" StrokeDashArray="4,2,4"> <chart:HorizontalLineAnnotation.LabelStyle> <chart:ChartAnnotationLabelStyle TextColor="Black" HorizontalTextAlignment="End" VerticalTextAlignment="End" FontSize="13"/> </chart:HorizontalLineAnnotation.LabelStyle> </chart:HorizontalLineAnnotation> </chart:SfCartesianChart.Annotations>
Using ViewAnnotation, we can place custom images anywhere on the chart area. The X1 and Y1 properties help us to position the image accurately on the chart.
Refer to the following code example.
<chart:SfCartesianChart.Annotations> <chart:ViewAnnotation X1="{OnPlatform WinUI=2021-03-01,Android=2020-06-25,iOS=2019-09-28, MacCatalyst=2021-09-01}" Y1="{OnPlatform WinUI='22.9', Android='25.8', iOS='25.8', MacCatalyst='21.3'}" CoordinateUnit="Axis"> <chart:ViewAnnotation.View> <Image Source="uparrow.png" HeightRequest="30" WidthRequest="30" /> </chart:ViewAnnotation.View> </chart:ViewAnnotation> <chart:ViewAnnotation X1="{OnPlatform WinUI= 2021-03-08, Android=2020-07-15, MacCatalyst= 2021-09-01,iOS=2019-11-01}" Y1="{OnPlatform WinUI='-27.4', Android='-29.9', iOS='-29.3', MacCatalyst='-26'}" CoordinateUnit="Axis"> <chart:ViewAnnotation.View> <Image Source="downarrow.png" HeightRequest="30" WidthRequest="30"/> </chart:ViewAnnotation.View> </chart:ViewAnnotation> </chart:SfCartesianChart.Annotations>
Finally, let’s further enhance the visual appeal of the Spline Area series by customizing its title, axes, and series.
Refer to the following code example to customize the chart title and picker appearance.
<chart:SfCartesianChart.Title> <Grid RowDefinitions="*,*" ColumnDefinitions="70,*"> <Image Grid.Column="0" Grid.RowSpan="2" Source="goldicon.png" HeightRequest="55" WidthRequest="55" Margin="{OnPlatform WinUI='15,3,0,0', Android='5,0,0,0',iOS='5,0,0,0', MacCatalyst='5,0,0,0'}" VerticalOptions="Start"/> <Label Grid.Row="0" Grid.Column="1" Text="Tracking Annual Gold Price Fluctuations by Percentage Across Major Global Currencies" TextColor="Black" HorizontalOptions="Start" FontSize="18" FontAttributes="Bold" Margin="{OnPlatform WinUI='5,5,0,0',Android='5,5,0,0',iOS='5,5,0,0',MacCatalyst='5,5,0,0'}"/> <HorizontalStackLayout Grid.Row="1" Grid.Column="1" > <Label Text="Annual percentage changes in gold prices from 2009 to 2023, compared across major global currencies." WidthRequest="{OnPlatform iOS='345', Android='345'}" MaxLines="1" TextColor="Black" HorizontalOptions="Start" FontSize="12" Margin="{OnPlatform WinUI='5,6,0,0',Android ='5,4,0,0', MacCatalyst='5,0,0,0', iOS='5,4,0,0'}"/> <Label Text="Choose Currency" TextColor="Black" FontSize="14" Margin="{OnPlatform WinUI='180,0,5,0', Android='30,0,5,0', iOS='30,0,5,0', MacCatalyst='800,0,5,0'}" VerticalOptions="Center"/> <Picker x:Name="picker" WidthRequest="{OnPlatform Default=200, Android=130, iOS=100}" ItemsSource="{Binding CurrencyName}" SelectedItem="{Binding SelectedCurrency}"/> </HorizontalStackLayout> </Grid> </chart:SfCartesianChart.Title>
To enhance the appearance and functionality of both the primary and secondary axes, you can use various properties such as:
Refer to the following code example.
<chart:SfCartesianChart> <chart:SfCartesianChart.XAxes> <chart:DateTimeAxis ShowMajorGridLines="False"> <chart:DateTimeAxis.Title> <chart:ChartAxisTitle Text="Year"/> </chart:DateTimeAxis.Title> <chart:DateTimeAxis.LabelStyle> <chart:ChartAxisLabelStyle LabelFormat="yyyy"/> </chart:DateTimeAxis.LabelStyle> </chart:DateTimeAxis> </chart:SfCartesianChart.XAxes> <chart:SfCartesianChart.YAxes> <chart:NumericalAxis ShowMajorGridLines="False" Minimum="-40" Maximum="40"> <chart:NumericalAxis.Title> <chart:ChartAxisTitle Text="% Annual Exchange Rate"/> </chart:NumericalAxis.Title> <chart:NumericalAxis.LabelStyle> <chart:ChartAxisLabelStyle/> </chart:NumericalAxis.LabelStyle> </chart:NumericalAxis> </chart:SfCartesianChart.YAxes> </chart:SfCartesianChart>
To enhance the visual appeal of the Spline Area series, we’ll apply a Fill color and adjust the opacity as shown in the following code example.
<chart:SfCartesianChart> <chart:SplineAreaSeries x:Name="series" Fill="#FAB12F" Opacity="0.9"> </chart:SplineAreaSeries> </chart:SfCartesianChart>
After executing these code examples, we will get the output that resembles the following image.
For more details, refer to the Tracking of annual gold price fluctuations across major global currencies using the .NET MAUI Spline Area Chart GitHub demo.
Thank you for reading! In this blog, we’ve explored how to track annual gold price fluctuations across major global currencies using Syncfusion .NET MAUI Spline Area Chart. We highly recommend following the steps outlined in this blog and sharing your feedback in the comments section below.
Existing customers can download the new version of Essential Studio® on the License and Downloads page. If you are not a Syncfusion customer, try our 30-day free trial to experience our incredible features.
You can also contact us through our support forum, feedback portal, or support portal. We are always happy to assist you!