Creating a Tornado Chart in .NET MAUI SfCartesianChart: Step-by-Step Guide
This article explains how to create a tornado chart using the column chart in MAUI.
A ‘tornado chart’ is a specific type of bar chart that includes two horizontal bars extending from a defined midpoint. It is used to compare data among different categories or types.
Model
To create the tornado chart, we require the original values in their negative form. I’ve changed the sine of the original value and stored it to another property.
public class Model
{
public DateTime Date { get; set; }
public double DieselPrice { get; set; }
public double PetrolPrice { get; set; }
public double NegativePetrolPrice { get; set; }
public Model(DateTime date, double petrolPrice, double dieselPrice)
{
Date = date;
PetrolPrice = petrolPrice;
NegativePetrolPrice = - petrolPrice;
DieselPrice = dieselPrice;
}
}
ViewModel
public class ViewModel
{
public ObservableCollection<model> FuelsPriceDetails { get; set; }
public ViewModel()
{
FuelsPriceDetails = new ObservableCollection<model>()
{
new Model (new DateTime(2014,01,01), 127.50, 133.46),
new Model (new DateTime(2015,01,01), 111.13, 114.90),
new Model (new DateTime(2016,01,01), 108.85, 110.13),
new Model (new DateTime(2017,01,01), 117.59, 120.15),
new Model (new DateTime(2018,01,01), 125.20, 129.98),
new Model (new DateTime(2019,01,01), 124.88, 131.48),
new Model (new DateTime(2020,01,01), 113.95, 119.14),
new Model (new DateTime(2021,01,01), 131.27, 134.94),
new Model (new DateTime(2022,01,01), 164.73, 177.66)
};
}
}
Create a column chart using the Cartesian Chart documentation. Set IsTransposed to true and EnableSideBySidePlacement to false to create a horizontal bar chart and avoid having segments arranged side by side.
XAML
<chart:sfcartesianchart istransposed="True" enablesidebysideseriesplacement="False">
…
<chart:columnseries itemssource="{Binding FuelsPriceDetails}" xbindingpath="Date" ybindingpath="NegativePetrolPrice">
<chart:columnseries itemssource="{Binding FuelsPriceDetails}" xbindingpath="Date" ybindingpath="DieselPrice">
</chart:columnseries></chart:columnseries></chart:sfcartesianchart>
C#
SfCartesianChart chart = new SfCartesianChart();
chart.IsTransposed = true;
chart.EnableSideBySideSeriesPlacement = false;
ColumnSeries series1 = new ColumnSeries()
{
ItemsSource = (new ViewModel()).FuelsPriceDetails,
XBindingPath = "Date",
YBindingPath = "NegativePetrolPrice",
};
ColumnSeries series2 = new ColumnSeries()
{
ItemsSource = (new ViewModel()).FuelsPriceDetails,
XBindingPath = "Date",
YBindingPath = "DieselPrice",
};
chart.Series.Add(series1);
chart.Series.Add(series2);
On the left side series, data labels and the y-axis display negative values. To eliminate the negative sign, set the LabelFormat as follows:
DataLabel:
XAML
<chart:columnseries>
<chart:columnseries.datalabelsettings>
<chart:cartesiandatalabelsettings>
<chart:cartesiandatalabelsettings.labelstyle>
<chart:chartdatalabelstyle labelformat="0;#.##">
</chart:chartdatalabelstyle></chart:cartesiandatalabelsettings.labelstyle>
</chart:cartesiandatalabelsettings>
</chart:columnseries.datalabelsettings>
</chart:columnseries>
C#
ColumnSeries series1 = new ColumnSeries()
{
…
};
series1.DataLabelSettings = new CartesianDataLabelSettings();
series1.DataLabelSettings.LabelStyle = new ChartDataLabelStyle
{
LabelFormat = "0;#.##"
};
Axis Label:
XAML
<chart:sfcartesianchart.yaxes>
<chart:numericalaxis>
<chart:numericalaxis.labelstyle>
<chart:chartaxislabelstyle labelformat="0;#.##">
</chart:chartaxislabelstyle></chart:numericalaxis.labelstyle>
</chart:numericalaxis>
</chart:sfcartesianchart.yaxes>
C#
NumericalAxis secondaryAxis = new NumericalAxis();
secondaryAxis.Title = new ChartAxisTitle();
secondaryAxis.LabelStyle = new ChartAxisLabelStyle()
{
LabelFormat = "0;#.##"
};
chart.YAxes.Add(secondaryAxis);
Output:
You can download the complete sample in this GitHub location.