.NET 8.0 の ASP.NET Core アプリ(MVC)に Highchartsを追加し、Dapperを通して取得した SQLiteデータベースのデータをグラフ表示するサンプルを作成しました。
ソースコードは GitHub で公開しています。
日本の歴代内閣と日経平均株価を列挙し、それぞれの関係を示すグラフになっています。
現代貨幣理論(MMT)とマクロ経済政策が理解されている現代だから言えるけど、日本のバブル崩壊で1990年代に発生したあらゆる負債を日銀が全て買い取っていれば、日本のバブル崩壊なんて存在せず、夕張市も破綻せず、未だに「Japan as No.1」だった。
財務省はいまだに日本経済を崩壊させ続けてるけど。
不動産バブル崩壊に伴う中国経済の低迷だって、1京円と言われる不動産業界と地方の負債を、中国政府が全て買い取れば中国経済は直ぐ復活する。
Highcharts
グラフの形式は Highcharts with annotations にしました。
Highchartsを商用利用する場合は 有料 です。

データベース
SQLiteの管理ツールは DB Browser for SQLite を使用。
使用したバージョンは 2024/10/29時点で最新の v3.13.1。
https://sqlitebrowser.org/blog/version-3-13-1-released/

DB Browser for SQLite で SQLiteのデータベースファイルを作成。
日本の歴代内閣、日経平均株価の過去データは、SQLiteデータベースファイルに登録済み。


ソースコード構成
今回使った Visual Studio プロジェクト テンプレートは、Visual Studio 2022 + .NET 8 + ASP.NET Core MVC、HTTPS無し。




NuGet パッケージ インストール
System.Data.SQLiteパッケージをインストール
使用したバージョンは 2024/11/6時点で最新の v1.0.119。
| 1 2 3 | > Install-Package System.Data.SQLite | 

Dapperパッケージをインストール
使用したバージョンは 2024/11/6時点で最新の v2.1.35。
| 1 2 3 | > Install-Package Dapper | 

Newtonsoft.Jsonパッケージをインストール
使用したバージョンは 2024/11/6時点で最新の v13.0.3。
| 1 2 3 | > Install-Package Newtonsoft.Json | 

ソースコード変更内容を解説

/DB/EWise.db
SQLiteデータベースファイル。日本の歴代内閣、日経平均株価の過去データ登録済み。
/WebApplication1/WebApplication1.sln
この変更は無視して下さい。ソリューションを作り直した名残なので。
/WebApplication1/WebApplication1/appsettings.json
SQLiteデータベースのコネクションストリングを追加。

| 1 2 3 4 5 |   "ConnectionStrings": {     "DefaultConnection": "Data Source=..\\..\\DB\\EWise.db;;Version=3;Pooling=True;Max Pool Size=100;;BusyTimeout=5000;Synchronous=OFF;"   }, | 
/WebApplication1/WebApplication1/Consts/StaticData.cs
SQLiteデータベースのコネクションストリングを、アプリケーションの static領域に保持し、コネクションストリングの参照を楽にする。

| 1 2 3 4 5 6 7 8 9 | namespace WebApplication1.Consts {     public static class StaticData     {         public static string ConnectionString = "";     } } | 
/WebApplication1/WebApplication1/Controllers/HomeController.cs
Topページが表示される際に実行される HomeControllerの Index()メソッドで、日本の歴代内閣、日経平均株価のデータを取得し、ViewModeに纏めて Viewへ渡している。

| 1 2 3 4 | using WebApplication1.Models.ViewModel; using WebApplication1.Sqls; | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |         public IActionResult Index()         {             var 日経平均株価s = Sql日経平均株価.SelectAll();             var 内閣s = Sql内閣.SelectAll();             var viewModel = new IndexViewModel             {                 日経平均株価List = 日経平均株価s,                 内閣List = 内閣s             };             return View(viewModel);         } | 
/WebApplication1/WebApplication1/Models/M内閣.cs
日本の歴代内閣用データモデルクラス。

| 1 2 3 4 5 6 7 8 9 10 11 | namespace WebApplication1.Models {     public class M内閣     {         public long 発足日付_UnixTimestamp { get; set; }         public string 内閣名 { get; set; }     } } | 
/WebApplication1/WebApplication1/Models/M日経平均株価.cs
日経平均株価用データモデルクラス。

| 1 2 3 4 5 6 7 8 9 10 | namespace WebApplication1.Models {     public class M日経平均株価     {         public long 日付_UnixTimestamp { get; set; }         public decimal 終値 { get; set; }     } } | 
/WebApplication1/WebApplication1/Models/ViewModel/IndexViewModel.cs
Topページ用の ビューモデルクラス。

| 1 2 3 4 5 6 7 8 9 10 | namespace WebApplication1.Models.ViewModel {     public class IndexViewModel     {         public required List<M日経平均株価> 日経平均株価List { get; set; }         public required List<M内閣> 内閣List { get; set; }     } } | 
/WebApplication1/WebApplication1/Program.cs
SQLiteデータベースのコネクションストリングを、アプリケーションの static領域に保持する処理を追加。

