2018年10月30日火曜日

レーダーチャートの表示2

前回レーダーチャートの表示を行うことが出来たので、今回は実際の値を代入したグラフの描画を試みる。
.controller('RaderChartController', ['$scope', 'Countries', function($scope, Countries) {
  var that = this;
  var itemNames = ["中性脂肪(TG)", "HDLコレステロール", "LDLコレステロール", "血糖", "HbA1c(JDS)", "GOT(AST)", "GPT(ALT)","ガンマ-GTP"];
  var labels = ["最新","前回","前々回"];
  var backgroundColors = ["rgba(153,255,51,0.4)","rgba(255,153,0,0.4)","rgba(0,153,255,0.4)"];
  var borderColors = ["rgba(153,255,51,1)","rgba(255,153,0,1)","rgba(0,153,255,1)"];
 that.ResultDataList = []
   Countries.get()
    .then(
      function(countries) {        
        countries.list.forEach(function(element){
          that.ResultDataList.push(element);
        });
    }
  );
$scope.tab.on('postchange', function() {
  //alert(JSON.stringify(that.ResultDataList[0],null,2));
  var i = 1;
  var datasets =[];
  that.ResultDataList.forEach(function(element){
    if(i<=3){
      var data=[0,0,0,0,0,0,0,0];
      element.items.forEach(function(item){
        var idx = itemNames.indexOf(item.itemName);
        if(idx>=0){
          //alert(idx+":"+item.itemName);
          data[idx] = item.value;
        }
      });
     // alert(JSON.stringify(data,null,2));
      datasets.push({
        'label': labels[i-1],
        'backgroundColor': backgroundColors[i-1],
        'borderColor': borderColors[i-1],
        'data': data
      });
    }
    i++;
  });
  //alert(JSON.stringify(datasets,null,2));
//レーダーチャート
  var ctx = document.getElementById("pie-chart-area");
  var myChart = new Chart(ctx, {
    type: 'radar',
    data: {
      'labels': itemNames,
      'datasets':datasets
     }
    });
  });
}])
3行目はレーダーチャートに表示する検査項目名のテーブルである。
4行目~6行目はレーダーチャートに描く3回分の検査のためのラベル、背景色、境界色のテーブルである。
まず、7行目で過去3回分の検査結果を格納するための配列ResultDataListの定義を行い、8行目~15行目で検査一覧を取得し、その一つ一つをResultDataListへプッシュしている。
16行目は、7~15行目の処理が非同期で行われるため、その処理が行われる前に17行目以降の処理が行われてしまうとデータがないままレーダーチャートを作成しようとするので、それを回避するため、タブがタップされた際に実行するようにする監視処理である。
その際、HTMLファイルのタブバーを定義しているons-tabbarタグに変数名 tab を定義しておく。
18行目はループ制御変数 i の定義である。これを使って過去3回分の検査を取り出す。
19行目は47行目でレーダーチャート描画関数に与えるパラメータとなるdatasetsというテーブルの定義である。
20行目はResultDataListに格納された過去の検査を一日分ずつ処理するものであり、
21行目から29行目はif文を使って過去3回分だけ該当する検査結果を取り出している。
今回表示したいレーダーチャートのデータは最新、前回、前々回の3回分であるから、繰り返す処理を先ほど定義したループ制御変数 i を用いて i が3以下のときにこの処理を繰り返すように制御している。
22行目は検査結果を格納するdataテーブルの定義をしており、レーダーチャートで扱うデータ数である8つの要素を0で初期化値している。
23~28行目はelement.items、つまり個々の検査項目に対する処理を行っている。
24行目では、当該検査項目が3行目に定義した検査項目名に一致しているかを判定するための処理を行っている。
ここで使っているindexOfというメソッドは、例えば var x = ['abc', 'def', 'ghi'] というテーブルがある場合、var idx = x.indexOf('abc') とすれば、idxの値は 0 になり、var idx = x.indeOf('ghi') とすれば idx の値は2になるといった感じで、テーブルに存在する値が何番目であるのかを返す関数である。また、テーブルに含まれていない場合は idx は-1となる。
3行目で定義している検査名テーブル itemNames に対してこのメソッドを使用することによって、item.itemNameが対象検査項目であるかどうかを判定し、25行目で idx が0以上であれば、27行目で22行目に定義した空のdataテーブルに検査値を代入している。
この様な処理を行う事で、dataテーブルに3行目に定義した検査項目名の順に検査値を設定することができる。
31行目~36行目ではこうして得られた1回分の検査情報をdatasetsテーブルにpushしている処理である。
{
        label: 'apples',
        backgroundColor: "rgba(153,255,51,0.4)",
        borderColor: "rgba(153,255,51,1)",
        data: [12, 19, 3, 17, 28, 24, 7]
      }
