DEV Community

Cover image for From Data to Insight: Visualizing GDP and Education Budgets with WinUI Scatter Chart
Zahra Sandra Nasaka for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

From Data to Insight: Visualizing GDP and Education Budgets with WinUI Scatter Chart

TL;DR: Use a WinUI Scatter Chart and interactive slider to visualize how countries allocate education spending relative to GDP. This helps developers build dynamic, data-driven dashboards for policy analysis and economic insights.

Welcome to our Chart of the Week Blog Series!

Developers face challenges when visualizing complex economic data like GDP and government spending. Let’s quickly understand the two key terms:

Gross Domestic Product (GDP) is the total monetary value of all goods and services produced within a country over a specific period. It serves as a comprehensive measure of a nation’s economic activity and overall health. A higher GDP often reflects a more productive and prosperous economy, influencing how much a government can invest in public services, including education.

Government education spending refers to the share of a nation’s budget allocated to schools, universities, teacher salaries, infrastructure, and learning programs, reflecting its commitment to human capital and long-term growth.

In this blog series, we’ll show how to build an interactive Syncfusion® WinUI Scatter Chart with Syncfusion® WinUI Slider that compares education investment across countries and years, making data exploration intuitive and insightful.

Scatter Chart

A Scatter Chart plots each data item as a point to show how two variables are related. This chart type is ideal for analyzing large datasets and visually understanding trends or distributions. It helps users discover patterns, clusters, and correlations in the data.

Advantages of Scatter Charts

  • Visualize relationships: Easily show how one variable affects another (e.g., GDP vs. education spending ).
  • Identify clusters: Spot groups of data points that behave similarly, such as countries with similar spending patterns.
  • Highlight outliers: Detect unusual data points.
  • Support multiple series: Compare categories or regions using distinct colors and markers.
  • Interactive insights: Scatter Charts in platforms like WinUI can show extra details when you hover over points and let you zoom or filter the data to explore it more easily.

Use cases of Scatter Charts

  • Policy analysis: Understanding how spending decisions vary across regions.
  • Economic research: Studying relationships between financial indicators.
  • Education planning: Identifying areas that need more investment.
  • Data journalism: Telling stories with clear, visual data comparisons.

Scatter Charts are excellent tools for comparing and analyzing data across countries. In this case, they help reveal patterns and relationships between GDP and government education spending.

Here’s how they help in our case

  • Compare countries side by side: You can easily see how different countries spend on education relative to their economic size.
  • Spot priorities: Some countries may invest heavily in education even with a lower GDP, showing a strong commitment to human development.
  • Find mismatches: Some countries with high GDP might spend less on education, which could raise questions about their national priorities.

The following image illustrates ** ** the Scatter Chart we’re going to create.

Visualizing GDP and government education spending shares using the WinUI Scatter Chart


Visualizing GDP and government education spending shares using the WinUI Scatter Chart

Let’s get started!

Step 1: Gathering the data

To begin building the WinUI Scatter Chart, it’s important to gather the necessary dataset from the link. You can either download a sample CSV file from a reliable source or create your own dataset and embed it within your project.

Step 2: Preparing the data for the chart

The CountryEducationModel class defines the structure of each data item used in the chart, representing education spending data for a country in a specific year.

