d3.js
tutorial
TypeScript
c3.js
型定義

TypeScriptチュートリアル② -外部ライブラリの利用-

TypeScriptチュートリアル①の続きです。次はJavaScript向けに書かれた外部ライブラリの利用方法を学んでみましょう。
また今回のチュートリアルではVisual Studio Codeというエディターを利用することを前提に解説していますので、もしよかったらインストールしてみてください。(https://code.visualstudio.com/download)

アプリケーション開発の開始

練習用のアプリケーションとして新たなフォルダの作成と一連の設定ファイルの初期生成をおこなっておきましょう。

コマンドプロンプト
mkdir ts_c3
cd ts_c3
npm init --y
tsc --init

"npm init --y"コマンドは、npmの設定ファイル"package.json"をデフォルトの内容で生成します。
"tsc --init"コマンドはTypeScriptのコンパイルオプションを指定するファイル"tsconfig.json"をデフォルトの内容で生成します。

C3.jsのインストール

今回、利用する外部ライブラリはC3.jsとしてみましょう。このライブラリはインタラクティブなグラフ(チャート)をWebで実現するためのライブラリで、ビジュアライゼーションライブラリのD3.jsのラッパーライブラリです。

コマンドプロンプト
npm install c3
npm install @types/c3

一つ目に入れているのはC3.jsの本体です。
二つ目に入れているのはTypeScriptでC3.jsを利用するための「型定義ファイル」です。どのような型定義ファイルが存在するかはこちらのリンク先を探索してみるとわかります。いっぱいありますね。
https://www.npmjs.com/~types)

型定義ファイル

「型定義ファイル」とは、JavaScriptで作成されたライブラリに、TypeScriptの型を当てはめるためのファイルです。このファイルによって、データ型を意識でき、エディタにより入力支援を伴ったプログラミングができるようになります。
型定義ファイルの用意の仕方や使い方には、いろいろ紆余曲折あって、様々な情報がインターネット上にもありますが、今回は、現在(2018/3時点)のおすすめの方法で型定義ファイルを導入しています。

コーディング

準備ができましたのでVisual Studio Codeを立ち上げてコーディングを始めましょう。
まずはindex.htmlを作成します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>円グラフ</title>
    <link href="node_modules/c3/c3.min.css" rel="stylesheet">
</head>
<body>
    <div id="chart"></div>
    <script src="bundle.js"></script>
</body>
</html>

ここでの注意点としてはC3.jsが用意しているCSSへのリンクを忘れずに入れてください。これがないと出来上がりがイマイチになります。

続いてTypeScriptのプログラム"app.ts"を作成します。

app.ts
import * as c3  from 'c3';

let chart = c3.generate({
    bindto: '#chart',
    data: {
        type: 'donut',
        columns: [
            ['良い感じ', 50],
            ['ピンとこない', 50]  
        ]
    },
    donut: {
        title: 'TypeScriptの印象は?'
    }
});

このコーディングでぜひ見ていただきたいのが、型定義ファイルによって、どのように入力支援がされるのかです。
たとえば下図のように、"let chart = c3."と入力した時点で、そこから続けることができる入力候補を表示してくれます。

スクリーンショット 2018-03-20 11.54.14.png

c3オブジェクトはC3.jsで用意されているオブジェクトですが、メソッドはgenerateのみが使えるので、それを案内してくれています。

またgenerateメソッドにはグラフを描画するためのデータをオブジェクトとして渡す必要がありますが、そちらでもオブジェクト内のプロパティが誤っていると指摘してくれます。
下図は本来はbindtoと入力しないといけないところで、大文字を交えたbindToと入力してしまった際のエラーです。

スクリーンショット 2018-03-20 12.59.26.png

他には「このプロパティに渡す値はオブジェクトだっけ?配列だっけ?」とアヤフヤになってしまった場合でも、誤って入力するとその場で指摘してくれるので安心です。
下図は本来columnsプロパティは配列を渡す必要があるのですが、誤ってオブジェクトを渡してしまっている例です。

スクリーンショット 2018-03-20 13.05.05.png

コンパイルとモジュールバンドル

無事、app.tsが入力できましたら、動作確認をするためにもTypeScriptのコンパイルとwebpackによるモジュールの結合を行います。ここで結合してるのは、先程作ったapp.tsのコンパイル結果であるapp.jsと、そこから依存している(importしている)C3.js、そして表面上には登場しませんが、C3.jsが依存しているD3.jsの3つを一つのbundle.jsというファイルにしています。

下記のコマンドを順番に実行してください。

コマンドプロンプト
tsc app.ts
webpack app.js --output bundle.js --mode=development

そしてindex.htmlをブラウザで開いてください。すると下図のようなページが開けば完成です。
スクリーンショット 2018-03-22 9.53.01.png

C3.jsをもう少し触ってみる

C3.js公式のサンプルをいろいろ見てみると、JavaScriptでよく利用されるsetTimeoutを使って、表示しているデータを増減させるとアニメーションを伴って華麗にグラフ上のデータも変化するようです。実際やってみましょう。
app.tsを下記のように書き換えてください。

app.ts
import * as c3  from 'c3';

let chart = c3.generate({
    bindto: '#chart',
    data: {
        type: 'donut',
        columns: [
            ['良い感じ', 50],
            ['ピンとこない', 50]
        ]
    },
    donut: {
        title: 'TypeScriptの印象は?'
    }
});
// ↓  ここから下を追記
setTimeout(() => {
   chart.load({
    columns: [
        ['良い感じ', 30],
        ['ピンとこない', 30],
        ['最高', 30]
    ]
   });
}, 3000);
setTimeout(()=> {
    chart.unload({
        ids: '最高'
    });
}, 5000);
// ↑ ここまで追記

入力が終わったら、コンパイルとモジュールの結合を忘れないでくださいね。

コマンドプロンプト
tsc app.ts
webpack app.js --output bundle.js --mode=development

chart_ani.gif

型定義ファイルの辛いところ

型定義ファイルを使うと、素のJavaScriptを使うことに比べて、補完による入力量の減少や入力ミスの早期発見が実現でき、とても気持ちよくコーディングが出来ますが、ひとつ辛いところがあります。
それは型定義ファイルが場合によってはコンパイルエラーとなったり、うまく入力支援してくれなかったりなど品質にバラつきがあるということです。型定義ファイルは多くの場合、世界のどこかの有志の方が作成してくれて公開してくれているのですが、移り変わりの激しいJavaScriptの世界では、TypeScriptのバージョンアップ速度と対象の外部ライブラリの移り変わりの速さの両方に対応しないといけないので、大変なんだとおもいます。
ここは場合によっては作者の方に連絡するか、自分で型定義ファイルを修正するか、もしくは(あんまりやりたくはないですが)any型で逃げるかをする必要が出てきます。悩ましい問題です。

 目次

TypeScriptチュートリアル① -環境構築編-
TypeScriptチュートリアル② -外部ライブラリの利用-
TypeScriptチュートリアル②外伝 -チャンク-