上記の書式は、前回のブログで紹介したレーダーチャートのデータを記述する際の書式であるが、32行目~35行目ではこの書式に合わせて19行目で定義したdatasetsテーブルへと挿入している。
32行目のlabelは4行目のlabelsから、backgroundColorは5行目のbackgroundColorsから、borderColorは6行目のborderColorsから、
そしてdataは先ほど検査値を代入した22行目のdataからそれぞれ持ってきている。その際、配列の添え字が[i-1]となっているのは i は1から始まっているので、i のままだとテーブルの二つ目から使ってしまうことになるのでこのようにしている。
38行目で i の値に1を足し、再び21行目からの処理を i が3になるまで繰り返している。
最後にレーダーチャート描画関数に与えるパラメータを、46行目であれば3行目のitemNamesに、47行目であれば31行目のdatasetsに設定することで、
常に最新の3件のデータを表示するレーダーチャートを描画できる。
図1 レーダーチャート完成図

上図は実際に確認した結果であるが、データ通りに取得できていることが分かる。
しかし、このレーダーチャートには少々改善の余地がある。
まず、中性脂肪の値が112程度に対して、HbA1cは8.2程しかないにも拘わらず、レーダーチャートの座標のスケールが検査値の大きい検査項目に合わされているため、HbA1cは値が小さすぎて中心近くにプロットされてしまう。レーダーチャートはどの項目が突出して大きいとか小さいとかを可視化するためのものであるから、これでは、レーダーチャートにした意味がない。検査ごとに座標のスケールを変えることはできないだろうか。
また、基準値の範囲をレーダーチャート中に示すことができればより直観的に健康状態を把握できるのではないだろうか。

課題はまだまだ多く存在するが、レーダーチャートのデータ取得が行えるようになった所で本研究は一区切りとさせていただく。

2018年10月23日火曜日

卒業論文の構成

 卒業研究が終盤に差し掛かっているため、本日、同時に卒業論文の構成について考えた。
 論文の大きい流れを決め、その中を細かく書きまとめた(図1~3)。


図1.卒業論文の構成1

図2.卒業論文の構成2

図3.卒業論文の構成3

 大体の構成を決めることが出来た為、確認・修正を行ったのち、分担を決めて次に進めていきたいと思う。 
 

レーダーチャートの表示1

今回は関連した検査項目を視覚的に把握出来る様なレーダーチャートの実装を試みる。
まず、レーダーチャートを導入するにあたって、「chart.js」の実装が必要という事が分かった。
そこでこちらをhttps://press.monaca.io/atsushi/230参考にしてchart.jsの実装を行っていく。
まず、MONACAの設定タブからJS/CSSコンポーネントの追加と削除をクリックする。

図1JS/CSSコンポーネント検索画面
そして、上記図1の様に検索欄に「Chart」と入力を行う。その後表示されている「Chart.js」の追加をクリックする。
図2 追加をクリックした際のポップアップ

その後、上記図2の様なポップアップが表示されるのでインストールをクリックする。
図3 ファイル選択画面

