ASP.NET Web APIでデータ蓄積の続きの2回目です。前回は温度データを最新から一覧表示するページを作成しました。今回は温度データのグラフを表示するページを作成します。最終的に以下のように表示するページを作成します。グラフ表示には、 Google Chart Tools を使いました。表示方法としては、まずHTMLのページでJavaScriptからASP.NET Web APIを利用して温度データを取得します。次にそのデータをGoogle Chart Toolsでグラフ表示します。
Google Chart Tools
グラフ表示には、 Google Chart Tools を使いましたがJavaScript系のグラフ表示ライブラリは、もちろん他にもいろいろとあります。ここでは単純にGoogleブランドと商用利用化ということで選択しました。申し訳ありませんが、他のライブラリとの比較等はしていません。ご了承ください。
Google Chart Toolsの使い方の特徴としてデータ形式を google.visualization.DataTable のオブジェクトとして作成するということを挙げたいです。マニュアルからの引用ですが以下のような形式です。
DataTable Classのマニュアルページ
var dt = new google.visualization.DataTable({ cols: [{id: 'task', label: 'Task', type: 'string'}, {id: 'hours', label: 'Hours per Day', type: 'number'}], rows: [{c:[{v: 'Work'}, {v: 11}]}, {c:[{v: 'Eat'}, {v: 2}]}, {c:[{v: 'Commute'}, {v: 2}]}, {c:[{v: 'Watch TV'}, {v:2}]}, {c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}] }, 0.6);
この形式をどのように作成するかということですが、Google DataTable .Net Wrapperというのがあったのでこれを利用させて頂きました。ここでは、ASP.NETでの温度データを取得するWeb APIでこのライブラリを利用してGoogle DataTableに変換してその形式でレスポンスを返します。広く公開するWeb APIだとするとレスポンスの形式は慎重に検討する必要があると思いますが、ここではとくかくGoogle Chart Toolsでグラフを表示するということを優先します。
ASP.NETプロジェクトへの実装
実際にグラフ表示を実装していきます。前回のプロジェクトに追加していきます。
前回のプロジェクトは以下です。(※単なるサンプルプログラムです。ご利用による不具合、不利益等について弊社は一切責任を負わないものとします。)
プロジェクトファイル一式
Google DataTable .Net Wrapperの組み込み
以下のページからGoogle DataTable .Net Wrapperをダウンロードします。
Google DataTable .Net Wrapper
分かりやすい場所に保存して、Google.DataTable.Net.Wrapper.dllをVisual Studioでプロジェクトを開いた状態で参照を追加します。
参照マネージャの一番下の参照から参照ボタンで追加します。以下のように追加されました。
ASP.NET Web APIのGETメソッドの追加
温度データを取得するためのAPIを実装します。GETで実装することとして、パラメータとして以下を渡すこととします。
GET: api/TemperatureDatas/DeviceId/FromDT/ToDT
デバイスID
取得時間開始
取得時間終了
これを前回まで作成しているTemperatureDatasControllerクラスに追加します。
//using Google.DataTable.Net.Wrapper; が必要です。 // GET: api/TemperatureDatas/DeviceId/FromDT/ToDT [ResponseType(typeof(string))] public IHttpActionResult GetTemperatureData(int deviceId, string fromDT, string toDT) { DateTime dtFromDT; DateTime dtToDT; //DataTableを生成してカラムを追加する var dt = new Google.DataTable.Net.Wrapper.DataTable(); dt.AddColumn(new Column(ColumnType.String, "CreatedDateTime", "日時")); dt.AddColumn(new Column(ColumnType.Number, "TemperatureValue", "温度")); //時間からDateTimeオブジェクトを生成する try { dtFromDT = DateTime.Parse(fromDT); dtToDT = DateTime.Parse(toDT); } catch { Row r = dt.NewRow(); r.AddCellRange(new Cell[] { new Cell("Format Error"), new Cell(0) }); dt.AddRow(r); return Ok(dt.GetJson()); } //該当する温度データレコードの取得 var recSet = db.TemperatureDatas.Where(itm => itm.DeviceId == deviceId && (itm.CreatedDateTime >= dtFromDT && itm.CreatedDateTime <= dtToDT)).OrderBy(itm => itm.CreatedDateTime); if (recSet.ToList().Count == 0) { Row r = dt.NewRow(); r.AddCellRange(new Cell[] { new Cell("Not found"), new Cell(0) }); dt.AddRow(r); } else { //レコードからRowを作成して、Cellを追加する foreach (var item in recSet) { Row r = dt.NewRow(); r.AddCellRange(new Cell[] { new Cell(item.CreatedDateTime), new Cell(item.TemperatureValue) }); dt.AddRow(r); } } //JSON文字列を生成して返す return Ok(dt.GetJson()); }
次にグラフを表示するページです。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>温度データ登録</title> <link href="/Content/bootstrap.css" rel="stylesheet" /> <link href="/Content/site.css" rel="stylesheet" /> <script src="/Scripts/modernizr-2.6.2.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> // Visualization API と折れ線グラフ用のパッケージのロード google.load("visualization", "1", { packages: ["corechart"] }); </script> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">温度データ管理テスト</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">ホーム</a></li> <li><a href="/Help">API</a></li> </ul> </div> </div> </div> <div class="container body-content"> <h2>温度データ表示</h2> <div> <table> <tr> <td>DeviceId:</td> <td><input type="text" id="DeviceId" value="100" /></td> </tr> <tr> <td>開始日時(yyyy-mm-dd HH:MM:ss):</td> <td><input type="text" id="FromDT" value="2015-07-01 00:00:00" /></td> </tr> <tr> <td>終了日時(yyyy-mm-dd HH:MM:ss):</td> <td><input type="text" id="ToDT" value="2015-07-31 00:00:00" /></td> </tr> <tr> <td colspan="2" align="right"><button onclick="callPostMethod()">検索実行</button></td> </tr> </table> <br /> <span id="ChartPlaceHolder">ここにチャートが表示されます。</span> </div> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript"> function callPostMethod() { // jQueryを使って呼ぶ var resdata = $.ajax("/api/TemperatureDatas", { type: "GET", data: { deviceId: $("#DeviceId").val(), fromDT: $("#FromDT").val(), toDT: $("#ToDT").val() }, async: true }).then (function (resdatas) { var data = new google.visualization.DataTable(resdatas); var options = { title: '温度データ', width: 480, height: 320 }; var chart = new google.visualization.LineChart(document.getElementById('ChartPlaceHolder')); chart.draw(data, options); }); } </script> <hr /> <footer> <p>© 2015 - 株式会社インデペンデンスシステムズ横浜</p> </footer> </div> <script src="/Scripts/jquery-1.10.2.js"></script> <script src="/Scripts/bootstrap.js"></script> <script src="/Scripts/respond.js"></script> </body> </html>
まず、表示関連としてbootstrap.cssを取り込んで何となく他のビューと同じような表示になるようにしました。
次にグラフですが、JQueryでGetしたレスポンスをそのままの形式でDataTableを生成しています。ASP.NET側でライブラリを利用してDataTableの形式にしたのでここではそのまま生成できます。これを、オプションを付加して折れ線グラフで表示しています。
最後にこのグラフページの静的リンクをナビ部分に追加します。_Layout.cshtmlを編集します。以下はナビ部分のみです。
<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("ホーム", "Index", "Home", new { area = "" }, null)</li> <li>@Html.ActionLink("温度データ一覧", "Index", "TemperatureDatasDisplay", new { area = "" }, null)</li> <li><a href="~/TempDataChart.html">温度データグラフ</a></li> <li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li> </ul> </div>
その他の課題として処理中の表示や時間の入力方法等があると思いますが、正常に動作するとグラフが表示されるところまでは確認出来ましたのでここまでとします。
これで、全体としてRaspbery Pi側も含めて、温度データの蓄積と表示、グラフ表示が出来ました。まだ課題といいますと認証等いろいろと思います。また出来たら書きます。
今回の最終的なプロジェクトは以下です。
プロジェクト一式
Amazon関連商品