[Chartjs]-How can i create multiple components with pie charts?

1👍

A bit late, but I was in the same boat as to how to create a pie chart in a Blazor Server App. I ended up creating a simple component to make an SVG pie chart and put it in it’s own component. I have created a sample in GitHub that you use SVG Pie Chart. There is a small modification as well to make it into a Doughnut chart. All you have to make sure is that the data you pass to the component totals up to 100%. No point in plotting a pie chart that has a total greater than 100%.

The code is simple:

Data Model:

namespace SVG_Pie_Chart.Data
{
    public class PieDataModel
    {
        public double Percent { get; set; }
        public string Name { get; set; }
        public string Color { get; set; }
    }
}

Component:

@using SVG_Pie_Chart.Data
<svg style="display:block; margin:auto; vertical-align:central;" height="@height" width="@width" viewBox="0, 0, 2000, 2000">
    @foreach (var p in PieDataToPlot)
    {
        @(RotAngle = RotAngle + (((p.Percent / 100) * 360.0) - 90))
        <path d="@GenerateArc(1000, 1000, 800, p.Percent)" id="@RotAngle" fill="@p.Color" transform="rotate(@RotAngle,1000,1000)"></path>
        @(RotAngle += 90)
    }
</svg>
@code {

    [Parameter]
    public List<PieDataModel> PieData { get; set; }
    [Parameter]
    public int height { get; set; } = 90;
    [Parameter]
    public int width { get; set; } = 200;
    private double RotAngle { get; set; } = 0;
    private List<PieDataModel> PieDataToPlot = new List<PieDataModel>();

    protected override void OnInitialized()
    {

        if (PieData != null)
        {
            PieDataToPlot = PieData;
        }
        base.OnInitialized();
    }

    #region Svg Pie
    private double DegToRad(double AngDeg)
    {
        return (AngDeg * Math.PI) / 180.0;
    }
    struct CartesianPosition
    {
        public double x;
        public double y;
    }
    private string GenerateArc(double cx, double cy, double r, double percent)
    {
        CartesianPosition Cartesian;

        double angledeg = (percent / 100) * 360.0;
        double anglerad = DegToRad(angledeg);
        Cartesian.x = cx + (r * Math.Cos(anglerad));
        Cartesian.y = cy - (r * Math.Sin(anglerad));
        if (Convert.ToInt32(Cartesian.y) == cy)
        {
            Cartesian.y += 1.0;
        }

        if (angledeg > 180)
        {
            return "M " + cx.ToString() + " " + cy.ToString() + " " + (cx + r).ToString() + "," + (cy).ToString() + " A" + r.ToString() + " " + r.ToString() + ", 0, 1, 0, " + Cartesian.x.ToString() + "," + Cartesian.y.ToString() + " ";
        }
        else
        {
            return "M " + cx.ToString() + " " + cy.ToString() + " " + (cx + r).ToString() + "," + (cy).ToString() + " A" + r.ToString() + " " + r.ToString() + ", 0, 0, 0, " + Cartesian.x.ToString() + "," + Cartesian.y.ToString() + " ";
        }
    }
    #endregion
}

And how to use:

<SVGPie PieData="@PieData" height="200" width="300"></SVGPie>
<SVGDoughnut PieData="@PieData"></SVGDoughnut>
@code
{
    private List<PieDataModel> PieData = new List<PieDataModel>();
    protected override void OnInitialized()
    {
        GenerateSamplePieData();
        base.OnInitialized();
    }
    private void GenerateSamplePieData()
    {
        PieDataModel PDM = new PieDataModel();
        PDM.Color = "#ff0000";
        PDM.Name = "Section 1";
        PDM.Percent = 30.0;
        PieData.Add(PDM);

        PDM = new PieDataModel();
        PDM.Color = "#ffff00";
        PDM.Name = "Section 2";
        PDM.Percent = 20.0;
        PieData.Add(PDM);

        PDM = new PieDataModel();
        PDM.Color = "#0000ff";
        PDM.Name = "Section 3";
        PDM.Percent = 20.0;
        PieData.Add(PDM);

        PDM = new PieDataModel();
        PDM.Color = "#00ff00";
        PDM.Name = "Section 4";
        PDM.Percent = 30.0;
        PieData.Add(PDM);

    }
}

As said, make sure your Percent do not add up to more than 100%.

Leave a comment