Blazor Serverにて気象データをグラフ化するWebアプリを作成する: Chart.js 呼出編

完成イメージ

Blazor Serverにて気象データをグラフ化するWebアプリを作成する f:id:cniya:20210728152036p:plain

Step 6: Chart.jsインストール

  • wwwrootにlibフォルダを追加する。
  • libフォルダ上で右クリック→追加→クライアント側のライブラリ
  • Chart.jsをインストール
  • libフォルダ内にChart.jsフォルダが作成され、必要なjsファイルが配置されていることを確認する

Step 7: Chart.jsの描画テスト

  • _Host.cshtmlにchart.min.jsの参照設定追加
  • サンプルグラフを書くrenderChart関数を追加する。
    <script src="lib/Chart.js/chart.min.js"></script>
    <script>
        function renderChart() {
            if (window.chartObj) {
                window.chartObj.destroy();
            }
            var ctx = document.getElementById('myChart');
            window.chartObj = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
                    datasets: [{
                        label: "Sample Data",
                        data: [2, 12, 16, 10, 12, 11, 3]
                    }]
                }
            });
        };
    </script>
</body>
  • Counter.razorを修正し、ボタンクリックでrenderChart()を呼び出すようにする。
  • Ctrl+F5でWebアプリを起動し、Counterページのボタンクリックでグラフが描画されることを確認する。
@page "/counter"

<h1>Counter</h1>

<button class="btn btn-primary" onclick="renderChart();">Click me</button>
<canvas id="myChart"></canvas>

@code {
}

Step 8: C#からJavascriptを呼び出す

  • Counter.razor.csを追加する。
  • partial classにする。
  • IJSRuntime.InvokeVoidAsyncにてjavascriptを呼び出す。
  • IJSRuntimeはinjectする。
    public partial class Counter
    {
        [Inject]
        IJSRuntime JSRuntime { get; set; }

        public async Task CallRenderChart()
        {
            await JSRuntime.InvokeVoidAsync("renderChart");
        }
    }
  • CallRenderChartを呼び出すようCounter.razorを修正する。
<button class="btn btn-primary" @onclick="CallRenderChart">Click me</button>

Step 9 : データセットを動的に生成する

  • JSON形式のパラメータを構造化したChartJsonクラスをDataフォルダ内に作成する。
    public class ChartJson<T>
    {
        [JsonPropertyName("type")]
        public string Type { get; set; }
        [JsonPropertyName("data")]
        public ChartData<T> Data { get; set; }
    }

    public class ChartData<T>
    {
        [JsonPropertyName("labels")]
        public List<string> Labels { get; set; }
        [JsonPropertyName("datasets")]
        public List<ChartDataSet<T>> DataSets { get; set; }
    }

    public class ChartDataSet<T>
    {
        [JsonPropertyName("label")]
        public string Label { get; set; }
        [JsonPropertyName("data")]
        public List<T> Data { get; set; }
    }
  • Counter.razor.csにDemoData()メソッド追加。
  • CallRenderChart内でDemoData()をシリアライズする。
        public async Task CallRenderChart()
        {
            var parameter = JsonSerializer.Serialize(DemoData());
            await JSRuntime.InvokeVoidAsync("renderChart");
        }

        public static ChartJson<double?> DemoData()
        {
            return new ChartJson<double?>()
            {
                Type = "line",
                Data = new ChartData<double?>()
                {
                    Labels = new List<string>() { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
                    DataSets = new List<ChartDataSet<double?>>() { new ChartDataSet<double?>() { Label = "Sample Data", Data = new List<double?>() { 20, 12, 16, 10, 12, 11, 3 } } }
                }
            };
        }
  • CallRenderChart内でJavascriptを呼び出すとき、シリアライズしたjson文字列をパラメータで呼び出せるよう、InvokeVoidAsyncからInvokeAsyncに変更する
            var parameter = JsonSerializer.Serialize(DemoData());
            await JSRuntime.InvokeAsync<string>("renderChart", parameter);
  • _Host.cshtmlのrenderChartでstring型のパラメータを受け取れるように修正。
  • 受け取ったstringをJSON化してChartの第二引数として与える。
    <script>
        function renderChart(jsonStr) {
            if (window.chartObj) {
                window.chartObj.destroy();
            }
            var ctx = document.getElementById('myChart');
            window.chartObj = new Chart(ctx, JSON.parse(jsonStr));
        };
    </script>
  • Ctrl+F5で動作確認。

Step 10:

  • Counter.razor.cs内でWeatherForecastServiceをinjectし、GetForecastAsyncにてデータを取得する。
  • ListからChartJsonを生成するメソッドFromForecastListを追加する。
        [Inject]
        WeatherForecastService WeatherForecastService { get; set; }

        public async Task CallRenderChart()
        {
            var forecasts = await WeatherForecastService.GetForecastAsync();
            var parameter = JsonSerializer.Serialize(FromForecastList(forecasts));
            await JSRuntime.InvokeAsync<string>("renderChart", parameter);
        }
        private static ChartJson<double> FromForecastList(List<WeatherForecast> forecasts)
        {
            return new ChartJson<double>()
            {
                Type = "line",
                Data = new ChartData<double>()
                {
                    Labels = forecasts.OrderBy(a => a.Date).Select(a => a.Date.ToShortDateString()).ToList(),
                    DataSets = new List<ChartDataSet<double>>() 
                    { 
                        new ChartDataSet<double>() 
                        { 
                            Label = "Highest Temp.", 
                            Data = forecasts.OrderBy(a => a.Date).Select(a => a.HighestTemperature).ToList() 
                        },
                        new ChartDataSet<double>() 
                        { 
                            Label = "Lowest Temp.", 
                            Data = forecasts.OrderBy(a => a.Date).Select(a => a.LowestTemperature).ToList() 
                        },
                        new ChartDataSet<double>() 
                        { 
                            Label = "Ave. Temp.", 
                            Data = forecasts.OrderBy(a => a.Date).Select(a => (double)a.Temperature).ToList() 
                        }
                    }
                }
            };
        }
  • Ctrl+F5にてWebアプリ起動し、Counterページのボタンクリックして動作確認する。 f:id:cniya:20210728152036p:plain

参考記事

www.chartjs.org www.ipentec.com