public class CountryEducationModel
{
    public string? Country { get; set; }
    public string? Region { get; set; }
    public int Year { get; set; }
    public double GDPSpent { get; set; }
    public double GovtSpent { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Next, the EducationExpenditure class acts as a bridge between the data and the chart UI. It loads, filters, and organizes the data based on the selected year, and exposes region-specific collections for binding to the chart.

public class EducationExpenditure : INotifyPropertyChanged
{
    ...
    public Dictionary<string, ObservableCollection<CountryEducationModel>> RegionData { get; } = new()
    {
        { "Asia", new ObservableCollection<CountryEducationModel>() },
        
        { "Oceania", new ObservableCollection<CountryEducationModel>() }
    };

    public ObservableCollection<CountryEducationModel> AsiaData => RegionData["Asia"];
    
    public ObservableCollection<CountryEducationModel> OceaniaData => RegionData["Oceania"];

    ...

    public EducationExpenditure()
    {
        LoadAllData();
        SelectedYear = 2000;
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

Finally, the LoadAllData method reads the CSV file embedded in the project, parses each line, and stores the data in a list. The LoadDataForYear method filters this list based on the selected year and populates region-specific collections.

private void LoadAllData()
{   
 ...
        var assembly = typeof(App).GetTypeInfo().Assembly;
        using var stream = assembly.GetManifestResourceStream("EducationSpendings.Assets.education_spendings.csv");
        if (stream == null) return;

        using var reader = new StreamReader(stream);
        reader.ReadLine(); // Skip header

        while (reader.ReadLine() is string line)
        {
            var parts = line.Split(',').Select(p => p.Trim()).ToArray();
            if (parts.Length >= 5 &&
                int.TryParse(parts[2], out int year) &&
                double.TryParse(parts[3], NumberStyles.Any, CultureInfo.InvariantCulture, out double gdp) &&
                double.TryParse(parts[4], NumberStyles.Any, CultureInfo.InvariantCulture, out double mappingValue))
            {
                completeData.Add(new CountryEducationModel
                {
                    Country = parts[0],
                    Region = parts[1],
                    Year = year,
                    GDPSpent = gdp,
                    GovtSpent = mappingValue
                });
            }
        }
        ...
}

private void LoadDataForYear(int year)
{
    var filtered = completeData.Where(d => d.Year == year).ToList();
        ...
    foreach (var region in RegionData.Keys)
    {
        RegionData[region].Clear();
    }

    foreach (var item in filtered)
    {
        if (!string.IsNullOrEmpty(item.Region) &&
            RegionData.TryGetValue(item.Region, out var regionCollection))
        {
            regionCollection.Add(item);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure the Syncfusion® WinUI Scatter Chart

In this demo, we’ll use two key controls: The Syncfusion® WinUI Scatter Chart and the Syncfusion® WinUI Slider. We’ll define a layout that positions these controls effectively to enhance visual clarity and user interaction.

<Window ><Border Padding="10" Margin="10" BorderThickness="2">

        <Grid Background="#E1E2E4"></Grid>
    </Border>
</Window>
Enter fullscreen mode Exit fullscreen mode

Then, configure the Syncfusion® WinUI Cartesian Charts control using the following documentation.

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

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

           <charts:SfCartesianChart.Series>
               <charts:ScatterSeries/>
           </charts:SfCartesianChart.Series></chart:SfCartesianChart></Window>
Enter fullscreen mode Exit fullscreen mode

Step 4: Binding data to the WinUI Scatter Chart

To display data in the Syncfusion® WinUI Scatter Chart, we bind each chart series to the corresponding data collection in the EducationExpenditure. This ensures that data for each region like Asia, Europe, and Africa, is shown correctly and updates automatically when the selected year changes.

Ensure the EducationExpenditureis set as the DataContext for the chart. This allows the chart to access all the necessary data properties from the EducationExpenditure.

<chart:SfCartesianChart.Series>
    <chart:ScatterSeries ItemsSource="{Binding AsiaData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>

    <chart:ScatterSeries ItemsSource="{Binding NorthAmericaData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>

    <chart:ScatterSeries ItemsSource="{Binding SouthAmericaData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>

    <chart:ScatterSeries ItemsSource="{Binding AfricaData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>

    <chart:ScatterSeries ItemsSource="{Binding EuropeData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>

    <chart:ScatterSeries ItemsSource="{Binding OceaniaData}"
                         XBindingPath="GDPSpent" YBindingPath="GovtSpent"
                         PointHeight="13" PointWidth="13"/>
</chart:SfCartesianChart.Series>
Enter fullscreen mode Exit fullscreen mode

In this example, each ScatterSeries in the chart is bound to a specific region’s data collection from the EducationExpenditure, ensuring that the chart reflects region-specific data dynamically. The XBindingPath is set to GDPSpent and the YBindingPath to GovtSpent, which means the chart uses these properties from the model to plot points along the X and Y axes, respectively. This mapping allows the chart to visualize the relationship between GDP spending and government spending for each region.

Step 5: Configure the WinUI Slider

Let’s add a WinUI Slider to make the chart interactive and user-friendly.

This allows users to select a specific year, and the chart updates instantly to show data for that year.

Configure the Slider in XAML

SfSlider lets users select a value from a range by sliding a thumb along a track. It’s commonly used for filtering data, adjusting settings, or selecting time periods.

Advantages of using SfSlider

  • Interactive: Users can easily select values by dragging.
  • Data Binding: Works smoothly with MVVM patterns.
  • Customizable: Supports styling, tooltips, labels, and dividers.
  • Responsive: Adapts well to different screen sizes and layouts.
  • Visual Feedback: Shows current value clearly, improving user experience.

The slider is added in XAML using the SfSlider control, letting users choose between 2000 and 2024. Its value is bound to the SelectedYear property in the EducationExpenditure with two-way binding, so changes reflect both ways. The slider is styled for better appearance and includes dividers to mark each year’s step.

<slider:SfSlider 
                 
                 Minimum="2000"
                 Maximum="2024"
                 Value="{Binding SelectedYear, Mode=TwoWay}"
                 ShowDividers="True"
                 
                 Margin="10"/>
Enter fullscreen mode Exit fullscreen mode

Connect Slider to EducationExpenditure

In the EducationExpenditure, the SelectedYear property links the slider to the chart. When the user changes the year, the property setter is triggered, which is called LoadDataForYear. This method filters the dataset for the selected year and updates the chart data.

private int _selectedYear;
public int SelectedYear
{
    get => _selectedYear;
    set
    {
        if (_selectedYear != value)
        {
            _selectedYear = value;
            OnPropertyChanged();
            LoadDataForYear(_selectedYear);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Update chart data dynamically

The LoadDataForYear method filters the dataset based on the selected year and updates region-specific collections like AsiaData and EuropeData. These collections are bound to chart series, so the chart refreshes automatically when the data changes.

private void LoadDataForYear(int year)
{
    var filtered = completeData.Where(d => d.Year == year).ToList();
    if (filtered.Any())
    {
        
    }

    AsiaData.Clear();
    EuropeData.Clear();
    AfricaData.Clear();
    NorthAmericaData.Clear();
    SouthAmericaData.Clear();
    OceaniaData.Clear();

    foreach (var item in filtered)
    {
        switch (item.Region)
        {
            case "Asia": AsiaData.Add(item); break;
            case "Europe": EuropeData.Add(item); break;
            case "Africa": AfricaData.Add(item); break;
            case "NorthAmerica": NorthAmericaData.Add(item); break;
            case "SouthAmerica": SouthAmericaData.Add(item); break;
            case "Oceania": OceaniaData.Add(item); break;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Enhancing the chart’s appearance

After setting up the chart and data binding, the next step is to refine its appearance. Customizing the visual elements makes the chart more professional and helps present the data more clearly. The following sections detail the customizations applied to the chart’s title, axes, tooltip, and legend.

Customizing chart header with an icon and title

To make the chart title visually appealing, a TextBlock is placed inside a border, allowing styling such as background color, padding, and font settings. Additionally, an image is included beside the title to enhance visual context and engagement.

<chart:SfCartesianChart.Header>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
        <Image Source="Assets/financial-literacy.png" Width="40" Height="30" Margin="10,3,2,0"/>
        <TextBlock FontSize="20" 
                   Text="Expenditure on education as share of government spending" 
                   VerticalAlignment="Center" 
                   Foreground="#333333" 
                   FontWeight="SemiBold" 
                   Margin="0,0,5,0"/>
    </StackPanel>
</chart:SfCartesianChart.Header>
Enter fullscreen mode Exit fullscreen mode

Customizing the chart axes

To make the chart more readable and visually appealing, the X and Y axes are customized using styles defined in the chart’s resources. These styles include dashed black grid lines and solid black axis lines, which help distinguish the chart’s layout clearly. The X-axis also consists of a descriptive header that explains the data being shown, specifically, the total expenditure on education as a percentage of GDP.

Both axes display their labels in percentage format to make the values easier to understand. By defining these styles once and applying them to both axes, the chart maintains a consistent and professional look while improving clarity for users.

<chart:SfCartesianChart.Resources>
    <Style TargetType="Line" x:Key="xDashedGridLineStyle">
        <Setter Property="Stroke" Value="Black"/>
        <Setter Property="StrokeThickness" Value="1"/>
        <Setter Property="StrokeDashArray" Value="4,2"/>
    </Style>

    <Style TargetType="Line" x:Key="yDashedGridLineStyle">
        <Setter Property="Stroke" Value="Black"/>
        <Setter Property="StrokeThickness" Value="1"/>
        <Setter Property="StrokeDashArray" Value="4,2"/>
    </Style>

    <Style TargetType="Line" x:Key="xAxisLineStyle">
        <Setter Property="StrokeThickness" Value="1"/>
        <Setter Property="Stroke" Value="Black"/>
    </Style>

    <Style TargetType="Line" x:Key="yAxisLineStyle">
        <Setter Property="StrokeThickness" Value="1"/>
        <Setter Property="Stroke" Value="Black"/>
    </Style>

    <DataTemplate x:Key="headerTemplate">
        <TextBlock Text="Total across all levels of education (% of GDP)" FontSize="15" FontWeight="Medium" Margin="3"/>
    </DataTemplate>
    ...
</chart:SfCartesianChart.Resources>

<!-- X and Y Axes Customization -->
<chart:SfCartesianChart.XAxes>
    <chart:NumericalAxis Minimum="0" 
                         Maximum="{Binding XAxisMax}" 
                         Interval="2"
                         HeaderTemplate="{StaticResource headerTemplate}"
                         MajorTickStyle="{StaticResource xAxisLineStyle}"
                         MajorGridLineStyle="{StaticResource xDashedGridLineStyle}">
        <chart:NumericalAxis.LabelStyle>
            <chart:LabelStyle LabelFormat="##0'%'"/>
        </chart:NumericalAxis.LabelStyle>
    </chart:NumericalAxis>
</chart:SfCartesianChart.XAxes>

<chart:SfCartesianChart.YAxes>
    <chart:NumericalAxis Minimum="0" 
                         Maximum="{Binding YAxisMax}" 
                         Interval="5"
                         MajorTickStyle="{StaticResource yAxisLineStyle}"
                         MajorGridLineStyle="{StaticResource yDashedGridLineStyle}">
        <chart:NumericalAxis.LabelStyle>
            <chart:LabelStyle LabelFormat="##0'%'"/>
        </chart:NumericalAxis.LabelStyle>
    </chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
Enter fullscreen mode Exit fullscreen mode

Styling the legend

A chart legend acts as a key to help viewers understand the data being presented. It maps the visual elements of the chart, such as colors, shapes, or patterns, to the specific data series they represent. For any chart that displays multiple series, a legend is essential for clarity and accurate to read and interpret the data correctly.

Note: For more in-depth information, you can refer to the official documentation.

The legend is styled and made dynamic by binding its header to a EducationExpenditure property. It also uses LegendIcon with rectangle icons to clearly show which color represents each data series, making the chart easier to understand.

...
<chart:SfCartesianChart.Legend>
    <chart:ChartLegend Placement="Right" ItemMargin="50,0,0,0">
        <chart:ChartLegend.Header>
            <TextBlock Text="Education Spending by Region" 
                       TextWrapping="Wrap" 
                       FontSize="15" 
                       FontWeight="Bold"/>
        </chart:ChartLegend.Header>
    </chart:ChartLegend>
...
<chart:ScatterSeries LegendIcon="Rectangle" ... />
...
</chart:SfCartesianChart.Legend>
...
Enter fullscreen mode Exit fullscreen mode

Customizing the tooltip

The tooltip shows extra details when you hover over a chart point. It has a black background with white text for clear visibility. It displays the country name at the top, followed by education and government spending values, which are neatly rounded using a converter. This helps users quickly understand the data in a clean and simple format.

...
<!-- Tooltip Template -->
<DataTemplate x:Key="customTooltipTemplate">
    <StackPanel Background="Black" MaxWidth="180" Padding="5">

        <!-- Country Name -->
        <TextBlock Text="{Binding Item.Country}" 
                   FontWeight="ExtraBold" 
                   FontSize="14" Foreground="White" 
                   TextWrapping="Wrap" 
                   HorizontalAlignment="Center"/>

        <Line Stretch="Fill" X2="1" Stroke="White" StrokeThickness="1" Margin="0,2,0,2"/>

        <!-- Education Spending -->
        <TextBlock FontSize="12" FontWeight="SemiBold" Foreground="White" Margin="0,2,0,2">
            <Run Text="Education (% of GDP): " />
            <Run Text="{Binding Item.GDPSpent, Converter={StaticResource RoundConverter}}" />
            <Run Text="%" />
        </TextBlock>

        <!-- Government Spending -->
        <TextBlock FontSize="12" FontWeight="SemiBold" Foreground="White" Margin="0,2,0,2">
            <Run Text="Govt Spending Share: " />
            <Run Text="{Binding Item.GovtSpent, Converter={StaticResource RoundConverter}}"/>
            <Run Text="%" />
        </TextBlock>
    </StackPanel>
</DataTemplate>
...
Enter fullscreen mode Exit fullscreen mode

After executing the previous code examples, we will get the output that resembles the following image.

Visualizing GDP and government education spending shares using the WinUI Scatter Chart


Visualizing GDP and government education spending shares using the WinUI Scatter Chart

GitHub reference

For more details, refer to the GitHub demo.

Conclusion

Thanks for reading! In this blog, we’ve seen how to use the Syncfusion® WinUI Scatter Chart to visualize government spending on education across different regions. With features like a year-based slider, custom styling, and interactive tooltips, the chart offers a clear and engaging way to explore the data. We encourage you to try the steps and share your thoughts in the comments 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 out our incredible features.

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

Related Blogs

This article was originally published at Syncfusion.com.

Top comments (0)