Chart of the Week: Creating a Doughnut Chart for the World’s Top Coffee-Producing Countries
Tags: dotnetmaui, charts, mobile, desktop
Published: 2023-07-24 06:53:04

---
title: Chart of the Week: Creating a Doughnut Chart for the World’s Top Coffee-Producing Countries
published: true
date: 2023-07-20 14:25:35 UTC
tags: dotnetmaui, charts, mobile, desktop
canonical_url: https://www.syncfusion.com/blogs/post/dotnet-maui-doughnut-chart-visualize-coffee-production.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipib7i1u0v6fj4tn7yip.png
---
Welcome to the **Chart of the Week** blog series!

Today, we will visualize the top coffee-producing countries worldwide with the help of the Syncfusion [.NET MAUI doughnut chart](https://www.syncfusion.com/maui-controls/maui-circular-charts/chart-types/maui-doughnut-chart ".NET MAUI Doughnut Chart"). This control is supported on both desktop (Windows and MacCatalyst) and mobile platforms (Android and iOS).

The world coffee production in 2020 was 5.3 million bags, lower than the previous year due to Brazil’s Arabica trees entering the off year of their biennial production cycle.

Refer to the following image, which explains the top coffee-producing countries and their production in 2020. ![Visualizing Top Coffee-Producing Countries’ Data Using the Syncfusion .NET MAUI Doughnut Chart](https://www.syncfusion.com/blogs/wp-content/uploads/2023/07/Visualizing-Top-Coffee-Producing-Countries-Data-Using-the-Syncfusion-.NET-MAUI-Doughnut-Chart-4.gif)

In this blog, we’ll replicate this chart using the Syncfusion [.NET MAUI doughnut chart](https://help.syncfusion.com/maui/circular-charts/doughnutchart "Getting started with .NET MAUI Doughnut Chart") control.

## Step 1: Gather coffee production data

Before creating a chart, we need to gather the data on coffee production from the [International Coffee Organization](https://www.ico.org/prices/po-production.pdf "International Coffee Organization Report"). For this demonstration, we obtain data on the countries involved, production amount in millions, and market share percentages. You can save the data in CSV format.

## Step 2: Prepare the data for the doughnut chart

Define the **CoffeeProductionModel** class with the properties **Country** , **Production** , **MarketShare,** and **Index** to hold the coffee production details.

Refer to the following code example.

```csharp
public class CoffeeProductionModel
{
    public string Country { get; set; }
    public double Production { get; set; }
    public double MarketShare { get; set; }
    public double Index { get; set; }

    public CoffeeProductionModel(double index, string country, double production, double marketShare)
    {
        Index = index;
        Country = country;
        Production = production;
        MarketShare = marketShare;
    }
}
```

Next, generate the production details using the **WorldCoffeeProduction** class and **ProductionDetails** property. Convert the CSV data to a collection of countries and production amounts using the **ReadCSV** method and store it in the **ProductionDetails** property.

Additionally, the selection properties need an interactive feature. In the interactive feature section, we will cover more about this.

Refer to the following code example.

```csharp
public class WorldCoffeeProduction : INotifyPropertyChanged
{

    List<CoffeeProductionModel> productionDetails;
    public List<Brush> PaletteBrushes { get; set; }
    public List<Brush> SelectionBrushes { get; set; }

    public List<CoffeeProductionModel> ProductionDetails
    {
       get
       {
          return productionDetails;
       }
       set
       {
          productionDetails = value;
          NotifyPropertyChanged(nameof(ProductionDetails));
       }
    }

    private Brush selectionBrush;
    public Brush SelectionBrush
    {
        get
        {
           return selectionBrush;
        }
        set
        {
           selectionBrush = value;

           NotifyPropertyChanged(nameof(SelectionBrush));
        }
    }

    private string country;
    public string Country
    {
       get
       {
          return country;
       }
       set
       {
                country = value;
                NotifyPropertyChanged(nameof(Country));
       }
    }

    private double Production;
    public double Production
    {
       get
       {
          return production;
       }
       set
       {
          production = value;
          NotifyPropertyChanged(nameof(Production));
       }
     }

     private double Percentage;
     public double Percentage
     {
        get
        {
           return percentage;
        }
        set
        {
           percentage = value;
           NotifyPropertyChanged(nameof(Percentage));
        }

      }

      private int selectedIndex = 0;
      public int SelectedIndex
      {
         get
         {
            return selectedIndex;
         }
         set
         {
            selectedIndex = value;
            SelectionBrush = SelectionBrushes[SelectedIndex];
            UpdateIndex(value);
            NotifyPropertyChanged(nameof(SelectedIndex));
          }
       }

       private double groupTo = 7;
       public double GroupTo
       {
           get { return groupTo; }
           set { groupTo = value; }
       }

       public WorldCoffeeProduction()
       {
          ProductionDetails = new List<CoffeeProductionModel>(ReadCSV());

          PaletteBrushes = new List<Brush>
          {
              new SolidColorBrush(Color.FromArgb("#5bdffc")),
              new SolidColorBrush(Color.FromArgb("#2fe0d0")),
              new SolidColorBrush(Color.FromArgb("#baf74d")),
              new SolidColorBrush(Color.FromArgb("#f5d949")),
              new SolidColorBrush(Color.FromArgb("#f2464d")),
              new SolidColorBrush(Color.FromArgb("#c86af7"))
           };

           SelectionBrushes = new List<Brush>
           {
              new SolidColorBrush(Color.FromArgb("#00b1d9")),
              new SolidColorBrush(Color.FromArgb("#05b3a2")),
              new SolidColorBrush(Color.FromArgb("#8ccf15")),
              new SolidColorBrush(Color.FromArgb("#d9b709")),
              new SolidColorBrush(Color.FromArgb("#d40b13")),
              new SolidColorBrush(Color.FromArgb("#9e07e3"))
           };
        }

        public IEnumerable<CoffeeProductionModel> ReadCSV()
        {
            Assembly executingAssembly = typeof(App).GetTypeInfo().Assembly;
            Stream inputStream = executingAssembly.GetManifestResourceStream("CoffeeProductionChart.Resources.Raw.coffeproductionbycountry.csv");

            string? line;
            List<string> lines = new List<string>();

            using StreamReader reader = new StreamReader(inputStream);
            while ((line = reader.ReadLine()) != null)
            {
                lines.Add(line);
            }

            return lines.Select(line =>
            {
                string[] data = line.Split(',');
                return new CoffeeProductionModel(Convert.ToDouble(data[0]), data[1], Convert.ToDouble(data[2]), Convert.ToDouble(data[3]));
            });
        }

        private void UpdateIndex(int value)
        {
            if (value >= 0 && value < ProductionDetails.Count)
            {
                var model = ProductionDetails[value];
                if (model != null && model.Country != null)
                {
                    if (model.Production < GroupTo)
                    {
                        Production = 0;
                        Percentage = 0;
                        Country = "";
                        foreach (var item in productionDetails)
                        {
                            if (GroupTo > item.Production)
                            {
                                Country = "Others";
                                Production += item.Production;
                                Percentage += item.MarketShare;
                            }
                        }
                    }
                    else
                    {
                        Country = model.Country;
                        Production = model.Production;
                        Percentage = model.MarketShare;
                    }
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
}
```

## Step 3: Configure the Syncfusion .NET MAUI Circular Charts

Let’s configure the [Syncfusion .NET MAUI Circular Charts](https://help.syncfusion.com/maui/circular-charts/getting-started "Getting started with .NET MAUI Circular Charts") control.

Refer to the following code example.

```xml
<chart:SfCircularChart >
</chart:SfCircularChart>
```

## Step 4: Binding coffee production data

To bind the coffee production data, we’ll use the Syncfusion [DoughnutSeries](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.DoughnutSeries.html "DoughnutSeries Class of .NET MAUI Circular Charts") class.

```xml
<chart:DoughnutSeries x:Name="series" ItemsSource="{Binding ProductionDetails}" XBindingPath="Country" YBindingPath="Production">
</chart:DoughnutSeries>
```

In this example, we’ve bound the **ProductionDetails** with the **ItemSource** property. The **XBindingPath** and **YBindingPath** are bound with the **Country** and **Production** properties, respectively.

## Step 5: Customizing the chart appearance

We can customize the doughnut chart’s appearance by customizing the doughnut segment colors, showing data labels, adding a title to the chart, and more.

Refer to the following code example to customize the doughnut chart title using the [Title](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartBase.html#Syncfusion_Maui_Charts_ChartBase_Title "Title property of .NET MAUI Charts") property in the [SfCircularChart](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.SfCircularChart.html "SfCircularChart Class of .NET MAUI Charts").

```xml
<chart:SfCircularChart.Title>
 <Border Background="#443c8f" StrokeThickness="1" Margin="0">
  <VerticalStackLayout>
   <Grid Padding="4">
    <Grid.ColumnDefinitions>
     <ColumnDefinition Width="34"/>
     <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <StackLayout Margin="0,0,0,0" VerticalOptions="Start" Orientation="Vertical">
     <Path Fill="White" HorizontalOptions="CenterAndExpand" VerticalOptions="Center" TranslationX="0.5" ScaleY="1.1" TranslationY="0.5" Data="{Binding PathData}"></Path>
    </StackLayout>
    <StackLayout Grid.Column="1" Margin="5,0,0,0" VerticalOptions="Center" HorizontalOptions="Start" Orientation="Vertical">
     <Label Text="The World's Top Coffee-Producing Countries" FontSize="22" FontAttributes="Bold" TextColor="white"/>
    </StackLayout>
   </Grid>
  </VerticalStackLayout>
 </Border>
</chart:SfCircularChart.Title>
```

Let’s configure the [chart legend](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartBase.html#Syncfusion_Maui_Charts_ChartBase_Legend "Legend property of .NET MAUI Charts") using the [ItemTemplate](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartLegend.html#Syncfusion_Maui_Charts_ChartLegend_ItemTemplate "ItemTemplate property of .NET MAUI Charts") property and position the legend items using the [Placement](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartLegend.html#Syncfusion_Maui_Charts_ChartLegend_Placement "Placement property of .NET MAUI Charts") property.

```xml
<chart:SfCircularChart.Legend>
 <chart:ChartLegend x:Name="chartLegend" Placement="Right" >
  <chart:ChartLegend.ItemTemplate>
   <DataTemplate>
    <StackLayout WidthRequest="{OnPlatform WinUI='150', Android='90',iOS='90',MacCatalyst='140'}" Margin="0,0,80,0" Orientation="Horizontal">
     <Ellipse WidthRequest="15" HeightRequest="15" Fill="{Binding IconBrush}" HorizontalOptions="Center" VerticalOptions="Center" />
     <Label FontSize="{OnPlatform WinUI='15', Android='13',MacCatalyst='15',iOS='13'}" Margin="5,0,0,0" FontAttributes="Bold" Text="{Binding Item,Converter={StaticResource legend}}" VerticalTextAlignment="Start" HorizontalTextAlignment="Start" />
    </StackLayout>
   </DataTemplate>
  </chart:ChartLegend.ItemTemplate>
 </chart:ChartLegend>
</chart:SfCircularChart.Legend>

```

Then, we customize the doughnut segment color, border, and width and group the data points less than the specific value using the [PaletteBrushes](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartSeries.html#Syncfusion_Maui_Charts_ChartSeries_PaletteBrushes "PaletteBrushes property of .NET MAUI Charts"), [Stroke](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.CircularSeries.html#Syncfusion_Maui_Charts_CircularSeries_Stroke "Stroke property of .NET MAUI Charts"), [StrokeWidth](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.CircularSeries.html#Syncfusion_Maui_Charts_CircularSeries_StrokeWidth "StrokeWidth property of .NET MAUI Charts"), and [GroupTo](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.PieSeries.html#Syncfusion_Maui_Charts_PieSeries_GroupTo "GroupTo property of .NET MAUI Charts") properties, respectively.

We can also modify the start and end positions of a segment in the chart using the [StartAngle](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.CircularSeries.html#Syncfusion_Maui_Charts_CircularSeries_StartAngle "StartAngle property of .NET MAUI Charts") and [EndAngle](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.CircularSeries.html#Syncfusion_Maui_Charts_CircularSeries_EndAngle "EndAngle property of .NET MAUI Charts") properties.

```xml
<chart:DoughnutSeries ShowDataLabels="True" x:Name="series" StartAngle="270" EndAngle="630"
           PaletteBrushes="{Binding PaletteBrushes}"
           ItemsSource="{Binding ProductionDetails}" GroupTo="{Binding GroupTo}"      
           XBindingPath="Country" Stroke="white" StrokeWidth="1"                                    
           YBindingPath="Production">
</chart:DoughnutSeries>
```

Configure the [CenterView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.DoughnutSeries.html#Syncfusion_Maui_Charts_DoughnutSeries_CenterView "CenterView property of .NET MAUI Charts") property to add information about coffee production. You can define the size of the center view using the [InnerRadius](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.DoughnutSeries.html#Syncfusion_Maui_Charts_DoughnutSeries_InnerRadius "InnerRadius property of .NET MAUI Charts") property of the doughnut series. The [CenterHoleSize](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.DoughnutSeries.html#Syncfusion_Maui_Charts_DoughnutSeries_CenterHoleSize "CenterHoleSize property of .NET MAUI Charts") property is used to prevent overlapping among the doughnut chart segments and center.

```xml
<chart:DoughnutSeries.CenterView>
 <StackLayout x:Name="layout" HeightRequest="{Binding CenterHoleSize}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" WidthRequest="{Binding CenterHoleSize}">
  <Label Text="Percent of" FontSize="{OnPlatform WinUI='13',Android='9',iOS='10',MacCatalyst='13'}" VerticalTextAlignment="Center" HorizontalOptions="Center" VerticalOptions="EndAndExpand" Margin="{OnPlatform WinUI='0',Android='5',MacCatalyst='10',iOS='5'}"/>
  <Label Text="Coffee Produced" FontSize="{OnPlatform WinUI='13',Android='9',iOS='10',MacCatalyst='13'}" VerticalOptions="StartAndExpand" Margin="0" HorizontalOptions="Center" />
  <Label Text="{Binding Percentage,Source={x:Reference coffeeProduction},StringFormat='{0:P0}'}" FontAttributes="Bold" FontSize="{OnPlatform WinUI='15',Android='9',iOS='12',MacCatalyst='14'}" HorizontalOptions="Center" VerticalOptions="StartAndExpand" Margin="{OnPlatform Android='0',iOS='0',Default='0,-20,0,0'}"/>
 </StackLayout>
</chart:DoughnutSeries.CenterView>

```

We can customize the data labels in the chart using the [DataLabelSettings](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.CircularSeries.html#Syncfusion_Maui_Charts_CircularSeries_DataLabelSettings "DataLabelSettings property of .NET MAUI Charts") property. Use the [LabelPlacement](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartDataLabelSettings.html#Syncfusion_Maui_Charts_ChartDataLabelSettings_LabelPlacement "LabelPlacement property of .NET MAUI Charts") property to place the data labels at the desired position. Modify the label style with an appropriate format using [LabelFormat](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartLabelStyle.html#Syncfusion_Maui_Charts_ChartLabelStyle_LabelFormat "LabelFormat property of .NET MAUI Charts") property.

We should enable the [ShowDataLabels](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartSeries.html#Syncfusion_Maui_Charts_ChartSeries_ShowDataLabels "ShowDataLabels property of .NET MAUI Charts") property in the doughnut series to display the data labels.

```xml
<chart:DoughnutSeries.DataLabelSettings>
 <chart:CircularDataLabelSettings UseSeriesPalette="True" LabelPlacement="Outer">
  <chart:CircularDataLabelSettings.LabelStyle>
   <chart:ChartDataLabelStyle LabelFormat="###.#M" />
  </chart:CircularDataLabelSettings.LabelStyle>
 </chart:CircularDataLabelSettings>
</chart:DoughnutSeries.DataLabelSettings>
```

## Step 6: Add interactivity feature

We can add interactive features to view the data for the selected segment in our chart using the [SelectionBehavior](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartSeries.html#Syncfusion_Maui_Charts_ChartSeries_SelectionBehavior "SelectionBehavior property of .NET MAUI Charts") property.

The selection features can highlight a specific data point, raise an event, or modify the value of the [SelectedIndex](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartSelectionBehavior.html#Syncfusion_Maui_Charts_ChartSelectionBehavior_SelectedIndex "SelectedIndex property of .NET MAUI Charts") property based on the segment selection. The [SelectionBrush](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartSelectionBehavior.html#Syncfusion_Maui_Charts_ChartSelectionBehavior_SelectionBrush "SelectionBrush property of .NET MAUI Charts") property is used to highlight the selected segment in the chart.

Here, we’ll bind the **SelectedIndex** to the series center view to show additional information about the data. Refer to the following code example.

```xml
<chart:DoughnutSeries.SelectionBehavior>
 <chart:DataPointSelectionBehavior SelectionBrush="{Binding SelectionBrush}" SelectedIndex="{Binding SelectedIndex,Mode=TwoWay}" />
</chart:DoughnutSeries.SelectionBehavior>

```

After executing the previous code example, we’ll get output like in the following image.
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/07/Visualizing-Top-Coffee-Producing-Countries-Data-Using-the-Syncfusion-.NET-MAUI-Doughnut-Chart-4.gif" alt="Visualizing Top Coffee-Producing Countries’ Data Using the Syncfusion .NET MAUI Doughnut Chart" style="width:100%">

  <figcaption>Visualizing Top Coffee-Producing Countries’ Data Using the Syncfusion .NET MAUI Doughnut Chart</figcaption>

</figure>

## GitHub reference

For more details, refer to the[GitHub demo](https://github.com/SyncfusionExamples/How-to-visualize-the-worlds-top-coffee-producing-countries-in-2020-using-a-Doughnut-Chart "Creating a Doughnut Chart for the World's Top Coffee Producing Countries in 2020 GitHub demo").

## Conclusion

Thanks for reading! In this blog, we’ve seen how to visualize the world’s top coffee-producing countries using the [Syncfusion .NET MAUI doughnut chart](https://help.syncfusion.com/maui/circular-charts/doughnutchart "Getting started with .NET MAUI Doughnut Chart"). Like this, you can also visualize other trends and changes worldwide. We encourage you to try the steps discussed and share your thoughts in the comments section below.

You can also reach us via our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback "Syncfusion Feedback Portal"). We are always eager to help you!

## Related blogs

- [Introducing the New .NET MAUI Expander Control](https://www.syncfusion.com/blogs/post/new-dotnet-maui-expander-control.aspx "Blog: Introducing the New .NET MAUI Expander Control")
- [Unveiling the Cutting-Edge .NET MAUI Chips Control](https://www.syncfusion.com/blogs/post/new-dotnet-maui-chips-control.aspx "Blog: Unveiling the Cutting-Edge .NET MAUI Chips Control")
- [Chart of the Week: Creating .NET MAUI Area Chart for US Tech Companies Adopting Dual-Class Voting Structures](https://www.syncfusion.com/blogs/post/dotnet-maui-area-chart-visualize-us-companies-adopting-dual-class-voting.aspx "Blog: Chart of the Week: Creating .NET MAUI Area Chart for US Tech Companies Adopting Dual-Class Voting Structures")
- [Introducing the New .NET MAUI Numeric Entry Control](https://www.syncfusion.com/blogs/post/dotnet-maui-numeric-entry.aspx "Blog: Introducing the New .NET MAUI Numeric Entry Control")