インストールをクリックすると、上記図3の様なchart.js内で読み込みを行うファイルの選択を行う事が出来るので、
「components/chart.js/dist/Chart.min.js」にチェックを入れ、保存をする。
これでChart.jsの導入が完了したので、プログラムの修正を行っていく。
【HTML】
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
:
中略
:
<body>
      <ons-template id="tab.html">
        <ons-page>
          <ons-tabbar>
            <ons-tab page="radarchart.html" label="レーダーチャート" icon="ion-ios-pie-outline">
            </ons-tab>            
 </ons-tabbar>
        </ons-page>
     </ons-template>
:
中略
:
      <ons-template id="radarchart.html">
        <ons-page ng-controller="RaderChartController as raderchart">
          <ons-toolbar>
            <div class="center">レーダーチャート</div>
          </ons-toolbar>
          <div id="canvas-holder" style="width:100%">
            <h1>Bar chart</h1>
            <canvas id="pie-chart-area" width="300" height="300">
            </canvas>
          </div>
        </ons-page>
      </ons-template>
まず、2行目のheadに先ほど実装したchart.jsをCDN(Content Delivery Network)で取得する。
次に、bodyにレーダーチャートを表示するページの作成を行う。
7行目にレーダーチャートを表示するタブバーの定義を行い、
18行目にビューの作成、 19行目ではコントローラーの指定を行い対応付けを行う。
20~22行目はツールバーの記述、25行目ではグラフの書式設定を行っている。

【JavaScript】
.controller('RaderChartController', ['$scope', 'Countries', function($scope, Countries) {
  var that = this;
  //レーダーチャート
  var ctx = document.getElementById("pie-chart-area");
  var myChart = new Chart(ctx, {
    type: 'radar',
    data: {
      labels: ["M", "T", "W", "T", "F", "S", "S"],
      datasets: [{
        label: 'apples',
        backgroundColor: "rgba(153,255,51,0.4)",
        borderColor: "rgba(153,255,51,1)",
        data: [12, 19, 3, 17, 28, 24, 7]
      }, {
        label: 'oranges',
        backgroundColor: "rgba(255,153,0,0.4)",
        borderColor: "rgba(255,153,0,1)",
        data: [30, 29, 5, 5, 20, 3, 10]
      }]
    }
  });
}])
まず、1行目でコントローラの作成を行う。名称はHTMLで定義したRaderChartControllerにする。
3行目からはこちらhttps://www.webprofessional.jp/introduction-chart-js-2-0-six-examples/を参考にして
レーダーチャートの描く関数の記述である。

図4 レーダーチャート画面
HTMLとJavascriptの編集を終えた後、スマートフォンで確認をすると上記図4の様にレーダーチャートの記述が行う事が出来た。
次回はサンプルデータではなく、実際の検査データの抽出を行い、レーダーチャートに表示を行えるようにしたい。

2018年10月9日火曜日

患者基本情報の取得と画面に表示

前回、患者ID、氏名を患者基本情報画面に表示することが出来たので、今回は、患者ID、氏名以外の患者基本情報も画面に表示させれるよう、プログラムを修正していく。

まずはORCAの****のところをそれらしい患者データを入れていく。
図1のように患者データを入れた。
図1:ORCAの患者基本情報の画面
あとは、残りの患者基本情報を画面に表示させていく。
HTMLを図2のように修正した。


