TL;DR: Want to visualize natural gas price volatility with more than just basic charts? Syncfusion’s .NET MAUI Toolkit lets you build custom variance indicators complete with directional arrows, percentage labels, and dynamic styling to help developers track market trends with clarity and precision.
Let’s be real, if your energy market charts only show price points, you’re missing the bigger picture. Today’s analysts and developers need visualizations that reveal volatility, trends, and directional shifts at a glance. That’s where Syncfusion’s .NET MAUI Toolkit Column Chart and Range Column Chart come in. In this post, we’ll show you how to build custom variance indicators complete with arrows, percentage labels, and dynamic color changes to visualize natural gas price volatility with clarity and impact.
Variance indicators are tools or metrics used to measure and visualize the difference between two values, typically to show change, deviation, or performance gaps. They are commonly used in data analysis, business intelligence, and dashboards to highlight trends or anomalies.
Variance indicators provide significant value in scenarios such as:
Syncfusion’s .NET MAUI Toolkit is a powerful collection of UI components for cross-platform application development. As an open-source tool, it’s freely available to developers and offers:
For our natural gas price volatility visualization, we’ll leverage the SfCartesianChart component with custom renderers.
Let’s explore the implementation steps!
First, gather historical Henry Hub Natural Gas Spot Price data from the Federal Reserve Economic Data (FRED) database. This dataset provides reliable pricing information for natural gas in USD per million BTU and highlights significant volatility over the past decade. For this example, we’ll focus on annual price points from 2014 to 2024.
Ensure the .NET MAUI Toolkit is properly configured in your application. Start by installing the Syncfusion® .NET MAUI Toolkit via NuGet. Then, refer to the official .NET MAUI Toolkit Charts documentation for detailed setup and configuration instructions. Once installed, you can begin using the Column Chart and Range Column Chart components to visualize price volatility data with custom variance indicators.
The data model needs to store both the time period and price value, along with additional properties to support variance calculations. We’ll use historical Henry Hub Natural Gas Spot Price data from the Federal Reserve Economic Data (FRED) database, which offers reliable pricing information for this key energy commodity.
In our model, we include properties for the year, price value, and high/low values. This will help us establish relationships between consecutive data points for calculating percentage changes as shown in the code example below.
public class ChartDataModel
{
public DateTime Year { get; set; }
public double YValue { get; set; }
public double High { get; set; }
public double Low { get; set; }
}
The Year and YValue properties store the time period and price value, while the High and Low properties help calculate the variance between consecutive time points.
The view model manages the data collection and prepares it for visualization. A key innovation in our approach is the use of the ProcessData() method to establish relationships between consecutive data points, enabling accurate variance calculations.
The view model populates historical Henry Hub natural gas price data and processes it to define the high-low relationships that drive our variance indicators. By storing both the current value and the next period’s value for each data point, we create a solid foundation for calculating percentage changes.
public class ChartViewModel
{
public ObservableCollection<ChartDataModel> Data { get; set; }
public ChartViewModel()
{
// Create the data collection
Data = new ObservableCollection<ChartDataModel>();
AddDataPoint(new DateTime(2014, 1, 1), 4.71);
AddDataPoint(new DateTime(2016, 1, 1), 2.28);
AddDataPoint(new DateTime(2018, 1, 1), 3.87);
AddDataPoint(new DateTime(2020, 1, 1), 2.02);
AddDataPoint(new DateTime(2022, 1, 1), 4.38);
AddDataPoint(new DateTime(2024, 1, 1), 3.18);
// Process data to calculate variance between points
ProcessData();
}
private void AddDataPoint(DateTime year, double value)
{
Data.Add(new ChartDataModel
{
Year = year,
YValue = value,
// Initialize to same value - will be updated later
Low = value,
High = value
});
}
private void ProcessData()
{
// Skip processing if we have 0 or 1 data points
if (Data.Count <= 1) return;
// For each point (except last), set high value to next point's value
for (int i = 0; i < Data.Count - 1; i++)
{
Data[i].Low = Data[i].YValue;
Data[i].High = Data[i + 1].YValue;
}
}
}
To effectively visualize our natural gas price data, we need to configure appropriate axes for the chart. We’ll use a DateTimeAxis for the X-axis to represent time periods, and a NumericalAxis for the Y-axis to display price values as shown in the code example below.
<syncfusion:SfCartesianChart.XAxes>
<syncfusion:DateTimeAxis/>
</syncfusion:SfCartesianChart.XAxes>
<syncfusion:SfCartesianChart.YAxes>
<syncfusion:NumericalAxis/>
</syncfusion:SfCartesianChart.YAxes>
At the core of our advanced visualization is the extension of the standard RangeColumnSeries to create a specialized RangeColumnSeriesExt class for rendering variance indicators. The RangeColumnSeries provides built-in functionality for displaying high-low ranges, which we leverage in our custom implementation.
This extension overrides the CreateSegment() method to return our custom RangeColumnSegmentExt class, allowing us to inject specialized rendering logic while retaining all the built-in functionality of the standard series.
public class RangeColumnSeriesExt : RangeColumnSeries
{
protected override ChartSegment CreateSegment()
{
return new RangeColumnSegmentExt();
}
}
The custom RangeColumnSegmentExt class extends the base RangeColumnSegment to draw connecting lines, directional arrows, and percentage labels that visualize the variance between consecutive price points. By overriding the Draw method, RangeColumnSegmentExt calculates the percentage change and dynamically positions visual elements based on price movement direction.
The Draw method in the RangeColumnSegmentExt creates a vertical line connecting consecutive price points, draws an arrow indicating direction, and displays a percentage label that is color-coded (green for increases, red for decreases). We use PathF to create custom arrow shapes and position them dynamically based on price movement.
public partial class RangeColumnSegmentExt : RangeColumnSegment
{
float offsetPercentage = 0.2f;
float topArrowTextGap = 3.0f;
float bottomArrowTextGap = 1.0f;
protected override void Draw(ICanvas canvas)
{
// Call base layout first
base.OnLayout();
// Skip drawing if segment isn't properly laid out or data is missing
if (float.IsNaN(Left) || float.IsNaN(Top) || float.IsNaN(Right) || float.IsNaN(Bottom) ||
Series is not RangeColumnSeriesExt || Item is not ChartDataModel dataPoint)
return;
// Skip last segment or if there's no change
var itemsSource = Series.ItemsSource as ObservableCollection<ChartDataModel>;
if (Index == itemsSource?.Count - 1 || dataPoint.Low == dataPoint.High)
return;
// Calculate change direction and percentage
bool isIncreasing = dataPoint.Low < dataPoint.High;
double changePercent = Math.Abs((dataPoint.High - dataPoint.Low) / dataPoint.Low) * 100;
// Set color based on direction
Color arrowColor = isIncreasing ? Colors.Green : Colors.Red;
// Ensure we have a valid drawing canvas
if (canvas == null) return;
// Save canvas state before drawing
canvas.SaveState();
float columnWidth = Right - Left;
float offsetX = columnWidth * offsetPercentage;
float centerX = (Left + Right) / 2 + offsetX;
// Draw line first
canvas.StrokeColor = Colors.Black;
canvas.StrokeSize = 1f;
canvas.DrawLine(centerX, Top, centerX, Bottom);
// Draw arrow
float arrowSize = 6;
var arrowPath = new PathF();
// Draw arrow based on direction
if (isIncreasing)
{
arrowPath.MoveTo(centerX, Top);
arrowPath.LineTo(centerX - arrowSize, Top + arrowSize);
arrowPath.LineTo(centerX + arrowSize, Top + arrowSize);
}
else
{
arrowPath.MoveTo(centerX, Bottom);
arrowPath.LineTo(centerX - arrowSize, Bottom - arrowSize);
arrowPath.LineTo(centerX + arrowSize, Bottom - arrowSize);
}
arrowPath.Close();
canvas.FillColor = Colors.Black;
canvas.FillPath(arrowPath);
// Draw percentage text with clear formatting.
string percentText = isIncreasing ?
$"{changePercent:0}%" :
$"- {changePercent:0}%";
var labelStyle = new ChartAxisLabelStyle() { FontSize = 12, TextColor = arrowColor };
var font = Font.Default;
// Measure text size using canvas.
SizeF textSize = canvas.GetStringSize(percentText, font, (float)labelStyle.FontSize);
float textY = isIncreasing ? Top - (textSize.Height * topArrowTextGap) : Bottom + (textSize.Height * bottomArrowTextGap);
canvas.DrawText(percentText, centerX - (textSize.Width / 2), textY, labelStyle);
canvas.RestoreState();
}
}
Our visualization uses a dual-series approach, with each series highlighting a different aspect of the data. We also configure the chart axes to ensure clear and professional presentation of the time periods and price values.
A standard ColumnSeries displays the actual natural gas price values, while our custom RangeColumnSeriesExt renders the variance indicators
This combination creates a comprehensive visualization that shows both absolute price levels and relative changes between consecutive periods.
<syncfusion:SfCartesianChart.Series>
<syncfusion:ColumnSeries ItemsSource="{Binding Data}"
XBindingPath="Year"
YBindingPath="YValue">
</syncfusion:ColumnSeries>
<local:RangeColumnSeriesExt ItemsSource="{Binding Data}"
XBindingPath="Year"
High="High"
Low="Low"/>
</syncfusion:SfCartesianChart.Series>
To ensure professional presentation, we enhance the chart axes with appropriate interval settings, titles, and grid line styling as shown in the below code example.
<syncfusion:SfCartesianChart.XAxes>
<syncfusion:DateTimeAxis Interval="2" IntervalType="Years">
<syncfusion:DateTimeAxis.Title>
<syncfusion:ChartAxisTitle Text="Time Period (Years)"/>
</syncfusion:DateTimeAxis.Title>
<syncfusion:DateTimeAxis.AxisLineStyle>
<syncfusion:ChartLineStyle Stroke="#888888"/>
</syncfusion:DateTimeAxis.AxisLineStyle>
</syncfusion:DateTimeAxis>
</syncfusion:SfCartesianChart.XAxes>
<syncfusion:SfCartesianChart.YAxes>
<syncfusion:NumericalAxis Maximum="5.5" Interval="1">
<syncfusion:NumericalAxis.Title>
<syncfusion:ChartAxisTitle Text="Price (USD per Million BTU)"/>
</syncfusion:NumericalAxis.Title>
<syncfusion:NumericalAxis.MajorGridLineStyle>
<syncfusion:ChartLineStyle StrokeWidth="{OnPlatform Android=0.0,iOS=0.0}"/>
</syncfusion:NumericalAxis.MajorGridLineStyle>
</syncfusion:NumericalAxis>
</syncfusion:SfCartesianChart.YAxes>
We can enhance the appearance of the chart by adjusting its existing properties.
<syncfusion:ColumnSeries
...
Spacing="{OnPlatform Android=0.5, iOS=0.5}"
Fill="#7bb4eb"
ShowDataLabels="False">
</syncfusion:ColumnSeries>
To enhance visual appeal and provide context for our visualization, we’ll add a custom chart title with descriptive subtitles.
You can configure the chart title using the Title property combined with a StackLayout to organize both the title and subtitle text as shown in the code example below.
<syncfusion:SfCartesianChart.Title>
<StackLayout Grid.Column="1" Orientation="Vertical" HorizontalOptions="Start">
<Label Text="Building Variance Indicators to Visualize Natural Gas Price Volatility"
FontAttributes="Bold"
FontSize="{OnPlatform Android=12, Default=16, iOS=12}" />
<Label Text="Visual Analysis of Natural Gas Price Volatility (2014–2024)"
FontSize="{OnPlatform Android=10, Default=12, iOS=10}" />
</StackLayout>
</syncfusion:SfCartesianChart.Title>
To provide detailed, on-demand information, we use a custom tooltip implemented with TooltipTemplate and ChartTooltipBehavior. This displays both the year and price value when users hover over data points.
The tooltip uses StringFormat='{}{0:yyyy}'
to format the year as a 4-digit value and presents both the time period and price in a clean, bordered container with consistent styling.
<syncfusion:SfCartesianChart.Resources>
<DataTemplate x:Key="tooltipTemplate">
<Border BackgroundColor="#7bb4eb"
Padding="8, 3, 8, 3"
Stroke="Transparent">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Item.Year, StringFormat='{}{0:yyyy}'}"
TextColor="Black"
FontSize="14"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text=" : "
TextColor="Black"
FontAttributes="Bold"
FontSize="14"
HorizontalOptions="Center"
VerticalOptions="Center" />
<BoxView WidthRequest="5"
BackgroundColor="Transparent" />
<Label Text="{Binding Item.YValue}"
TextColor="Black"
FontSize="14"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</Border>
</DataTemplate>
</syncfusion:SfCartesianChart.Resources>
<syncfusion:SfCartesianChart.TooltipBehavior>
<syncfusion:ChartTooltipBehavior Background="#7bb4eb" />
</syncfusion:SfCartesianChart.TooltipBehavior>
<syncfusion:ColumnSeries
...
EnableTooltip="True"
TooltipTemplate="{StaticResource tooltipTemplate}">
</syncfusion:ColumnSeries>
<local:RangeColumnSeriesExt
...
EnableTooltip="False" />
Refer to the following image.
For more details, refer to the GitHub demo.
Q1. Is the Syncfusion® .NET MAUI Toolkit open-source and cross-platform compatible?
Yes, the Syncfusion® .NET MAUI Toolkit is an open-source tool that is freely available to developers. It offers cross-platform compatibility, working seamlessly across iOS, Android, macOS, and Windows.
Q2. How do Syncfusion® .NET MAUI Charts enable custom visualizations like these variance indicators?
Syncfusion’s .NET MAUI Charts, particularly the SfCartesianChart, provide cross-platform support, high-performance rendering, and extensive customization. This post demonstrates how to extend the RangeColumnSeries and override the CreateSegment() and Draw() methods to render custom variance indicators such as connecting lines, directional arrows, and color-coded percentage labels enabling developers to visualize data trends with greater clarity.
Natural gas data is volatile, and your charts should reflect that. With Syncfusion’s .NET MAUI Toolkit Cartesian Charts, you can go beyond static visuals and build interactive, insightful variance indicators that bring energy market trends to life.
Whether you’re building dashboards for analysts, traders, or researchers, these tools help you deliver clarity, context, and confidence in every chart.
Ready to elevate your .NET MAUI apps? Try Syncfusion’s charting components today and start visualizing volatility like a pro. Try out the steps discussed in this blog and leave 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 check our incredible features.
If you require assistance, please don’t hesitate to contact us via our support forum, support portal, or feedback portal. We are always eager to help you! Stay tuned for next week’s featured Chart of the Week.