2018年10月23日火曜日

レーダーチャートの表示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 患者基本情報の画面
また文字のフォントや一行あたりの幅など調整していきたいと考えている。

2018年9月25日火曜日

②患者基本情報データの取得6

前回に引き続き、WebAPIを使って、ORCAから患者基本情報をとってこれるよう、プログラミングを行っていく。その際、認証情報をヘッダに書く必要がある。

まず、URLからデータを取得するためのサービスを作る。その名前を'Patient'にした。
すると、次のようなプログラムになる。
JS
.service('Patient', ['$http', function($http) {
  this.get = function() {
    $http.defaults.headers.get = {
      'Authorization' : 'Basic ' + window.btoa(g_user + ':' + g_passwd)
    };
    return $http.get('http://172.16.108.251:8000/api01rv2/patientgetv2?id=00001&format=json')
      .then(
        function(response) {  
          return response.data.patientinfores.Patient_Information;
        },
        function(response) {  
          alert('Error at Patient:' + JSON.stringify(response.data, null, 2));
        }
      );
  };
}])
図1.サービス 'Patient'

g_userとg_passwdは自分の認証情報を代入して、教えてやらなければならないので、index.jsの1番最初に次のようなプログラムをうつ。
JS
g_user = 'ormaster';
g_passwd = '[ormasterのパスワード]';
図2.ORCAのユーザ名とパスワードの設定

次はモデルとビューの架け橋となるコントローラを作る。その名前を'PatientController'にした。すると、次のようなプログラムになる。
JS
.controller('PatientController', ['$scope', 'Patient', function($scope, Patient) {
  var that = this;
 
  /* 患者情報の読み込み */
  Patient.get()
    .then(
      function(patient){
        that.Patient_ID = patient.Patient_ID;
        that.WholeName = patient.WholeName;
        that.BirthDate = patient.BirthDate;
        that.Sex = patient.Sex == '1' ? 'M' : 'F';
      }  
    );
}])
図3.コントローラ 'PatientController'

作成したPatientサービスをコントローラに注入して(1行目)、そのget()メソッドを使って患者情報を取得する(5行目)。取得した患者情報(患者ID、氏名、生年月日、性別)をコントローラのプロパティに設定し、ビュー(demographics.html)から参照できるようにした。なお、11行目は男性(patient.Sexが'1')なら'M'、女性(patient.Sexが'1'以外)なら'F'をthat.Sexに設定するコードである。
ビューではコントローラを経由して患者情報を出力する。

そして、図1と図3のプログラムを.serviceは.serviceが続いているところ、.controllerは.controllerが続いている、適切なところに挿入する。

こうしてモデル(Service)とコントローラを作成したわけであるが、ビュー(HTML)を作成しないとコントローラは動かないようである。そこで、ビュー(demographics.html)を次の図4のようにプログラミングして、患者基本情報を取得するようにする。
HTML
図4:demographics.htmlに書くプログラム

1行目でPatientControllerをpatientという変数名で参照して、9行目で患者IDをpatient.Patient_IDで、13行目で患者名をpatient.WholeNameを使って出力している


すると、図5のように、患者基本情報が取得された。
図5:患者基本情報が取得された基本情報の画面

alert(
'Success:' + JSON.stringify(response.data.patientinfores,null,2));と打って、うまく、すべての患者基本情報が取得されているのか見てみる。
すると、図6のようにうまく、すべての患者基本情報が取得されていることが分かった。
図6:alertした時の画面

AngularJSではデータを格納するモデルをサービスで、ビューをHTMLで、そして両者の橋渡しをコントローラを使って行っているのである。


次は、患者ID、氏名以外の項目も表示させられるよう、プログラムを修正していく。また、ORCAの患者データもそれらしい値を入力していく。

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

今回はメイン画面にて過去の検査結果が閲覧できるような処理を行う。

想定しているような処理は、図1の様な既にサンプルアプリに存在しているグラフ描画画面の年号選択の様なものである。検査日付を選択したら、対応したデータの表示を行いたい。
図1 グラフ画面での年号選択コンボボックス
以下は、サンプルアプリでどのように年の選択を行っているかを抜き出したものである。ビュー(HTML)とコントローラ(CountryController)の関係する部分を抜粋した。

