InfoType 作りにチャレンジしてみた

この記事は enebular Advent Calendar 2018 7 日目です。

はじめに

Enebular の InfoType、サンプルにもある Line/Bar/Pie チャートで、大抵は事足りてしまうと思うのですが、アプリケーション次第では違う見せ方もあるんじゃないか、と思いチャレンジしてみました。

ES2015 で InfoType 作り

以前 Qiita に、InfoType を ES2015 で作成する記事を投稿していますが、今回も ES2015 でいきます。

ES2015 で書くと、下記のようなクラスでいけます。
# 正確なところは、公式ドキュメントにないので、怪しい部分はありますが。。。

d3 や Chart.js など、使いたいライブラリーは、npm install して、クラス宣言の前に import することで使えるようになります。

import * as d3 from "d3";

export default class SampleInfoType {
  constructor(settings, options) {
    // 初期化
    // チャート用 HTML 要素の作成(お決まり)
    this.el = window.document.createElement('div');
    this.data = [];
  }

  addData (data) {
    // データ追加時のイベントハンドラー

    // メンバー変数 data に格納して再描画
    this.data = data;

    // d3 や Chart.js などで描画する
  } 

  clearData () {
    // データクリア時のイベントハンドラー
    // メンバー変数 data を空にして再描画
    this.data = [];

    // d3 や Chart.js などで描画する
  }

  resize (options) {
    // チャートリサイズ時のイベントハンドラー
    this.width = options.width;
    this.height = options.height - 50;
  }

  getEl() {
    // チャート用 HTML 要素の getter (お決まり)
    return this.el;
  }

  // 以下、クラス変数定義
  static get defaultSettings() {
    return {
      // デフォルト値
    };
  }

  static get settings() {
    return EnebularIntelligence.SchemaProcessor([{
      // パラメータとかいろいろ
    }], SampleInfoType.defaultSettings); 
  }
}

window.EnebularIntelligence.register('linechart', SampleInfoType);

ちなみに、上記の Qiita の記事を書いた当時は、ES2015 で書いたコードは eit package で失敗するため、事前に babel でトランスパイルする必要がありました。
でも @uhuru/enebular-infomotion-tool-v2@1.0.0-alpha.25 からは @babel/core@babel/preset-env@babel/preset-react が組み込まれており、eit package の実行で、自動的に babel でのトランスパイルも実行されるようになっています。

# v1.0.0-alpha.24 の依存パッケージ
$ npm info @uhuru/enebular-infomotion-tool-v2@1.0.0-alpha.24
(略)
dependencies:
app-module-path: ^2.2.0   browser-sync: ^2.23.6     chalk: ^2.1.0             commander: ^2.11.0        fs-extra: ^4.0.2          gulp: ^4.0.0              prompt: ^1.0.0
axios: ^0.17.0            browserify: ^14.4.0       clui: ^0.3.6              download-git-repo: ^1.0.1 gulp-livereload: ^3.8.1   minifier: ^0.8.1          uglify-js: ^3.1.3
# v1.0.0-alpha.25 の依存パッケージ
$ npm info @uhuru/enebular-infomotion-tool-v2@1.0.0-alpha.25
(略)
dependencies:
@babel/core: ^7.1.6         app-module-path: ^2.2.0     browser-sync: ^2.23.6       clui: ^0.3.6                fs-extra: ^4.0.2            minifier: ^0.8.1
@babel/preset-env: ^7.1.6   axios: ^0.17.0              browserify: ^14.4.0         commander: ^2.11.0          gulp-livereload: ^3.8.1     prompt: ^1.0.0
@babel/preset-react: ^7.0.0 babelify: ^10.0.0           chalk: ^2.1.0               download-git-repo: ^1.0.1   gulp: ^4.0.0                uglify-js: ^3.1.3

あの記事の存在意義はゼロになりましたが、ウフルさん、さすがです!

作成した InfoType

今回作成した InfoType は、心電図です(ユースケースがピンポイントすぎますが)。
以前から Fitbit を使ってリアルタイムに心拍数を取ったりしているので、Line チャート以外の見せ方がないか考えた結果、ここに落ち着きました。

DataSource (例えば Firebase) から数字を受信したら、それを 1 分あたりの心拍数とみなし、そこから計算した時間間隔でそれっぽい波形を描画し続けます。

こんな感じです。 f:id:horihiro:20181202164621p:plain

波形は Canvas 上に描画していますが、細かい処理は smoothie にお任せしています。
標準で組み込まれている d3 は使っていません。

全コードはGitHubで公開しているので、フォークしてご自由にお使いください。

github.com

心電図なので、DataSource からの受信がなくても波形を定期的に描画します。 なので、上のクラス構造とはだいぶ違いますが、参考程度に。

おわりに

Enebular を使えば Firebase に保存したデータをもとに、自分のオリジナルのグラフを Web ページとして表示することが簡単にできます。

一方で、作っていて思ったのは、エディターとターミナルで作業をしながら、Web ページからアップロードするのは、ちょっと面倒でした。 なので、eit package までするのであれば、アップロード(それに必要なログインも)もできる eit deploy みたいなコマンドもあればいいと思いました。