Doughnut Chart
Explore interactive Blazor Doughnut Chart demos with real-world examples. Learn how to visualize data, customize chart options, and implement data labels using the Blazor Doughnut Chart component.
Chart setup #
How it works #
The Doughnut Chart component provides a simple way to visualize categorical data as proportional segments of a circle.
How to use:
This demo shows how to configure a basic doughnut chart, assign data, and adjust chart options for your scenario.
How to use:
- Add the
DoughnutChartcomponent to your page. - Define your data and labels using the chart's data model.
- Customize appearance and behavior using the
Optionsproperty (e.g., colors, legend, tooltips). - Bind your data and options to the component.
- Refer to the demo code below for a working example and further customization options.
<DoughnutChart @ref="doughnutChart" Width="600" />
<div class="mt-5">
<Button Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="RandomizeAsync"> Randomize </Button>
<Button Color="ButtonColor.Link" Size="ButtonSize.Small" @onclick="AddDatasetAsync"> Add Dataset </Button>
<Button Color="ButtonColor.Info" Size="ButtonSize.Small" @onclick="AddDataAsync">Add Data</Button>
</div>
@code {
private DoughnutChart doughnutChart = default!;
private DoughnutChartOptions doughnutChartOptions = default!;
private ChartData chartData = default!;
private string[]? backgroundColors;
private int datasetsCount = 0;
private int dataLabelsCount = 0;
private Random random = new();
protected override void OnInitialized()
{
backgroundColors = ChartJsColorUtility.CategoricalTwelveColors;
chartData = new ChartData { Labels = GetDefaultDataLabels(4), Datasets = GetDefaultDataSets(1) };
doughnutChartOptions = new();
doughnutChartOptions.Responsive = true;
doughnutChartOptions.Plugins.Title!.Text = "2022 - Sales";
doughnutChartOptions.Plugins.Title.Display = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await doughnutChart.InitializeAsync(chartData, doughnutChartOptions);
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task RandomizeAsync()
{
if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return;
var newDatasets = new List<IChartDataset>();
foreach (var dataset in chartData.Datasets)
{
if (dataset is DoughnutChartDataset doughnutChartDataset
&& doughnutChartDataset is not null
&& doughnutChartDataset.Data is not null)
{
var count = doughnutChartDataset.Data.Count;
var newData = new List<double?>();
for (var i = 0; i < count; i++)
{
newData.Add(random.Next(0, 100));
}
doughnutChartDataset.Data = newData;
newDatasets.Add(doughnutChartDataset);
}
}
chartData.Datasets = newDatasets;
await doughnutChart.UpdateAsync(chartData, doughnutChartOptions);
}
private async Task AddDatasetAsync()
{
if (chartData is null || chartData.Datasets is null) return;
var chartDataset = GetRandomDoughnutChartDataset();
chartData = await doughnutChart.AddDatasetAsync(chartData, chartDataset, doughnutChartOptions);
}
private async Task AddDataAsync()
{
if (dataLabelsCount >= 12)
return;
if (chartData is null || chartData.Datasets is null)
return;
var data = new List<IChartDatasetData>();
foreach (var dataset in chartData.Datasets)
{
if (dataset is DoughnutChartDataset doughnutChartDataset)
{
data.Add(new DoughnutChartDatasetData(doughnutChartDataset.Label, random.Next(0, 100), backgroundColors![dataLabelsCount]));
}
}
chartData = await doughnutChart.AddDataAsync(chartData, GetNextDataLabel(), data);
dataLabelsCount += 1;
}
#region Data Preparation
private List<IChartDataset> GetDefaultDataSets(int numberOfDatasets)
{
var datasets = new List<IChartDataset>();
for (var index = 0; index < numberOfDatasets; index++)
{
datasets.Add(GetRandomDoughnutChartDataset());
}
return datasets;
}
private DoughnutChartDataset GetRandomDoughnutChartDataset()
{
datasetsCount += 1;
return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() };
}
private List<double?> GetRandomData()
{
var data = new List<double?>();
for (var index = 0; index < dataLabelsCount; index++)
{
data.Add(random.Next(0, 100));
}
return data;
}
private List<string> GetRandomBackgroundColors()
{
var colors = new List<string>();
for (var index = 0; index < dataLabelsCount; index++)
{
colors.Add(backgroundColors![index]);
}
return colors;
}
private List<string> GetDefaultDataLabels(int numberOfLabels)
{
var labels = new List<string>();
for (var index = 0; index < numberOfLabels; index++)
{
labels.Add(GetNextDataLabel());
dataLabelsCount += 1;
}
return labels;
}
private string GetNextDataLabel() => $"Product {dataLabelsCount + 1}";
private string GetNextDataBackgrounfColor() => backgroundColors![dataLabelsCount];
#endregion Data Preparation
}Data labels #
The Doughnut Chart component supports data labels, allowing you to display values or category names directly on each segment of the chart.
How to use:
Data labels make it easier for users to interpret the chart by showing relevant information directly on each doughnut segment.
How to use:
- Enable data labels by configuring the chart's plugin options, such as
Options.Plugins.Datalabels.Display = true. - You can customize the label content, formatting, and position using the available plugin settings.
- Assign your data and labels as usual to the chart's data model.
- Refer to the demo code below for a working example and further configuration options.
<DoughnutChart @ref="doughnutChart" Width="600" />
@code {
private DoughnutChart doughnutChart = default!;
private DoughnutChartOptions doughnutChartOptions = default!;
private ChartData chartData = default!;
private string[]? backgroundColors;
private int datasetsCount = 0;
private int dataLabelsCount = 0;
private Random random = new();
protected override void OnInitialized()
{
backgroundColors = ChartJsColorUtility.CategoricalTwelveColors;
chartData = new ChartData { Labels = GetDefaultDataLabels(4), Datasets = GetDefaultDataSets(3) };
doughnutChartOptions = new();
doughnutChartOptions.Responsive = true;
doughnutChartOptions.Plugins.Title!.Text = "2022 - Sales";
doughnutChartOptions.Plugins.Title.Display = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// pass the plugin name to enable the data labels
await doughnutChart.InitializeAsync(chartData: chartData, chartOptions: doughnutChartOptions, plugins: new string[] { "ChartDataLabels" });
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task RandomizeAsync()
{
if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return;
var newDatasets = new List<IChartDataset>();
foreach (var dataset in chartData.Datasets)
{
if (dataset is DoughnutChartDataset doughnutChartDataset
&& doughnutChartDataset is not null
&& doughnutChartDataset.Data is not null)
{
var count = doughnutChartDataset.Data.Count;
var newData = new List<double?>();
for (var i = 0; i < count; i++)
{
newData.Add(random.Next(0, 100));
}
doughnutChartDataset.Data = newData;
newDatasets.Add(doughnutChartDataset);
}
}
chartData.Datasets = newDatasets;
await doughnutChart.UpdateAsync(chartData: chartData, chartOptions: doughnutChartOptions);
}
private async Task AddDataAsync()
{
if (dataLabelsCount >= 12)
return;
if (chartData is null || chartData.Datasets is null)
return;
var data = new List<IChartDatasetData>();
foreach (var dataset in chartData.Datasets)
{
if (dataset is DoughnutChartDataset doughnutChartDataset)
{
data.Add(new DoughnutChartDatasetData(doughnutChartDataset.Label, random.Next(0, 100), backgroundColors![dataLabelsCount]));
}
}
chartData = await doughnutChart.AddDataAsync(chartData, GetNextDataLabel(), data);
dataLabelsCount += 1;
}
#region Data Preparation
private List<IChartDataset> GetDefaultDataSets(int numberOfDatasets)
{
var datasets = new List<IChartDataset>();
for (var index = 0; index < numberOfDatasets; index++)
{
var dataset = GetRandomDoughnutChartDataset();
if (index == 0)
dataset.Datalabels.Anchor = DataLabelAnchor.End;
else if (index == numberOfDatasets - 1)
dataset.Datalabels.Anchor = DataLabelAnchor.Start;
else
dataset.Datalabels.Anchor = DataLabelAnchor.Center;
datasets.Add(dataset);
}
return datasets;
}
private DoughnutChartDataset GetRandomDoughnutChartDataset()
{
datasetsCount += 1;
return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() };
}
private List<double?> GetRandomData()
{
var data = new List<double?>();
for (var index = 0; index < dataLabelsCount; index++)
{
data.Add(random.Next(0, 100));
}
return data;
}
private List<string> GetRandomBackgroundColors()
{
var colors = new List<string>();
for (var index = 0; index < dataLabelsCount; index++)
{
colors.Add(backgroundColors![index]);
}
return colors;
}
private List<string> GetDefaultDataLabels(int numberOfLabels)
{
var labels = new List<string>();
for (var index = 0; index < numberOfLabels; index++)
{
labels.Add(GetNextDataLabel());
dataLabelsCount += 1;
}
return labels;
}
private string GetNextDataLabel() => $"Product {dataLabelsCount + 1}";
private string GetNextDataBackgrounfColor() => backgroundColors![dataLabelsCount];
#endregion Data Preparation
}