Pie Chart


Explore interactive Blazor Pie Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Pie Chart component.

API Documentation

Chart setup #

Before using any chart demo: install BlazorExpress.ChartJS 1.2.2, load Chart.js 4.4.1, chartjs-plugin-datalabels 2.2.0, and _content/BlazorExpress.ChartJS/blazorexpress.chartjs.js, then add @using BlazorExpress.ChartJS to your chart page or chart folder.

Follow the shared chart setup guide, the .NET 8 WebAssembly guide, or the .NET 8 Web App Server guide. For full chart component guidance and examples, visit chartjs.blazorexpress.com.

How it works #

The Pie Chart component visualizes categorical data as proportional slices of a circle, making it ideal for showing parts of a whole.

How to use:
  1. Add the PieChart component to your page and set its dimensions (e.g., Width="600").
  2. Prepare your chart data by specifying Labels for each category and one or more Datasets with values and background colors.
  3. Configure chart options such as Responsive and Title using the PieChartOptions object.
  4. Initialize the chart in OnAfterRenderAsync by calling pieChart.InitializeAsync(chartData, pieChartOptions).
  5. Use the demo's interactive buttons to randomize data, add datasets, or add new data points dynamically.
  6. Refer to the demo code below for practical examples of data preparation, dynamic updates, and chart customization.
This demo demonstrates how to set up a pie chart, bind your data, and interactively update the chart to fit your application's needs.
<PieChart @ref="pieChart" 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 PieChart pieChart = default!;
    private PieChartOptions pieChartOptions = 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) };

        pieChartOptions = new();
        pieChartOptions.Responsive = true;
        pieChartOptions.Plugins.Title!.Text = "2022 - Sales";
        pieChartOptions.Plugins.Title.Display = true;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await pieChart.InitializeAsync(chartData, pieChartOptions);
        }
        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 PieChartDataset pieChartDataset
                && pieChartDataset is not null
                && pieChartDataset.Data is not null)
            {
                var count = pieChartDataset.Data.Count;

                var newData = new List<double?>();
                for (var i = 0; i < count; i++)
                {
                    newData.Add(random.Next(0, 100));
                }

                pieChartDataset.Data = newData;
                newDatasets.Add(pieChartDataset);
            }
        }

        chartData.Datasets = newDatasets;

        await pieChart.UpdateAsync(chartData, pieChartOptions);
    }

    private async Task AddDatasetAsync()
    {
        if (chartData is null || chartData.Datasets is null) return;

        var chartDataset = GetRandomPieChartDataset();
        chartData = await pieChart.AddDatasetAsync(chartData, chartDataset, pieChartOptions);
    }

    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 PieChartDataset pieChartDataset)
                data.Add(new PieChartDatasetData(pieChartDataset.Label, random.Next(0, 100), backgroundColors![dataLabelsCount]));
        }

        chartData = await pieChart.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(GetRandomPieChartDataset());
        }

        return datasets;
    }

    private PieChartDataset GetRandomPieChartDataset()
    {
        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 Pie Chart component supports data labels, allowing you to display values or category names directly on each slice of the chart.

How to use:
  1. Enable data labels by passing the ChartDataLabels plugin when initializing the chart: plugins: new[] { "ChartDataLabels" }.
  2. Customize the position of data labels for each dataset using the Datalabels.Anchor property (e.g., Anchor.End or Anchor.Center).
  3. Prepare your chart data and datasets as usual, and bind them to the PieChart component.
  4. Use the provided buttons to randomize data or add new data points dynamically, and observe how data labels update automatically.
  5. Refer to the demo code below for practical examples of enabling and customizing data labels in your pie charts.
Data labels make it easier for users to interpret the chart by showing relevant information directly on each pie slice.
<PieChart @ref="pieChart" Width="600" />

<div class="mt-5">
    <Button Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="RandomizeAsync"> Randomize </Button>
    <Button Color="ButtonColor.Info" Size="ButtonSize.Small" @onclick="AddDataAsync">Add Data</Button>
</div>

@code {
    private PieChart pieChart = default!;
    private PieChartOptions pieChartOptions = 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) };

        pieChartOptions = new();
        pieChartOptions.Responsive = true;
        pieChartOptions.Plugins.Title!.Text = "2022 - Sales";
        pieChartOptions.Plugins.Title.Display = true;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // pass the plugin name to enable the data labels
            await pieChart.InitializeAsync(chartData: chartData, chartOptions: pieChartOptions, 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 PieChartDataset pieChartDataset
                && pieChartDataset is not null
                && pieChartDataset.Data is not null)
            {
                var count = pieChartDataset.Data.Count;

                var newData = new List<double?>();
                for (var i = 0; i < count; i++)
                {
                    newData.Add(random.Next(0, 100));
                }

                pieChartDataset.Data = newData;
                newDatasets.Add(pieChartDataset);
            }
        }

        chartData.Datasets = newDatasets;

        await pieChart.UpdateAsync(chartData, pieChartOptions);
    }

    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 PieChartDataset pieChartDataset)
                data.Add(new PieChartDatasetData(pieChartDataset.Label, random.Next(0, 100), backgroundColors![dataLabelsCount]));
        }

        chartData = await pieChart.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 = GetRandomPieChartDataset();

            if (index == 0)
                dataset.Datalabels.Anchor = DataLabelAnchor.End;
            else if (index == numberOfDatasets - 1)
                dataset.Datalabels.Anchor = DataLabelAnchor.End;
            else
                dataset.Datalabels.Anchor = DataLabelAnchor.Center;

            datasets.Add(dataset);
        }

        return datasets;
    }

    private PieChartDataset GetRandomPieChartDataset()
    {
        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
}

