Blazor WebAssemblyでMudBlazorを使ってPie Chartを表示してみた

# はじめに

この記事では、Blazor WebAssemblyでMudBlazorを使って、Pie Chartを表示するまでの手順を示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/70d94be6-29cf-278d-0f43-b38d7082ae0c.png)


## Blazor WebAssemblyとは
.NET を使って対話型のクライアント側 Web アプリを構築するためのWebフレームワークです。

https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-6.0#blazor-webassembly


## MudBlazorとは
見やすく、直感的に操作できるようなデザインであるマテリアルデザインを導入したコンポーネントフレームワークです。

https://mudblazor.com/

https://github.com/MudBlazor/MudBlazor


# 実行環境 
- Windows 11 
- Visual Studio 2022
- C# (.NET 6.0)

# 本文
## 1. プロジェクトの作成
デスクトップ上に「BlazorApp」というプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/96ccf9e7-a01b-35b3-070a-685c653cf353.png)

追加情報は特に変更せず、デフォルトで進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/222ca113-bbdf-9e9c-ee7e-b265b5144ff9.png)

以下のようなファイル構成で展開し、プロジェクトの作成は完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/b1ef641c-cfe2-4b8d-2c8b-54981323507f.png)

## 2. MudBlazorの導入
まずは、MudBlazorパッケージをインストールします。
ソリューションエクスプローラーにあるBlazorAppプロジェクトを右クリックして、NuGetパッケージの管理を選択してください。そして参照で「MudBlazor」を検索し、MudBlazorパッケージをインストールしましょう。私がインストールしたバージョンは6.0.6でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/003fa43f-d015-f1a8-98a9-ad1469df0129.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/c658e3c1-4c7e-1892-e6bd-0e5c2844536a.png)

次にMudBlazorを使うために、いくつかコードを追加します。
BlazorAppプロジェクト直下にある「_Imports.razor」ファイルに、以下のように追加します。

```razor:_Imports.razor
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorApp
@using BlazorApp.Shared

@using MudBlazor // 追加
```
wwwrootにある「index.html」ファイルに、以下のように追加します。
headタグ内にlink要素を2つ追加してください。また、bodyタグ内にscript要素を1つ追加してください。

```html:index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorApp</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="BlazorApp.styles.css" rel="stylesheet" />
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" /> <!--追加-->
    <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" /> <!--追加-->
</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
    <script src="_content/MudBlazor/MudBlazor.min.js"></script> <!--追加-->
</body>

</html>
```

BlazorAppプロジェクト直下にある「Program.cs」ファイルに、以下のように追加します。

```cs:Program.cs
using BlazorApp;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services; // 追加

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddMudServices(); // 追加

await builder.Build().RunAsync();
```

Sharedフォルダにある「MainLayout.razor」ファイルに、以下のように追加します。

```razor:MainLayout.razor
@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            @Body

            <MudThemeProvider/> @*追加*@
            <MudDialogProvider/> @*追加*@
            <MudSnackbarProvider/> @*追加*@
        </article>
    </main>
</div>
```

以上で、MudBlazorの導入は完了です！

## Pie Chartを表示する
それでは、Pie Chartを表示させます。

Pagesフォルダにある「Index.razor」ファイルに、以下のようにコードを追加します。

```razor:Index.razor
@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@*ここから下を追加*@

<MudPaper Class="pa-4">
    <MudChart ChartType="ChartType.Pie" InputData="@data" @bind-SelectedIndex="bsIndex" InputLabels="@labels" Width="300px" Height="300px" />
</MudPaper>
<MudPaper Class="pa-4 mt-2 d-flex justify-center">
    <MudButton OnClick="AddDataSize" Variant="Variant.Filled" Color="Color.Primary">Add</MudButton>
    <MudButton @onclick="RandomizeData" Variant="Variant.Filled" Class="mx-4">Randomize</MudButton>
    <MudButton OnClick="RemoveDataSize" Variant="Variant.Filled" Color="Color.Secondary">Remove</MudButton>  
</MudPaper>
<MudText Typo="Typo.h6">Selected portion of the chart: @bsIndex</MudText>
@code {
    private int bsIndex = -1; //default value cannot be 0 -> first selectedindex is 0.
    int dataSize = 4;
    double[] data = { 77, 25, 20, 5 };
    string[] labels = { "Uranium", "Plutonium", "Thorium", "Caesium", "Technetium", "Promethium",
                        "Polonium", "Astatine", "Radon", "Francium", "Radium", "Actinium", "Protactinium",
                        "Neptunium", "Americium", "Curium", "Berkelium", "Californium", "Einsteinium", "Mudblaznium" };

    Random random = new Random();

    void RandomizeData()
    {
        var new_data = new double[dataSize];
        for (int i = 0; i < new_data.Length; i++)
            new_data[i] = random.NextDouble() * 100;
        data = new_data;
        StateHasChanged();
    }

    void AddDataSize()
    {
        if (dataSize < 20)
        {
            dataSize = dataSize + 1;
            RandomizeData();
        }
    }
    void RemoveDataSize()
    {
        if (dataSize > 0)
        {
            dataSize = dataSize - 1;
            RandomizeData();
        }
    }
}
```

実行すると、以下のように表示できれば成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/d844a39a-1d6a-ca42-9ee4-4ce1a4fb43d0.png)