2018年7月4日水曜日

MONACAのサンプルアプリ編集3

前回は、Populationサービスを使ってOpenDolphinの検査データから、前の画面で選択した検査項目の時系列データを取得する処理を作成した。今回は、この取得したデータを使ってグラフを描画するためのデータ加工処理、およびグラフ描画を行う。
.controller('PopulationChartController', ['$scope', function($scope) {
  $scope.formatData = function() {
    if (!$scope.data) {
      return [];
    }
      alert(JSON.stringify($scope.data,null,2));

    var total = [],
      males = [],
      females =[];

    for (var i = 0; i < $scope.data.length; i++) {
      var data = $scope.data[i];

      total.push({x: data.age, y: data.total});
      males.push({x: data.age, y: data.males});
      females.push({x: data.age, y: data.females});
    }
まず、Javascriptの上記「poplationchartController」の12行目からのプログラムを以下のものに書き換える。
$scope.data.forEach(function(item){
      var strDate = item.sampleDate.replace(/ /g, ' 02:');
      var sampleDate =Date.parse(strDate.replace(/-/g, '/'));
      var value =parseFloat(item.value);
      var normalValue = item.normalValue.split(/-/);
      var lower = parseFloat(normalValue[0]);
      var upper = parseFloat(normalValue[1]);

      total.push({x: sampleDate, y: upper});
      males.push({x: sampleDate, y: value});
      females.push({x: sampleDate, y: lower});
    });

    return [
      {
        key: '上限',
        values: total
      },
      {
        key: '下限',
        values: females
      },
      {
        key: '検査結果',
        values: males
      }
    ];
  };
OpenDolphinから取得した検査結果は以前のブログに書いたように次のようなフォーマットをしている。
{
  "list": [
    {
      "progressState": null,
      "items": [
        {
          "laboCode": null,
          "lipemia": null,
          "hemolysis": null,
          "dialysis": null,
          "reportStatus": "E",
          "groupCode": "01",
          "groupName": "生化学的検査",
          "parentCode": "0001",
          "medisCode": "3J010000002327101",
          "itemName": "総ビリルビン",
          "abnormalFlg": null,
          "normalValue": "0.2-1.2",
          "specimenCode": "023",
          "specimenName": "血清",
          "commentCode1": null,
          "comment1": null,
          "commentCode2": null,
          "comment2": null,
          "sortKey": null,
          "itemCode": "0001",
          "sampleDate": "2018-05-06 00:00",
          "patientId": "1.3.6.1.4.1.9414.70.1:00001",
          "unit": "mg/dL",
          "value": "0.4",
          "id": 1120
        },
       ・
       ・
       ・     
      (中略)
       ・
       ・
       ・
        {
          "laboCode": null,
          "lipemia": null,
          "hemolysis": null,
          "dialysis": null,
          "reportStatus": "E",
          "groupCode": "07",
          "groupName": "一般検査",
          "parentCode": "0493",
          "medisCode": "1B040130201506211",
          "itemName": "便中ヒトヘモ定性2日目",
          "abnormalFlg": null,
          "normalValue": "陰性",
          "specimenCode": "015",
          "specimenName": "便",
          "commentCode1": null,
          "comment1": null,
          "commentCode2": null,
          "comment2": null,
          "sortKey": null,
          "itemCode": "0493",
          "sampleDate": "2018-05-04 00:00",
          "patientId": "1.3.6.1.4.1.9414.70.1:00001",
          "unit": null,
          "value": "インセイ",
          "id": 1084
        }
      ],
      "sampleDate": "2018-05-04 00:00",
      "laboCenterCode": "LSCC",
      "moduleKey": "LSCC2018050442011",
      "reportFormat": null,
      "patientName": "山下 浩介",
      "patientSex": "M",
      "numOfItems": null,
      "patientId": "1.3.6.1.4.1.9414.70.1:00001",
      "id": 1051
    }
  ]
}
この中で、検査日時はsampleDateで、「2018-06-06 00:00」という形式になっている。Javascriptで日時として認識されるデータは「2018/06/06 00:00:00」という形式なので、これを正規表現を使って適切な書式に書き換える。
var strDate = item.sampleDate.replace(/ /g, ' 02:');
まず、「strDate」という変数を定義し、検査日時item.sampleDate中のスペースを「 02:」に置き換える。これにより、元の時刻「00:00」を「02:00:00」という時分秒の形式に置き換えることができる。なお、「02:00:00」は午前2時0分0秒を意味するが、この時間には意味がない。「01:00:00」でも何でもよかった。
var sampleDate =Date.parse(strDate.replace(/-/g, '/'));
次に、strDate.replace(/-/g, '/')で「strDate」の中の「-」を「/」へ置き換えて、日付「2018-06-06」を「2018/06/06」という形式に変換し、「Date.parse」という命令により文字列の日時をJavascriptの日時オブジェクトに変換する(Javascriptの日付オブジェクトは基準日時からの経過秒で表現されている)。これらの置き換え作業によって、検査日時を変数「sampleDate」に設定できた。
 var value =parseFloat(item.value);
これは、検査値「item.value」を「paresFloat」命令で文字列から実数値に変換し、変数「value」に代入しているところである。
var normalValue = item.normalValue.split(/-/);
var lower = parseFloat(normalValue[0]);
var upper = parseFloat(normalValue[1]);
これは「item.normalValue」に入っている検査の基準値を上限と下限に分離して、それぞれ変数「upper」と「lower」に格納する処理である。item.normalValueの中に格納されている値は「0-10」という書式になっているので、「-」を区切り文字として、「-」の前後で数字を分ける。例えば、「0.2-1.2」という値であれば、「0.2」と「1.2」の二つの値に分け、それぞれを下限値、上限値とする。
そのために、splitメソッドを使う。item.normalValue.split(/-/)は、item.normalValueの中身を「-」を区切り文字として分割し、その結果を配列に格納する。したがって変数「normalvalue」の先頭要素「normalValue[0]」には下限値が、2番目の要素「normalValue[1]」には上限値が格納される。
こうして得られた下限値・上限値をparseFloat関数を使って実数値に変換し、それぞれ変数「lower」,「upper」へ代入する。
total.push({x: sampleDate, y: upper});
males.push({x: sampleDate, y: value});
females.push({x: sampleDate, y: lower});

こうして 検査日時、検査結果、基準値の下限値・上限値が得られたので配列「total」へは上限値を、配列「males」へは検査値を、そして配列「females」へは下限値を、それぞれ追加している。
これらの処理により、グラフの描画が行えるようになった。
実際にスマートフォンの方で確認したところ、図1の様な画面が表示され、グラフの描画を行うことが出来た。
図1 検査結果グラフ
ただし、このグラフは折れ線グラフではなく、積み上げグラフになっている。これは、元のアプリがそのような仕様になっているからである。また、X軸の目盛りが日付ではなく数値になっている。これはJavascriptの日付オブジェクトの内部形式(基準日時からの経過秒)がそのまま表示されているからである。さらに、Y軸に単位が表示されていない。
次回は折れ線グラフになるように、そして、X軸の目盛りが日付に、Y軸に単位を表示するように修正を行っていきたい。
 それからもう一つ。全画面の検査一覧画面に検査結果が表示されていない。基準値外であれば色をつけて強調するなどしたい。
 また、単に折れ線グラフだけでなく検査項目に応じたグラフ表示も考えたい。
 さらに、検査項目によっては、複数の項目を比較しながら見たいケースがあるかもしれない。そのような検査項目を調べて、同時に複数の検査値を表示する機能(例えばバランスを見ることができるようなレーダーチャートなど)も持たせたい。
 患者名など患者情報が表示されていないので、それも表示したい。基本情報、バイタル、アレルギーなど。

0 件のコメント:

コメントを投稿

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

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