Skip to main content Skip to footer

How to Create a C# .NET Tornado Chart

Quick Start Guide
What You Will Need

Visual Studio 2026

ComponentOne WinForms Edition

Controls Referenced

FlexChart

Tutorial Concept A Tornado Chart helps identify which factors have the greatest impact on an outcome by visualizing two series directly opposed to one another. This guide shows how to create one in C# .NET using FlexChart with simple bar chart customizations.

Data visualization is all about telling a clear story, and tornado charts are often chosen because they clearly help compare two variables in your data set. Tornado charts (sometimes also known as population pyramids) are essentially bar charts with two series rendered on opposite sides of the Y axis.

WinForms Tornado Chart

FlexChart is a flexible C# and VB.NET charting control that can be used to create bar charts and customized to create tornado charts and population pyramids.

In this tutorial, we will demonstrate how you can create a simple tornado chart to compare two series in a desktop Windows application. We'll walk through how to structure your data, configure the chart, and apply the visual adjustments needed to transform a basic bar chart into a clean, professional population pyramid like the one shown above.

Step 1: Setting up the Project and Data Source

Step 2: Sorting the Data Set in C#

Step 3: Databinding the Chart to JSON Data

Step 4: Configure the Tornado Chart

Step 5: Finishing Touches

Ready to get started? Download ComponentOne Today!

Step 1: Setting up the Project and Data Source

First, we will create a .NET 10 project in Visual Studio 2026 and set up a JSON data source containing gender population data for several countries.

  1. Create a new WinForms .NET 10 application.
  2. Add a NuGet package reference to C1.Win.FlexChart.
  3. Drag and drop a FlexChart to the form, named flexChart1.
  4. Add this population.json file as a resource to the project.
    a. Set its Build Action to Content.
    b. Set its Copy to Output Directory to Always or Newer.
  5. Add the following code to load and deserialize the JSON file into a collection of objects.
List<CountryPopulation> populationData = new List<CountryPopulation>();
var buildDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var path = Path.Combine(buildDir, "Resources", "Population.json");
var text = File.ReadAllText(path);
populationData = System.Text.Json.JsonSerializer.Deserialize<List<CountryPopulation>>(text);

public class CountryPopulation
{
    public string Name { get; set; }
    public double MalePopulation { get; set; }
    public double FemalePopulation { get; set; }
}

Step 2: Sorting the Data Set in C#

Second, we need to sort the data source to create the tornado chart effect, with the largest values at the top and the smallest at the bottom. This is a key aspect of tornado charts and population pyramids. In .NET programming, sorting is best handled on the data collection and easily supported using the LINQ OrderBy method. In our sample, we want to sort by combined population data for each gender.

// sort data set
populationData = populationData.OrderBy(x => x.MalePopulation + x.FemalePopulation).ToList();

Step 3: Databinding the Chart to JSON Data

Third, we need to configure the data binding for the FlexChart to our JSON dataset. The code below creates two series: one for the male population and one for the female population. The key is to set the DataSource and BindingX properties on the FlexChart and the Binding property on each series.

  • (FlexChart) DataSource: Set this to your data set or collection
  • (FlexChart) BindingX: Set this to the common, shared field to display on the X axis (for bar charts, this will be flipped)
  • (Series) Binding: Set this to the Y value that each series will be bound to

The code below also sets the Chart Type and Header (title).

flexChart1.ChartType = ChartType.Bar;
flexChart1.Header.Content = "Population Pyramid";

// data binding
flexChart1.DataSource = populationData;
flexChart1.BindingX = "Name";

var maleSeries = new C1.Win.Chart.Series();
maleSeries.Name = "Male";
maleSeries.Binding = "MalePopulation";

var femaleSeries = new C1.Win.Chart.Series();
femaleSeries.Name = "Female";
femaleSeries.Binding = "FemalePopulation";

// clear and add series
flexChart1.Series.Clear();
flexChart1.Series.Add(maleSeries);
flexChart1.Series.Add(femaleSeries);

At this point, our chart looks like this:

C# Tornado Chart

Step 4: Configure the Tornado Chart

Next, we need to transform the bar chart into a tornado chart. In FlexChart, this can be accomplished by creating two plot areas (named "left" and "right") and assigning each series to a different plot area using the Series' PlotAreaName property. Note that the left plot area's X axis is reversed to create the mirrored appearance of a tornado.

flexChart1.PlotAreas.Add(new PlotArea { Name = "leftPlot", Column = 0 });
flexChart1.PlotAreas.Add(new PlotArea { Name = "rightPlot", Column = 1 });

var leftAxis = new C1.Win.Chart.Axis();
leftAxis.PlotAreaName = "leftPlot";
leftAxis.Position = Position.Bottom;
leftAxis.Reversed = true;

var rightAxis = new C1.Win.Chart.Axis();
rightAxis.PlotAreaName = "rightPlot";
rightAxis.Position = Position.Bottom;

maleSeries.AxisX = leftAxis;
femaleSeries.AxisX = rightAxis;

Now our chart is starting to take shape! Observe how each series is rendered along its own X axis by creating two separate plot areas.

C# .NET Tornado Chart

Step 5: Finishing Touches

Finally, there are several ways we can further enhance our population pyramid.

  • Replace the axis lines and labels with informative data labels
  • Add a logarithmic scale to the X axes to more clearly contrast the population by gender rather than by country
  • Change the color palette to a custom black and gray scheme

The code below applies these changes to each axis.

flexChart1.AxisY.MajorGrid = false;

maleSeries.DataLabel = new C1.Win.Chart.DataLabel { Content = "{y: #,##0,,M}", Position = LabelPosition.Right };
maleSeries.DataLabel.Style.StrokeColor = Color.White;
leftAxis.AxisLine = false;
leftAxis.Labels = false;
leftAxis.MajorTickMarks = TickMark.None;
leftAxis.LogBase = 10;
leftAxis.Min = 1000000;

femaleSeries.DataLabel = new C1.Win.Chart.DataLabel { Content = "{y: #,##0,,M}", Position = LabelPosition.Left };
femaleSeries.DataLabel.Style.StrokeColor = Color.White;
rightAxis.AxisLine = false;
rightAxis.Labels = false;
rightAxis.MajorTickMarks = TickMark.None;
rightAxis.LogBase = 10;
rightAxis.Min = 1000000;

// custom palette
flexChart1.Palette = Palette.Custom;
flexChart1.CustomPalette = new List<System.Drawing.Brush>();
flexChart1.CustomPalette.Add(new SolidBrush(Color.Black));
flexChart1.CustomPalette.Add(new SolidBrush(Color.Gray));

The final chart is shown below.

WinForms Tornado Chart

Ready to check it out? Download ComponentOne Today!

Conclusion

It's tornado season for your dashboard! By placing one data series on the left and another on the right, it makes differences, imbalances, and distributions immediately obvious at a glance.

In .NET applications, you might expect a specialized chart type for this visualization. But with FlexChart, you don't need one. A tornado chart can be created by cleverly customizing a standard horizontal bar chart using two plot areas, axis formatting, and a few styling tweaks.

You can download a complete sample from GitHub as part of the FlexChartExplorer.

comments powered by Disqus