| 1 2 3 | using WebApplication1.Consts; | 
| 1 2 3 | StaticData.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); | 
/WebApplication1/WebApplication1/Properties/launchSettings.json
この変更は無視して下さい。ソリューションを作り直した名残なので。
/WebApplication1/WebApplication1/Sqls/Sql内閣.cs
SQLiteデータベースから日本の歴代内閣のデータを取得する処理を作成。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using Dapper; using System.Data.SQLite; using WebApplication1.Consts; using WebApplication1.Models; namespace WebApplication1.Sqls {     public static class Sql内閣     {         public static List<M内閣> SelectAll()         {             using (var sqliteConnection = new SQLiteConnection(StaticData.ConnectionString))             {                 const string query = "SELECT * FROM 内閣";                 sqliteConnection.Open();                 return sqliteConnection.Query<M内閣>(query).AsList();             }         }     } } | 
/WebApplication1/WebApplication1/Sqls/Sql日経平均株価.cs
SQLiteデータベースから日経平均株価のデータを取得する処理を作成。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using Dapper; using System.Data.SQLite; using WebApplication1.Consts; using WebApplication1.Models; namespace WebApplication1.Sqls {     public static class Sql日経平均株価     {         public static List<M日経平均株価> SelectAll()         {             using (var sqliteConnection = new SQLiteConnection(StaticData.ConnectionString))             {                 const string query = "SELECT 日付_UnixTimestamp, 終値 FROM 日経平均株価";                 sqliteConnection.Open();                 return sqliteConnection.Query<M日経平均株価>(query).AsList();             }         }     } } | 
/WebApplication1/WebApplication1/Views/Home/Index.cshtml
Visual Studio プロジェクトを新規作成した際、デフォルトで実装されている「Welcome」欄は削除。
Topページが表示される際に実行される HomeControllerの Index()メソッドから受け取った、日本の歴代内閣、日経平均株価のデータを、JavaScriptの renderChart()メソッドへ渡す処理を追加。
renderChart()メソッドの実体は /wwwroot/js/site.js に実装しています。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @model WebApplication1.Models.ViewModel.IndexViewModel @{     ViewData["Title"] = "日経平均株価チャート"; } <div id="container" style="width: 6000px; height: 500px;"></div> <script>     // site.js内のrenderChart関数を呼び出してチャートを描画     // .NETのモデルデータをJavaScriptに渡す際に、UNIXタイムスタンプをミリ秒に変換     renderChart('container',     @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.日経平均株価List.Select(d => new         {             x = d.日付_UnixTimestamp * 1000, // 秒からミリ秒に変換             y = (double)d.終値         }).ToList())),     @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.内閣List.Select(r => new         {             x = r.発足日付_UnixTimestamp * 1000, // 秒からミリ秒に変換             text = r.内閣名         }).ToList()))         ); </script> | 
/WebApplication1/WebApplication1/Views/Shared/_Layout.cshtml
Highchartsを含む JavaScriptライブラリを <Head>内で読み込むように実装。

| 1 2 3 4 5 6 7 |     <script src="https://code.highcharts.com/highcharts.js" asp-fallback-src="/js/highcharts.js" asp-fallback-test-class="highcharts-test" asp-fallback-test-property="Highcharts" asp-append-version="true"></script>     <script src="https://code.highcharts.com/modules/annotations.js" asp-fallback-src="/js/annotations.js" asp-fallback-test-class="highcharts-annotations-test" asp-fallback-test-property="Highcharts" asp-append-version="true"></script>     <script src="/lib/jquery/dist/jquery.min.js" asp-append-version="true"></script>     <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js" asp-append-version="true"></script>     <script src="/js/site.js" asp-append-version="true"></script> | 
/WebApplication1/WebApplication1/WebApplication1.csproj
インストールした System.Data.SQLite、Dapper、Newtonsoft.Json、NuGetパッケージが追加されている。

| 1 2 3 4 5 6 7 |   <ItemGroup>     <PackageReference Include="Dapper" Version="2.1.35" />     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />     <PackageReference Include="System.Data.SQLite" Version="1.0.119" />   </ItemGroup> | 
/WebApplication1/WebApplication1/wwwroot/js/annotations.js
Highchartsの ローカルJavaScriptライブラリ。
CDNに接続できなかった場合に備えて、Highchartsの JavaScriptライブラリをローカルにも保持。
/WebApplication1/WebApplication1/wwwroot/js/highcharts.js
Highchartsの ローカルJavaScriptライブラリ。
CDNに接続できなかった場合に備えて、Highchartsの JavaScriptライブラリをローカルにも保持。
/WebApplication1/WebApplication1/wwwroot/js/site.js
Highchartsの JavaScriptライブラリを使い、日本の歴代内閣と日経平均株価のグラフを表示する renderChart()メソッドを作成。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | function renderChart(containerId, chartData, regimes) {     Highcharts.chart(containerId, {         chart: {             type: 'line'         },         title: {             text: '日経平均株価と内閣',             align: 'left'         },         xAxis: {             type: 'datetime',             labels: {                 format: '{value:%Y}年' // x軸のラベルをyyyy/MM/dd形式に設定             }         },         yAxis: {             title: {                 text: ''             },             labels: {                 formatter: function () {                     return this.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + '円'; // 3桁ごとにカンマを入れる                 }             }         },         tooltip: {             xDateFormat: '%Y/%m', // ツールチップの日付フォーマットをyyyy/MM形式に設定             valueSuffix: ' 円' // 金額の後ろに「円」を追加         },         series: [{             name: '日経平均株価',             data: chartData // 渡されたデータを使用         }],         annotations: regimes.map(r => ({             labels: [{                 point: {                     x: r.x,                     y: chartData.find(d => d.x >= r.x)?.y || chartData[0].y, // 発足日付付近のy値を取得                     xAxis: 0,                     yAxis: 0                 },                 text: r.text             }],             labelOptions: {                 backgroundColor: 'rgba(255,255,255,0.5)',                 borderColor: 'black'             }         }))     }); } | 
 
  
  
  
  

コメント