HTML
<ons-page ng-controller="PatientController as patient">

  <ons-toolbar>
    <div class="center">基本情報</div>
  </ons-toolbar>

   <ons-list>
    <ons-list-header>
       <h1>個人情報</h1>
      </ons-list-header>
   </ons-list>    

  <div class="haikei">
    <ons-list-item>
      <ons-col width="30%"> <h6>氏名</h6> </ons-col>
      <ons-col><h4>{{ patient.WholeName }}</h4></ons-col>
    </ons-list-item>
   </div>

  <div class="haikei2">
    <ons-list-item>
      <ons-col width="30%"> <h6>シメイ</h6> </ons-col>
      <ons-col><h4>{{ patient.WholeName_inKana }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei">
   <ons-list-item>
      <ons-col width="30%"> <h6>患者ID</h6> </ons-col>
      <ons-col><h4>{{ patient.Patient_ID }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei2">
    <ons-list-item>
      <ons-col width="30%"> <h6>性別</h6> </ons-col>
      <ons-col><h4>{{ patient.Sex }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei">
    <ons-list-item>
      <ons-col width="30%"> <h6>生年月日</h6> </ons-col>
      <ons-col><h4>{{ patient.BirthDate }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei2">
    <ons-list-item>
      <ons-col width="30%"> <h6>住所</h6> </ons-col>
      <ons-col><h4>{{ patient.WholeAddress1 }}</h4></ons-col>
    </ons-list-item>
  </div>


   <ons-list>
    <ons-list-header><h1>アレルギー等</h1></ons-list-header>
   </ons-list> 

  <div class="haikei3">
    <ons-list-item>
      <ons-col width="30%"> <h6>アレルギー</h6> </ons-col>
      <ons-col><h4>{{ patient.Allergy1 }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei4">
    <ons-list-item>
      <ons-col width="30%"> <h6>感染症</h6> </ons-col>
      <ons-col><h4>{{ patient.Infection1 }}</h4></ons-col>
    </ons-list-item>
  </div>

  <div class="haikei3">
    <ons-list-item>
      <ons-col width="30%"> <h6>禁忌</h6> </ons-col>
      <ons-col><h4>{{ patient.Contraindication1 }}</h4></ons-col>
    </ons-list-item>
  </div>


   <ons-list>
    <ons-list-header><h1>コメント</h1></ons-list-header>
   </ons-list> 

  <div class="haikei5">
    <ons-list-item>
      <ons-col width="30%"> <h6>コメント</h6> </ons-col>
      <ons-col><h4>{{ patient.Comment1 }}</h4></ons-col>
    </ons-list-item>
  </div>


  </ons-list>
</ons-page>
                             図2:患者基本情報を画面に表示させるプログラム(HTML)

次に、javaを図3のように修正した。
JS
Patient.get()
    .then(
      function(patient){
        that.Patient_ID = patient.Patient_ID;
        that.WholeName = patient.WholeName;
        that.BirthDate = patient.BirthDate;
        that.Sex = patient.Sex == '1' ? '男性' : '女性';
        that.WholeName_inKana = patient.WholeName_inKana;
        that.WholeAddress1 = patient.Home_Address_Information.WholeAddress1;
        that.Allergy1 = patient.Allergy1;
        that.Infection1 = patient.Infection1;
        that.Contraindication1 = patient.Contraindication1;
        that.Comment1 = patient.Comment1;
      }  
    );
}])
            図3:患者基本情報を画面に表示させるプログラム(java)

そしたら、図4、図5のように、図1の患者基本情報が画面に表示された。
(分かりやすいように色付け、グルーピングした)
図4:アプリの患者基本情報の画面1

図5:アプリの患者基本情報の画面2

これで、うまく患者ID、氏名以外も患者基本情報画面に表示させれるようにできた。
あとは、それぞれで作成したプログラムを合わせて、1つの完成形のアプリにしていきたい。

2018年10月2日火曜日

④検査結果表示について7

今回は、前回作成した日付のコンボボックスを変更した場合、対応した検査データのリストを表示するといった処理を行う。
考え方としては、that.sampleDateとthat.listの各検査のsampleDateが等しいときに対応した検査データを抽出してlistへ代入するといった感じだ。
この考え方であれば、createGroupの中で動作を行う方が好ましいので、先にCountries.get()内に記述されている検査項目を作成する
var list = countries.list[0]
that createGroup(list);

上記のプログラムの赤字部分を削除する。次に実際にcreateGroupの中へ記述を行っていく。
this.createGroup = function(list){
        var list = [];
        that.list.forEach(function(element){
          if(that.sampleDate == element.sampleDate){
            list = element;
          }
        });
 :
 :
 中略
 :
 :
});
まず2行目でlistの定義並びに配列を空にしている。これは一度しか参照しないlistの値を初期化する為である。
3~7行目は条件式の記述である。もし、that.sampleDateとelement.sampleDateが同じであれば、listへ各項目を代入するといった処理である。
次に、that.listが変更された場合にこのプログラムが実行されるように、that.listを監視している$scope.$wacthの内部へ以下の様な記述を行う。
$scope.$watch('countries.sampleDate', function() {
          that.createGroup();
    }
上記のプログラムは、countries.sampleDateの値が動いた場合、that.createGroupを実行するといったプログラムである。

これらの処理を行った後、アプリケーションの方で確認を行うと、
検査項目リスト自体は日付を変更すると対応したリストで作成するといった想定した動作を行ったのだが、「that.sampleDate undefined that.list.forEach」というエラーメッセージが表示されていた。
考えられる原因のひとつとして、前回記述したデフォルト値の設定である
that.sampleDate=that.sampleDateList[0];
の位置が悪いのではないだろうかという事で、countriesget内で移動をさせたのだが、改善は見られなかった。
次に、countries.getとcreateGroup内でalertを発生させ、処理の順番がどの様になっているのかを確認した。
countries.getでは「代入しました」、createGroup内では「createGroupに入りました SampleDate値」をアラートさせた。
図1 アラート結果

アラート結果を見ると、上記図1のような流れになっていた。まずはじめにcreateGroupが実行されsampleDate値は空、2番目にcountries.getが実行、
3、4番目に再びcreateGroupが実行されており、sampleDate値は直近の物になっていた。

どうやらcountries.getよりも先にcreateGroupが実行されている為、この様なエラーメッセージが表示されているのだろう。
解決策として、sampleDateの値が空である場合はcreateGroupを実行させないといった処理を行えば良いのではないだろうか。
そこで、$scope.$watch内の記述を以下の様に書き換える。
$scope.$watch('countries.sampleDate', function() {
    if(that.sampleDate){
      that.createGroup();
    }
この条件式は、「that.sampleDateに値があるならば、that.createGroupを実行する」といった条件式である。
上記の記述を行った後、確認を行うとcountries.getから先に実行され、先ほどのエラーメッセージが表示されることはなくなった。
が、アラートからもわかるようになぜか二回createGroupの呼び出しを行っていることがわかる。これはcountries.get内でもthat.creatGroupの呼び出しを行っている為である。
$scope.$watch上で実行している以上無意味な記述であるため、削除を行った。
図2 5/6の検査結果リスト
図3 5/5の検査リスト

これらの処理を行った後確認をすると、上記図2,3の様に日付を変更するたびに対応したデータの表示を行う事に成功した。

次回は関連した検査データごとのレーダーチャートの作成を目指したい。

2018年10月1日月曜日

患者基本情報作成①

今回では、患者基本情報で表示する項目とHTMLとCSSを使った実際の画面設計をした。


項目数は9項目で、
「氏名」、「氏名(フリガナ)」、「患者ID」、「性別」、「生年月日」、「住所」、「アレルギー」、「感染症」、「禁忌」

この項目に絞った。

HTMLでClassを指定すると共に、図1のように各項目を追加した。

<div class="haikei">
    <ons-list-item>
      <ons-col width="30%"> <h6>氏名</h6> </ons-col>
      <ons-col>{{ patient.Patient_ID }}</ons-col>
    </ons-list-item>
図1 HTML 患者基本情報の項目追加

またデザインとしては、CSSでClass=haikeiのbackcolorを変更した。

.haikei{
    background-color: #D7EEFF;
}
図2 CSS 背景の色の変更

結果としては図3-図4のようになった、データはまだ取り込めていないが今後表示できるように取り組んで行きたいと考えている。


図3 患者基本情報の画面

図4 患者基本情報の画面
また文字のフォントや一行あたりの幅など調整していきたいと考えている。

レーダーチャートの表示2

前回 レーダーチャートの表示を行うことが出来たので、今回は実際の値を代入したグラフの描画を試みる。 .controller('RaderChartController', ['$scope', 'Countries', funct...