Change legend position #

The Pie Chart component allows you to easily change the position of the chart legend to improve readability or match your application's layout.

How to use:
  1. Set the legend position using pieChartOptions.Plugins.Legend.Position (e.g., "top", "right", "bottom", or "left").
  2. Update the legend position dynamically by changing this property and calling pieChart.UpdateAsync(chartData, pieChartOptions).
  3. Use the demo's buttons to switch the legend position interactively and see the effect in real time.
  4. Refer to the demo code below for practical examples of configuring and updating the legend position in your pie charts.
Adjusting the legend position helps ensure your chart is clear and fits well within your application's design.
<PieChart @ref="pieChart" Width="600" />

<div class="mt-5">
    <Button Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="PositionTopAsync"> Position: top </Button>
    <Button Color="ButtonColor.Link" Size="ButtonSize.Small" @onclick="PositionRightAsync"> Position: right </Button>
    <Button Color="ButtonColor.Info" Size="ButtonSize.Small" @onclick="PositionBottomAsync"> Position: bottom </Button>
    <Button Color="ButtonColor.Warning" Size="ButtonSize.Small" @onclick="PositionLeftAsync"> Position: left </Button>
</div>

@code {
    private PieChart pieChart = default!;
    private PieChartOptions pieChartOptions = 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) };

        pieChartOptions = new();
        pieChartOptions.Responsive = true;
        pieChartOptions.Plugins.Title!.Text = "2022 - Sales";
        pieChartOptions.Plugins.Title.Display = true;

        pieChartOptions.Plugins.Legend.Position = "right";
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await pieChart.InitializeAsync(chartData, pieChartOptions);
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    private async Task PositionTopAsync() => await UpdatePositionAsync("top");
    private async Task PositionRightAsync() => await UpdatePositionAsync("right");
    private async Task PositionBottomAsync() => await UpdatePositionAsync("bottom");
    private async Task PositionLeftAsync() => await UpdatePositionAsync("left");

    private async Task UpdatePositionAsync(string position)
    {
        pieChartOptions.Plugins.Legend.Position = position;
        await pieChart.UpdateAsync(chartData, pieChartOptions);
    }

    #region Data Preparation

    private List<IChartDataset> GetDefaultDataSets(int numberOfDatasets)
    {
        var datasets = new List<IChartDataset>();

        for (var index = 0; index < numberOfDatasets; index++)
        {
            datasets.Add(GetRandomPieChartDataset());
        }

        return datasets;
    }

    private PieChartDataset GetRandomPieChartDataset()
    {
        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
}
DO YOU KNOW?
This demo website is built using the BlazorExpress.Bulma library and published on the Azure Web App. See our source code on GitHub.