Blazor Serverにて気象データをグラフ化するWebアプリを作成する: Chart.js 呼出編
完成イメージ
Blazor Serverにて気象データをグラフ化するWebアプリを作成する
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ページのボタンクリックして動作確認する。