Ionic製のアプリにD3 Liquid Fill Gaugeを組み込んでみました！

# 概要

IoT機器の情報を表示する場合などで、「液体の量」を表現したい場合があるかと思います。
ちょうどこんな感じに。

![d3LiquidGaugeApp.gif](https://qiita-image-store.s3.amazonaws.com/0/166225/568c1afe-8607-4333-ada5-461b8ed8f804.gif)

というわけで、先日入門したばかりのIonic Frameworkを使ってこんな感じのアプリを実装してみたのでご紹介します！٩( 'ω' )و

つくったサンプルのリポジトリは以下です。
[kemokemo/d3LiquidGaugeApp](https://github.com/kemokemo/d3LiquidGaugeApp)

## 使用環境

この記事で使用した環境は以下の通りです。

```sh
cli packages: (C:\Users\KemoKemo\AppData\Roaming\npm\node_modules)

    @ionic/cli-utils  : 1.19.2
    ionic (Ionic CLI) : 3.20.0

System:

    Node : v8.10.0
    npm  : 5.6.0
    OS   : Windows 10

Misc:

    backend : pro
```

## 使用ライブラリ

* [ngx-d3-liquid-fill-gauge](https://github.com/adedayo/ngx-d3-liquid-fill-gauge)
* [D3](https://github.com/d3/d3)

どちらも [BSD 3-Clause](https://opensource.org/licenses/BSD-3-Clause) ライセンスです。

## 実装の手順

実装の解説には以下のような内容が含まれます。

* Ionicアプリに`Component`を追加して使う場合の記述方法
* 作成した`Component`に、外部から値を`Input`する方法

これらの内容が全く初めてだったり、「む、イマイチ分からんにょ(ΦωΦ)」という方は是非先に`Josh Morony` さんの操作動画をご覧になってください。とてもわかり易くてオススメです。

* [Custom Components in Ionic 2](https://www.joshmorony.com/custom-components-in-ionic-2/)
 * [YouTube - Custom Components in Ionic](https://www.youtube.com/watch?v=Tg4FoOf4pBo)

### ライブラリのインストール

では実際の手順に入っていきましょう。
まずは、`D3`をインストールします。

```sh
npm install d3
```

`ngx-d3-liquid-fill-gauge`は、READMEの手順を実施しても下図のように`ngx-d3-liquid-fill-gauge が見つかりません。`というエラーが出てビルドできなかったので、componentとしてコピーして使うことにしました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166225/ba2fce15-0c5c-3fe1-d63a-01d8450e3f13.png)

※実際には [ここ](https://github.com/adedayo/ngx-d3-liquid-fill-gauge/tree/master/src/app/modules/ngx-d3-liquid-fill-gauge) の Rev. [c23ff7f](https://github.com/adedayo/ngx-d3-liquid-fill-gauge/commit/c23ff7f1d6cabd614b41c3d229ae13d3ad6e5a35) のモジュール群を、Ionicプロジェクトの`src/components/ngx-d3-liquid-fill-gauge`にコピーしました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166225/597b875f-13c3-f969-a26c-a7b4e53fc196.png)

さらに今回のサンプルでは、`liquid-gauge`という名称のコンポーネントで`ngx-d3-liquid-fill-gauge`をラップしました。アニメーションなどの設定は予め`liquid-gauge`内に定義したものを使って、親画面からは数値など頻繁に変更があるような値だけ入力して使う仕組みにしたかったためです。

`src/app/app.module.ts`も以下のように書き換えます。

```diff
 import { SplashScreen } from '@ionic-native/splash-screen';
 import { StatusBar } from '@ionic-native/status-bar';
 
 import { MyApp } from './app.component';
-import { LiquidGaugeComponent } from '../components/liquid-gauge/liquid-gauge';
 import { HomePage } from '../pages/home/home';
+import { NgxD3LiquidFillGaugeComponent } from '../components/ngx-d3-liquid-fill-gauge/ngx-d3-liquid-fill-gauge.component';
+import { LiquidGaugeComponent } from '../components/liquid-gauge/liquid-gauge';
 
 @NgModule({
   declarations: [
     MyApp,
-    LiquidGaugeComponent,
-    HomePage
+    HomePage,
+    NgxD3LiquidFillGaugeComponent,
+    LiquidGaugeComponent
   ],
   imports: [
     BrowserModule,
```

あとはtemplateに `app-ngx-d3-liquid-fill-gauge` を追記すれば表示できます。

```liquid-gauge.html
<b>Default Parameters</b>
<app-ngx-d3-liquid-fill-gauge></app-ngx-d3-liquid-fill-gauge>
```

### 値を親画面から渡す

`src/components/liquid-gauge/liquid-gauge.ts` で `Input` を使えるようにします。

```diff
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
```

同じく`liquid-gauge.ts`に以下を追記します。`name` と `value` という名前で外部から入力できるようになりました。

```diff
 export class LiquidGaugeComponent {
 
-  text: string;
+  @Input('name') name;
+  @Input('value') value;
 
   constructor() {
     console.log('Hello LiquidGaugeComponent Component');
-    this.text = 'Hello World';
+  }
```

親画面である `src/pages/home/home.html` には以下のような変更をしました。
`[name]`で`LiquidGaugeComponent`の`name`を指定し、`"name01"`などで`src/pages/home/home.ts`のプロパティを参照しています。これにより **親画面のhomeからliquid-gaugeにnameやvalueを渡して** います。

```diff
 <ion-content padding>
-  <liquid-gauge></liquid-gauge>
+  <liquid-gauge [name]="name01" [value]="value01" ></liquid-gauge>
+  <liquid-gauge [name]="name02" [value]="value02" ></liquid-gauge>
+  <liquid-gauge [name]="name03" [value]="value03" ></liquid-gauge>
 </ion-content>
```

`src/pages/home/home.ts` には、`liquid-gauge`に渡すパラメータを以下のように定義しました。

```diff
export class HomePage {
 
+  name01: string = "Something 01";
+  value01: number = 0.0;
+
+  name02: string = "Something 02";
+  value02: number = 28.7;
+
+  name03: string = "Something 03";
+  value03: number = 65.1;
+
   constructor(public navCtrl: NavController) {
 
   }
```

### ionic-lab 画面で確認

以下のコマンドを実行すれば、デフォルトブラウザが起動して画面が確認できます。
デフォルトURLは`http://localhost:8100`です。

```sh
ionic serve
```

せっかくなのでクロスプラットフォーム感を味わいたい！٩( 'ω' )و
ということで、ブラウザで`http://localhost:8100/ionic-lab`を開くと冒頭のような画面が確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166225/394bb6ec-dc7c-3562-e85b-c3a0a79c7912.png)

# 謝辞

素晴らしいライブラリ [D3 Liquid Fill Gauge](http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6) を公開してくださった `Curtis Bratton` さん、そんな素敵な `D3 Liquid Fill Gauge` をAngular ComponentとしてTypeScriptで実装して[ngx-d3-liquid-fill-gauge](https://github.com/adedayo/ngx-d3-liquid-fill-gauge) として公開してくださった`adedayo` さんに、この場をお借りしてお礼申し上げます！m(_ _)m

そして、私に素敵なIonic Frameworkとの出会いをくださった良書 [Ionicで作る モバイルアプリ制作入門](https://www.amazon.co.jp/Ionic%E3%81%A7%E4%BD%9C%E3%82%8B-%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%97%E3%83%AA%E5%88%B6%E4%BD%9C%E5%85%A5%E9%96%80%E3%80%88Web-iPhone-Android%E5%AF%BE%E5%BF%9C%E3%80%89-%E6%A6%8A%E5%8E%9F/dp/4863542364) の著者である 榊原さん にもお礼申し上げます！m(_ _)m

Ionicでサクサクっとアプリつくるの、楽しいですね:heart_eyes: