TL;DR: Let’s see how to visualize skyscraper data with Syncfusion .NET MAUI Semi-Doughnut Chart and Maps controls. We’ll gather data, create a semi-doughnut chart with a center view by adding Maps control, and customize visuals like angles, colors, and interactive features. Enhance your app with geographic context and dynamic data visualization for a richer user experience.
Welcome to the Chart of the Week blog series!
Data visualization is an essential part of modern applications, and combining charts with maps can elevate the user experience by providing geographic context to your data.
In this blog, we’ll explore how to create a Semi-Doughnut Chart with integrated Maps using the Syncfusion .NET MAUI Circular Charts and Maps controls.
Understanding Doughnut Charts and Maps
The Circular Chart is a versatile control representing data in a circular format. A semi-doughnut chart presents data in a semi-circle, ideal for scenarios where screen space is limited or when combining charts with other visual elements.
The Maps control allows us to integrate rich geographic data visualizations into your .NET MAUI apps. You can add layers, markers, and shapes to create dynamic maps that perfectly complement your chart data.
Visualizing skyscraper data in urban landscapes
In today’s urban landscape, skyscrapers symbolize innovation, architectural prowess, and economic strength. To highlight cities with the most skyscrapers, we use .NET MAUI to create an interactive doughnut chart paired with maps. This integration not only emphasizes statistical data but also provides geographic context, grasping insights immediately.
The following image shows the semi-doughnut chart that we intend to create.
Let’s explore the steps involved in analyzing the details of the top 10 cities with the most skyscrapers!
Step 1: Gathering data for the chart
To begin, we need to gather data for the chart. We’ll refer to Wikipedia, which offers comprehensive information on cities with the most skyscrapers.
Step 2: Prepare the data for the chart
Next, define a SkyscrapersModel class to encapsulate information about each country, city, and the number of skyscrapers. This model ensures that the information is well-organized and easily accessible for visualization.
By representing each record with a dedicated class, you can seamlessly bind data to both the Doughnut Chart and Maps.
Refer to the following code example:
public class SkysCrapersModel
{
public string? City { get; set; }
public string? Country { get; set; }
public int Count { get; set; }
}
Now, create a SkysCrapersData class to manage the collection of skyscraper details. This SkysCrapersData will serve as the intermediary between your data and the user interface, facilitating data binding.
Refer to the following code example:
public class SkysCrapersData : INotifyPropertyChanged
{
public ObservableCollection<SkysCrapersModel> Data { get; set; }
public SkysCrapersData()
{
Data = new ObservableCollection<SkysCrapersModel>
{
new SkysCrapersModel { City = "Hong-Kong", Country = "Hong Kong", Count = 558 },
new SkysCrapersModel { City = "Shenzhen", Country = "China", Count = 415 },
new SkysCrapersModel { City = "New York", Country = "US", Count = 318 },
new SkysCrapersModel { City = "Dubai", Country = "UAE", Count = 263 },
new SkysCrapersModel { City = "Guangzhou", Country = "China", Count = 194 },
new SkysCrapersModel { City = "Shanghai", Country = "China", Count = 194 },
new SkysCrapersModel { City = "Kuala Lumpur", Country = "Malaysia", Count = 179 },
new SkysCrapersModel { City = "Tokyo", Country = "Japan", Count = 176 },
new SkysCrapersModel { City = "Wuhan", Country = "China", Count = 169 },
new SkysCrapersModel { City = "Chongqing", Country = "China", Count = 145 },
};
}
}
Step 3: Configure the Syncfusion .NET MAUI Circular Charts
Let’s configure the Syncfusion .NET MAUI Circular Charts control using this documentation.
Refer to the following code example.
<Grid>
<chart:SfCircularChart>
</chart:SfCircularChart>
</Grid>
Step 4: Bind the data to the .NET MAUI Doughnut Chart
Let’s bind the data to the .NET MAUI DoughnutSeries to visualize the top 10 cities for skyscrapers.
<chart:SfCircularChart>
<chart:DoughnutSeries
x:Name="series"
ItemsSource="{Binding Data}"
XBindingPath="City"
YBindingPath="Count">
</chart:DoughnutSeries>
</chart:SfCircularChart>
Step 5: Customizing the chart appearance
Let’s enhance the aesthetics and readability of the .NET MAUI Semi-Doughnut Chart by customizing its elements, like title, series, interaction features, and center view.
Adding the chart title
Adding a title is simple and intuitive. It helps users understand the content of the chart more effectively. Refer to the following code example to customize the chart title.
<chart:SfCircularChart.Title>
<StackLayout HorizontalOptions="Center" Orientation="Horizontal" Margin="0,10,0,20">
<Path Data="{StaticResource PathData}"
Stroke="#666666"
VerticalOptions="Center"
HorizontalOptions="Start" />
<Label Text="Top 10 Cities with the Most Skyscrapers"
FontSize="{OnPlatform Android=16, iOS=16, Default=20}"
VerticalTextAlignment="Center"
Margin="5,0,0,0"
FontAttributes="Bold"
TextColor="#666666"
LineBreakMode="WordWrap"/>
</StackLayout>
</chart:SfCircularChart.Title>
Customize the Doughnut Chart angle, color, and size
Refer to the following example code to customize the chart’s size, angle, and color using the Radius, InnerRadius, StartAngle, EndAngle, and PaletteBrushes properties.
XAML
<chart:DoughnutSeries
StartAngle="150"
EndAngle="390"
PaletteBrushes="{Binding CustomBrushes}"
Radius="0.9"
InnerRadius="0.75"
ExplodeRadius="15">
</chart:DoughnutSeries>
C#
public class SkysCrapersData : INotifyPropertyChanged
{
public ObservableCollection<Brush> CustomBrushes { get; set; }
public SkysCrapersData()
{
CustomBrushes = new ObservableCollection<Brush>()
{
new SolidColorBrush(Color.FromArgb("#9e0142")),
new SolidColorBrush(Color.FromArgb("#d53e4f")),
new SolidColorBrush(Color.FromArgb("#f46d43")),
new SolidColorBrush(Color.FromArgb("#fdae61")),
new SolidColorBrush(Color.FromArgb("#fee08b")),
new SolidColorBrush(Color.FromArgb("#e6f598")),
new SolidColorBrush(Color.FromArgb("#abdda4")),
new SolidColorBrush(Color.FromArgb("#66c2a5")),
new SolidColorBrush(Color.FromArgb("#3288bd")),
new SolidColorBrush(Color.FromArgb("#5e4fa2")),
};
}
}
Adding a center view and interactivity support to the chart
Now, configure the CenterView property of the DoughnutSeries to add any view to the center of the chart. This feature helps us to provide additional information about the data represented.
In this example, we’ll add the SfMaps control at the center of the chart and enable the explode interactivity feature to make it more engaging and visually appealing.
The .NET MAUI Maps control is a powerful data visualization control for displaying statistical information over a geographical area. It offers highly interactive and customizable features like selection, tooltips, legends, markers, bubbles, and color mapping. With Maps control, you can visualize population density, sales, political boundaries, weather patterns, election results, routes, and more.
Refer to the following code example. Here, we’ll highlight the major cities with the most skyscrapers by placing a custom marker on the map when a chart segment explodes. Additionally, we’ll display the corresponding country name and the skyscraper count in the bottom area of the chart.
<Grid>
<chart:SfCircularChart>
<chart:DoughnutSeries
ExplodeOnTouch="True"
ExplodeIndex="{Binding SelectedIndex, Mode=TwoWay}">
<chart:DoughnutSeries.CenterView>
<Border
x:Name="border"
HeightRequest="{Binding CenterHoleSize}"
WidthRequest="{Binding CenterHoleSize}"
BackgroundColor="Transparent"
Stroke="Transparent"
Padding="20,0,20,0">
<Border.StrokeShape>
<RoundRectangle
CornerRadius="{Binding CenterHoleSize, Converter={StaticResource innerRadiusConverter}, Source={x:Reference series}}" />
</Border.StrokeShape>
<maps:SfMaps>
<maps:SfMaps.Layer>
<maps:MapShapeLayer
ShapesSource="https://cdn.syncfusion.com/maps/map-data/world-map.json"
ShapeStroke="#888888"
ShapeFill="#e7e7e7"
Markers="{Binding MapMarkerCollection, Source={x:Reference viewModel}}">
<maps:MapShapeLayer.MarkerTemplate>
<DataTemplate>
<StackLayout HorizontalOptions="Center">
<Image Source="map_pin.png" HeightRequest="30" WidthRequest="30" />
<Label
Text="{Binding SelectedCityName, Source={x:Reference viewModel}}"
HorizontalTextAlignment="Center"
FontSize="10"
FontAttributes="Bold" />
</StackLayout>
</DataTemplate>
</maps:MapShapeLayer.MarkerTemplate>
</maps:MapShapeLayer>
</maps:SfMaps.Layer>
</maps:SfMaps>
</Border>
</chart:DoughnutSeries.CenterView>
</chart:DoughnutSeries>
</chart:SfCircularChart>
<Border
HorizontalOptions="Center"
Padding="10"
VerticalOptions="End"
Margin="{OnPlatform WinUI='0,-20,0,20', MacCatalyst='0,-20,0,40', Default='0,-40,0,40'}"
Stroke="Black"
WidthRequest="150"
StrokeShape="RoundRectangle 10">
<StackLayout HorizontalOptions="Center">
<StackLayout Grid.Row="0" Orientation="Horizontal" Spacing="10">
<Image Source="{Binding SelectedCityImage}" WidthRequest="25" HeightRequest="25" />
<Label Text="{Binding SelectedCountryName}" FontSize="16" TextColor="Black" />
</StackLayout>
<Label
Text="{Binding SelectedCityCount}"
Margin="40,0,0,0"
FontSize="15"
FontAttributes="Bold"
TextColor="Black" />
</StackLayout>
</Border>
</Grid>
To achieve this, we’ve defined the following properties in the SkysCrapersData class:
- SelectedIndex: Stores the index of the exploded chart segment.
- SelectedCityImage: Displays the image of the selected city.
- SelectedCityName: Represents the name of the selected city.
- SelectedCityCount: Shows the skyscraper count for the selected city.
- SelectedCountryName: Displays the name of the country.
- MapMarkerCollection: Holds the markers to display on the map, highlighting the cities with the most skyscrapers.
Refer to the following code example.
public class SkysCrapersData : INotifyPropertyChanged
{
private int _selectedIndex;
public int SelectedIndex
{
get => _selectedIndex;
set
{
if (_selectedIndex != value)
{
_selectedIndex = value;
UpdateIndex();
OnPropertyChanged(nameof(SelectedIndex));
}
}
}
private string? _selectedCityImage;
public string? SelectedCityImage
{
get => _selectedCityImage;
set
{
_selectedCityImage = value;
OnPropertyChanged(nameof(SelectedCityImage));
}
}
private string? _selectedCityName;
public string? SelectedCityName
{
get => _selectedCityName;
set
{
_selectedCityName = value;
OnPropertyChanged(nameof(SelectedCityName));
}
}
private string? _selectedCountryName;
public string? SelectedCountryName
{
get => _selectedCountryName;
set
{
_selectedCountryName = value;
OnPropertyChanged(nameof(SelectedCountryName));
}
}
private int _selectedCityCount;
public int SelectedCityCount
{
get => _selectedCityCount;
set
{
_selectedCityCount = value;
OnPropertyChanged(nameof(SelectedCityCount));
}
}
private MapMarkerCollection? _mapMarkerCollection;
public MapMarkerCollection? MapMarkerCollection
{
get => _mapMarkerCollection;
set
{
_mapMarkerCollection = value;
OnPropertyChanged(nameof(MapMarkerCollection));
}
}
public SkysCrapersData()
{
MapMarkerCollection = new MapMarkerCollection();
SelectedIndex = 1;
}
private void UpdateIndex()
{
var selectedCity = Data.ElementAtOrDefault(SelectedIndex);
if (selectedCity != null)
{
SelectedCityName = selectedCity.City;
SelectedCountryName = selectedCity.Country;
SelectedCityCount = selectedCity.Count;
SelectedCityImage = $"{selectedCity.Country?.ToLower().Replace(" ", "_")}.png";
MapMarkerCollection?.Clear();
var marker = selectedCity.City switch
{
"Hong-Kong" => new MapMarker { Latitude = 22.3193, Longitude = 114.1694 },
"Shenzhen" => new MapMarker { Latitude = 22.5429, Longitude = 114.0596 },
"New York" => new MapMarker { Latitude = 40.7128, Longitude = 74.0060 },
"Dubai" => new MapMarker { Latitude = 25.2048, Longitude = 55.2708 },
"Guangzhou" => new MapMarker { Latitude = 23.1291, Longitude = 113.2644 },
"Shanghai" => new MapMarker { Latitude = 31.2304, Longitude = 121.4737 },
"Kuala Lumpur" => new MapMarker { Latitude = 3.1499, Longitude = 101.6945 },
"Tokyo" => new MapMarker { Latitude = 35.6764, Longitude = 139.6500 },
"Wuhan" => new MapMarker { Latitude = 30.5928, Longitude = 114.3052 },
"Chongqing" => new MapMarker { Latitude = 29.5657, Longitude = 106.5512 },
_ => null
};
if (marker != null)
{
MapMarkerCollection?.Add(marker);
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
After executing the above code examples, we’ll get the output that resembles the following image.
Visualizing the skyscrapers data with .NET MAUI Semi-Doughnut Chart and Maps
GitHub reference
For more details, refer to the project on GitHub.
Conclusion
Thank you for reading! In this blog, we’ve explored how to visualize the top 10 cities with the most skyscrapers data using the Syncfusion .NET MAUI Doughnut Chart and Maps control. This integration offers a powerful example of combining geographic data with statistical representations to convey insights effectively. We encourage you to follow the steps outlined and share your feedback in the comments section below.
The 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
- Syncfusion Essential® UI Kit for .NET MAUI: Accelerate App Development with Pre-Built UI Pages
- Building a Neumorphic UI with .NET MAUI Column Chart to Showcase Gen Z’s Favourite Social Media Platforms
- Introducing Syncfusion’s Second Set of Open-Source .NET MAUI Controls
- Sneak Peek at 2024 Volume 4: .NET MAUI