HTML

<ons-list class="year-select-container">
   <ons-list-item>
     <select
       ng-model="country.year"
       ng-options="year for year in country.years"
       class="text-input text-input--transparent"
       style="width: 100%; margin-top: 4px">
     </select>
   </ons-list-item>
 </ons-list>
これがhtmlの記述である。4行目、および5行目を書き換えれば応用が出来そうにみえる。
次に、「country.year」が何かを確認していく。

JS

this.years = [];
  for (var i = 1950; i <= 2100; i++) {
    this.years.push('' + i);
  }

 $scope.$watch('country.year', function() {
    that.getPopulation();
  });
上記のコードはCountryController内で記述されており、なお関係があるものだけを
抜粋したものである。
行目の$scope.$watch~は指定された値を監視し、その値が変化したら処理getPopulation()を行うといったものである。
これらの処理を行う事でコンボボックスの作成を行う事が出来ることが分かったところで、我々のアプリケーションの改造へ移る。まずは検査日付の選択が行えるコンボボックスの作成を試みる。

HTML

<ons-list class="year-select-container">
            <ons-list-item>
              <select
                ng-model="countries.sampleDate"
                ng-options="sampleDate for sampleDate in countries.sampleDateList"
                class="text-input text-input--transparent"
                style="width: 100%; margin-top: 4px">
              </select>
            </ons-list-item>
          </ons-list>
上記HTMLはmain.html内に記述する。
検査日は「sampleDate」として定義されているため、ng-model,ng-optionsをそれぞれ置き換える。なお、ng-modelに指定した'countries.sampleDate'はコンボボックスにつけた変数名のようなもので、ng-optionsに指定した'countries.sampleDateList'は検査日のリストが格納されている。

JS

that.sampleDateList = [];
Countries.get()
    .then(
      function(countries) {
        countries.list.forEach(function(element){
          that.sampleDateList.push(element.sampleDate);
        });
        that.sampleDate=that.sampleDateList[0];        
        // 直近の検査日の検査結果を変数 list に格納
        that.list = countries.list;

        var list = countries.list[0];
        that.createGroup(list);
    }
);
$scope.$watch('countries.sampleDate', function() {
    //that.listからthat.list[i].sampleDate = that.sampleDateとなるthat.list[i]を取り出してthat.createGroupを呼び出す
});
これは、CountriesController内で記述を行う。まず、1行目でsampleDateListの配列を空にする。
5~7行目ではsampleDateListに検査リストに含まれている検査日の流し込みを行っている。
また、これをアラートすると、以下の図2の様になり、抽出出来ていることが分かる。

図2 sampleDateListをアラートした図
8行目は、デフォルト値の設定である。この代入をしない場合、起動直後の状態だとコンボボックスが空欄になってしまう為、こちらを参考にしそれを防止した。
10行目の定義は、OpenDolphinから取得した検査データ一覧をメモリーに保存するといった処理である。
13行目は以前のブログで記述したグルーピング処理を関数化したcreateGroupの呼び出しである。
16行目からはSampleDateの監視を行うような処理であるが、まだ未完成である。
これらの修正を行い、アプリを確認すると、以下の図3の様にコンボボックスの作成を行う事が出来た。
図3 メイン画面での日付選択のコンボボックス

次回は17行目のコメントにも書いてあるような処理の記述を行い、過去の検査結果の表示を行いたい。

【Tips】

コントローラ内で定義したプロパティ(this.sampleDateなどthis.が付いたもの)は、ビュー(HTML)内ではコントローラへの参照オブジェクト(countriesなど)のプロパティとして参照できる(countries.sampleDate)。
ビュー内でこのプロパティが変更されるとコントローラ内のプロパティも変更され、逆にコントローラ内で設定したプロパティの値はビューへ反映される。
これと同じように、コントローラ内で定義したメソッド(this.createGroup = function(list){...})も、ビューから呼び出せるのだろうか?
普通の関数とコントローラのメソッドの違いは何だろうか?
$scope$watchはコントローラのプロパティを監視し、その値が変更されたときに指定した処理を実行する命令である。これを使ってモデル(HTML)とコントローラの間で連携を実現している。いわゆる.onChangeなどのイベントリスナーと等価なものであろう。
ただし、$scope$watchを使うのがAngularJSの流儀なのかもしれない。



2018年9月20日木曜日

②患者基本情報データの取得5

前回、ORCAから患者情報をとってこれたので、あとはスマホからWebAPIを送って、これと同じものを取ってこれるよう、認証情報をヘッダに書いてやればいいだけである。

認証情報は下記のプログラムを書いてみる。(g_user、g_passwdをそれぞれORCAのユーザ名、パスワードとする

$http.defaults.headers.get = {
  'Authorization' : 'Basic ' + window.btoa(g_user + ':' + g_passwd)
};

残りのプログラミングをどう書けばいいのか分からないので、あるブログのこの記事の患者基本情報をところ、サイトサイト②を参考にして、プログラミングしてみた。

それぞれプログラミングしたのは以下の3枚である
図1:あるブログを参考にしたプログラム
図2:サイト①を参考にしたプログラム
図3:サイト②を参考にしたプログラム

どれも行ったが、いまだに認証画面が出てくるので、修正していって、うまく患者基本情報を取得していけるようにしていきたい。

【コメント】
認証のための下記のプログラムにおいて、g_userとg_passwdは変数です。文字列定数ではありません。
$http.defaults.headers.get = {
  'Authorization' : 'Basic ' + window.btoa(g_user + ':' + g_passwd)
};
ですから前もってg_userとg_passwdにはORCAのユーザ('ormaster')とパスワードを代入しておく必要があります。
g_user = 'ormaster';
g_passwd = '[ormasterのパスワード]';
定数と変数の違いに注意してください。図1~3のいずれも定数と変数を混同しています(ormasterは変数ではありません)。

【AngularJSのプログラム作法】
AngilarJSでスマホアプリを開発するにはその作法に従う必要があります。
まず、URLからデータを取得する(いわゆるWebAPI)ためのサービスを作ります。その名前を'Patient'とすると次のようなプログラムになるでしょう。
.service('Patient', ['$http', function($http) {
  this.get = function() {
    $http.defaults.headers.get = {
      'Authorization' : 'Basic ' + window.btoa(g_user + ':' + g_passwd)
    };
    return $http.get('http://172.16.108.251:8000/api01rv2/patientgetv2?id=00001&format=json')
      .then(
        function(response) {  
          return response.data.patientinfores.Patient_Information;
        },
        function(response) {  
          alert('Error at Patient:' + JSON.stringify(response.data, null, 2));
        }
      );
  };
}])
図1. サービス'Patient'

次にモデルとビューの懸け橋となるコントローラを作ります。その名前を'PatientController'とすると、プログラムは次のようになるでしょう。
.controller('PatientController', ['$scope', 'Patient', function($scope, Patient) {
  var that = this;

  /* 患者情報の読み込み */
  Patient.get()
    .then(
      function(patient){
        that.Patient_ID = patient.Patient_ID;
        that.WholeName = patient.WholeName;
        that.BirthDate = patient.BirthDate;
        that.Sex = patient.Sex == '1' ? 'M' : 'F';
      }  
    );
}])
図2. コントローラ'PatientController'

作成したPatientサービスをコントローラに注入して(1行目)、そのget()メソッドを使って患者情報を取得します(5行目)。取得した患者情報(患者ID、氏名、生年月日、性別)をコントローラのプロパティに設定し、ビュー(demographics.html)から参照できるようにします。
ビューではコントローラを経由して患者情報を出力します。
<ons-page ng-controller="PatientController as patient">
  <ons-toolbar>
    <div class="center">Demographics</div>
  </ons-toolbar>
  <ons-list>
    <ons-list-header>基本情報</ons-list-header>
    <ons-list-item>
      <ons-col width="20%">患者ID</ons-col>
      <ons-col>{{ patient.Patient_ID }}</ons-col>
    </ons-list-item>
    <ons-list-item>
      <ons-col width="20%">氏名</ons-col>
      <ons-col>{{ patient.WholeName }}</ons-col>
    </ons-list-item>
  </ons-list>
</ons-page>
図3. ビュー(demographics.html)

ここでは、1行目でPatientControllerをpatientという変数名で参照して、9行目で患者IDをpatient.Patient_IDで、13行目で患者名をpatient.WholeNameを使って出力しています。

このように、AngularJSではデータを格納するモデルをサービスで、ビューをHTMLで、そして両者の橋渡しをコントローラを使って行います。このことを念頭に置いてプログラムの設計を行う必要があります。

4検査結果表示について⑤

今回は前回グルーピングを行ったグループ名の項目が少々小さく、見づらい為、cssの編集を行っていく。
<ons-list-header>{{ group.groupName }}</ons-list-header>
まずhtmlの上記コードを下記の様にする
<ons-list-header class="group">{{ group.groupName }}</ons-list-header>
この処理はons-list-header にクラス属性を付与するといったものである。今回は名称をgroupとしている。
次にcssファイルに下記のコードを記述する。
ons-list-header.group{
    font-size:30px;
    background-color: rgb(71, 228, 92);
    height: 35px;
    padding-top:3px;
}
上記のコードは先ほど定義したクラスに対する詳細設定である。フォントサイズ、背景色、高さ、高さの調節等を行っている。
図1 CSSでグループ名を装飾した結果

これらの処理を行った後、アプリケーションにて確認すると上記図1の様にグループ名を見やすくすることが出来た。
次回は指定した日付に対応する配列要素を抽出するといったコードの記述を行っていきたい。

【コメント】
検査項目をグルーピングして表示する件についてはこれで完成ですね。
次へ進んでいきましょう。

2018年9月14日金曜日

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

前回のコメントを参考にしながら再び編集を試みた。
function(countries) {
var list = countries.list[0];
that.list = [];
list.items.forEach(function(element){
var normalValue =  element.normalValue.split(/-/);
var lower = parseFloat(normalValue[0]);
var upper = parseFloat(normalValue[1]);
var bgColor;
if(element.value >= lower && element.value <= upper){
bgColor ="normal";}else{
bgColor ="abnormal";
}
that.list.push(
{
itemName:element.itemName,
value:Math.round(element.value *100) /100 ,
unit:element.unit,
bgColor:bgColor
}
);
});
まず、上記のリスト配列を、下記のものに差し替える。
function(countries) {
// 直近の検査日の検査結果を変数 list に格納
var list = countries.list[0];
// 検査グループ配列を空配列に初期化
that.group = [];
// 個々の検査グループを格納するための一変数を null で初期化
var group = null;
// 検査結果項目配列 list.items の個々の要素 element に対してループ処理
list.items.forEach(function(element){
// elementが一番最初の検査結果項目の場合、groupを初期化する
if(group == null) {
group = {
'groupName': element.groupName,
'items': []
};
// 検査グループが変わったとき、groupを検査グループ配列に追加してからgroupを初期化する
} else if(group.groupName != element.groupName){
that.group.push(group);
group = {
'groupName': element.groupName,
'items': []
};
}
// 基準値を求めて normalValue 変数に格納する
var normalValue = getNormalValueRange(element.normalValue);
// 基準値と検査結果を比較して背景色を決める
var bgColor;
if(element.value >= normalValue.lower && element.value <= normalValue.upper){
bgColor ="normal";}else{
bgColor ="abnormal";
}
// グループに検査結果を追加する
group.items.push(
{
'itemName': element.itemName,
'value': round(element.value),  //  四捨五入
'unit': element.unit,
'bgColor': bgColor,
}
);
});
// 最後のgroupを検査グループ配列に追加する
if(group != null) {
that.group.push(group);
}
}
);
また、getNormalValueRange関数およびround関数の定義を以下の様に行った。
/*
基準値の下限と上限を求める
*/
function getNormalValueRange(normalValue) {
var normalValue = normalValue.split(/-/);
var lower = parseFloat(normalValue[0]);
var upper = parseFloat(normalValue[1]);
return {
lower: lower,
upper: upper,
};  
}

/*
四捨五入(小数第3位)
*/
function round(value) {
return Math.round(value * 100) / 100;
}
jsのグループ対応付けが完了したところで、次にHTMLの編集を行う。
<ons-list>
<ons-list-item class="{{country.bgColor}}"  ng-click="countries.showCountry(country.itemName)" modifier="chevron" ng-repeat="country in countries.list | filter:query">
<ons-col width="50%">{{ country.itemName }}</ons-col>
<ons-col>{{country.value}}</ons-col>
<ons-col>{{country.unit}}</ons-col>
</ons-list-item>
</ons-list>
HTMLのこの記述を、以前のブログのコメントに記載されていたこの形式に書き換えた。
<ons-list ng-repeat="group in countries.group">
<ons-list-header>{{ group.groupName }}</ons-list-header>
<ons-list-item class="{{country.bgColor}}" ng-click="countries.showCountry(country.itemName)" modifier="chevron" ng-repeat="country in group.items | filter:query">
<ons-col width="65%">{{ country.itemName }}</ons-col>
<ons-col>{{ country.value }}{{ country.unit }}</ons-col>
</ons-list-item>
</ons-list>
上記の書き換えを行った後、スマートフォンで確認したところ、以下の図1の様な結果が表示された。
図1 グルーピング処理を行った後の画面

こうして、なんとかグループごとに検査項目の表示を行う事が出来た。
次回は過去の検査データの表示が行えるような処理を行っていきたい。

【コメント】
検査項目のグルーピングができました。過去の検査データは 配列countries.listの中に入っています。だから、3行目の
var list = countries.list[0];
で、指定した日付に対応する配列要素を取り出せばよいでしょう(この場合は先頭の配列要素を取り出しているので直近の検査結果になっています)。やってみてください。

その前に、図1に表示された検査グループ名称「生化学的検査」ですが、デフォルトの表示だと控えめすぎるので、もっと存在感を出した方が良いように思います。 例えばCARADA健診手帳のような画面を参考にしてCSSを使って画面をデザインしてはどうでしょう?

2018年9月13日木曜日

①患者基本情報項目4


カラダパレッドのグラフが表示されない問題だが、今回あらためてアプリケーションを初期化し、検査データを各種サイトを参考に基準値を入力しグラフが表示されるか試みた。

データは9月11日~9月14日の4日間データ入力をした。

図1 検査値の入力
検査データの入力画面で記入をしてもグラフに表示が出ることはなかった、しかし図3の画面で記入のマークを押すことで直接血圧や体重等のデータを入力できることが分かった。

図2 トップの画面


図3 グラフの画面
図3から直接データを入力した結果グラフを表示させることができた。

<検査データ入力の際基準値として参照したサイト>

臨床検査値の基準値 

「腹囲」

血糖値

HDLコレステロール

「尿検査」

「肝検査」

上記に上げたサイトは2018/9/13に参照したものである。

またアプリのデザインですが、項目ごとにイラストをいれて分かりやすいようにできればと考えているがなかなか適したものが見つからず難しい。より見やすいよなアプリケーションを作りたい。


【コメント】
これまでいろいろなアプリを見てきました。どれもカラフルで見やすいですね。画面のレイアウト(デザイン)はCSSを使います。そろそろMonacaでCSSを使って画面のデザイン(色を付けたりフォントを大きくしたり・・・)を試してみてはどうでしょうか?

2018年9月11日火曜日

②患者基本情報データの取得4

前回、「http://172.16.108.251:8000/api01rv2/patientgetv2?id=00001&format=json」このURLを打ち込んでも、エラーばかりが発生して、何も表示されない状況に陥ったが、その原因は、ORCA自体がおかしくなっていたということが判明して。
なので、「sudo service jma-receipt restart」このコマンドでORCAの再起動を行った。

そうすると、うまく図1のような画面が表示された。
図1:URLを入れて打ち込んだ結果
ブラウザはJSONを解釈できないから、ブラウザの機能を使って、JSONの中身を見る。今回はgoogle Chromeを使っているので、右ボタンをクリックして、「ページのソースを表示」を押すと、図2のような画面が出てきて、JSONの中身をみることができた。
図2:JSONの中身を表示した結果

これを見やすくするため、JSON整形ツールを使って、整形してみた。

{
  "patientinfores": {
    "Information_Date": "2018-09-11",
    "Information_Time": "14:45:07",
    "Api_Result": "00",
    "Api_Result_Message": "処理終了",
    "Reskey": "Patient Info",
    "Patient_Information": {
      "Patient_ID": "00001",
      "WholeName": "山下 浩介",
      "WholeName_inKana": "ヤマシタ コウスケ",
      "BirthDate": "1970-12-06",
      "Sex": "1",
      "HouseHolder_WholeName": "山下 浩介",
      "Home_Address_Information": {
        "Address_ZipCode": "*******",
        "WholeAddress1": "岡山県**市**",
        "WholeAddress2": "*丁目*−*",
        "PhoneNumber1": "***-**-****"
      },
      "Contraindication1": "********",
      "Contraindication2": "禁忌2",
      "Allergy1": "********",
      "Allergy2": "アレルギー2",
      "Infection1": "********",
      "Infection2": "感染症2",
      "Comment1": "********",
      "Comment2": "コメント2",
      "TestPatient_Flag": "0",
      "NickName": "カルテ例1 P56",
      "Reduction_Reason": "00",
      "Reduction_Reason_Name": "該当なし",
      "Discount": "00",
      "Discount_Name": "該当なし",
      "Condition1": "00",
      "Condition1_Name": "該当なし",
      "Condition2": "00",
      "Condition2_Name": "該当なし",
      "Condition3": "00",
      "Condition3_Name": "該当なし",
      "Ic_Code": "01",
      "Ic_Code_Name": "現金",
      "Community_Cid_Agree": "False",
      "FirstVisit_Date": "2017-12-18",
      "LastVisit_Date": "2018-01-17",
      "HealthInsurance_Information": [
        {
          "Insurance_Combination_Number": "0001",
          "InsuranceCombination_Rate_Admission": "0.30",
          "InsuranceCombination_Rate_Outpatient": "0.30",
          "Insurance_Nondisplay": "N",
          "InsuranceProvider_Class": "009",
          "InsuranceProvider_Number": "01400019",
          "InsuranceProvider_WholeName": "協会",
          "HealthInsuredPerson_Symbol": "41061242",
          "HealthInsuredPerson_Number": "9635",
          "RelationToInsuredPerson": "1",
          "HealthInsuredPerson_WholeName": "山下 浩介",
          "Certificate_StartDate": "2017-10-25",
          "Certificate_ExpiredDate": "9999-12-31",
          "Insurance_CheckDate": "2017-10-25"
        },
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {},
        {}
      ]
    }
  }
}

図3のORCAの画面と比較してみると
図3:ORCAの患者IDが1の患者さんの患者情報

うまくORCAから患者情報をとってこれていると分かる。

あとは、スマホからWebAPIを送って、これと同じものを取ってこれるよう、認証情報をヘッダに書いてやればいい。
前回も書いたように、あるブログのこの記事の患者基本情報のところと、HTTPリクエスト時のヘッダー情報の設定にこのサイトが参考になると考えた。
また、このサイトも参考にしてみたりした。
これらを参考にして、プログラムを行っているところである。患者情報を取得するには、あるブログのある記事に書いていたものをどのように変更していけば、うまくいくのか、よく分からないので、さまざまなパターンをプログラムしていっている段階である。ここで苦戦中なので、しっかりと研究を追い込んで、やっていきたい。

【コメント】
このサイトにはHTTPリクエスト時にヘッダー情報を設定する方法が書かれているので参考になりますね。
g_user、g_passwdをそれぞれORCAのユーザ名、パスワードとすると、次のようにして認証情報を書けばよいのでしょうね。
$http.defaults.headers.get = {
  'Authorization' : 'Basic ' + window.btoa(g_user + ':' + g_passwd)
};
試してみてください。

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

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