こんにちは!今回はGoogle Chart Toolsで棒グラフ(Column Chart)を書いてみます。
完成形は公式のサンプルにある、これ!
Google Chart Tools とは
(ざっくりですが)多様なチャートを簡単に描画できるようにGoogleが提供しているツール群です。
ココが公式です。
で、どんなチャートが書けるのかはChart Galleryを見てみてください。
これだけあればチャートに関しては困ることはないだろうと思われるほど、多様なチャートを描画することができます。
しかも簡単に!
さらにオプションも充実しているので、線の太さや色なんかはもちろんのこと
軸の設定や、折れ線グラフなんかの点(ポイント)の形や大きさ、ツールチップ表示等
本当に色々なところを自分好みにいじることができます。
英語ですがドキュメントが非常に充実していて、サンプルコード(JS)もあるので「本当に使いやすいな」という印象です。
早速ですが、今回のお題であるColumn Chartを書いてみましょう!
事前準備
- GitBash (所々出てくるコマンドを実行する為。他でもいいですが、オススメです)
- Node.js (typescriptをインストールする為にnpmを使うので)
- npmを使わないインストール方法をとるのであれば必須ではありません。
- Typescript (Typescriptで書くので必須)
- tsd (型定義ファイルをインストールするのに使います)
これらの導入に関しては割愛させて頂きますm(_ _)m
Web検索を駆使、もしくはこのへんを参照して頂ければと思います。
今回のプロジェクトの構成(最終形)
折角AngularJSなのでService, Controller, Directiveに分けてつくってみたいと思います。
google-chart-tools-sample
┣ typings // tsdでインストールされた型定義ファイルたち
┣ app.js // コンパイルで生成されるjs
┣ app.ts // moduleの登録等を行う
┣ ColumnChartController.ts // コントローラークラス
┣ ColumnChartDirective.ts // ディレクティブクラス
┣ ColumnChartService.ts // サービスクラス
┣ index.html
┗ tsd.json // tsdの設定ファイル。"$tsd init"で生成します。
Column Chart を描く!
型定義ファイルのインストール
今回はangularjs
とgoogle.visualization
の型定義ファイルが必要です。
- angularjsの型定義インストール
$ tsd query angular -rosa install
- google.visualizationの型定義ファイルのインストール
$ tsd query google.visualization -rosa install
これで"typings"ディレクトリが作成されて、その中に型定義ファイルたちがいるはずです。
サービスクラスの作成
今回サービスクラスでは、チャートのオプション設定やデータ部分を書きます。
こんな感じ。
namespace app.service {
"use strict";
export class ColumnChartService {
private data: google.visualization.DataTable;
private options: any = {
title: "Motivation and Energy Level Throughout the Day",
focusTarget: "category",
hAxis: {
title: "Time of Day",
format: "h:mm a",
viewWindow: {
min: [7, 30, 0],
max: [17, 30, 0]
},
textStyle: {
fontSize: 14,
color: "#053061",
bold: true,
italic: false
},
titleTextStyle: {
fontSize: 18,
color: "#053061",
bold: true,
italic: false
}
},
vAxis: {
title: "Rating (scale of 1-10)",
textStyle: {
fontSize: 18,
color: "#67001f",
bold: false,
italic: false
},
titleTextStyle: {
fontSize: 18,
color: "#67001f",
bold: true,
italic: false
}
}
};
constructor() {
this.createData();
}
public getOptions(): any {
return this.options;
}
public getData(): any {
return this.data;
}
private createData() {
this.data = new google.visualization.DataTable();
this.data.addColumn("timeofday", "Time of Day");
this.data.addColumn("number", "Motivation Level");
this.data.addColumn("number", "Energy Level");
this.data.addRows([
[{v: [8, 0, 0], f: "8 am"}, 1, .25],
[{v: [9, 0, 0], f: "9 am"}, 2, .5],
[{v: [10, 0, 0], f: "10 am"}, 3, 1],
[{v: [11, 0, 0], f: "11 am"}, 4, 2.25],
[{v: [12, 0, 0], f: "12 pm"}, 5, 2.25],
[{v: [13, 0, 0], f: "1 pm"}, 6, 3],
[{v: [14, 0, 0], f: "2 pm"}, 7, 4],
[{v: [15, 0, 0], f: "3 pm"}, 8, 5.25],
[{v: [16, 0, 0], f: "4 pm"}, 9, 7.5],
[{v: [17, 0, 0], f: "5 pm"}, 10, 10],
]);
}
}
}
データ(data)とかオプション(options)は、公式のサンプルからそのまま持ってきました。
コントローラークラスの作成
サービスを使ってチャート描画部分を担当するコントローラーを作ります。
namespace app.controller {
"use strict";
export class ColumnChartController {
constructor(private columnChartService: app.service.ColumnChartService) {
}
public draw(element: Element) {
new google.visualization.ColumnChart(element).draw(
this.columnChartService.getData(), this.columnChartService.getOptions());
}
}
}
先に作成したサービスクラスを使うのでコンストラクタの引数にとります。後ほど注入します。
メソッドはチャート描画をする為の"draw(element: Element)"があるのみです。
ディレクティブクラスの作成
表示部分を担当してもらいます。
namespace app.directive {
"use strict";
export class ColumnChartDirective implements ng.IDirective {
public restrict: string;
public replace: boolean;
public scope: any;
public controller: any;
public controllerAs: string;
public link: (
scope: ng.IScope,
element: ng.IAugmentedJQuery,
attrs: ng.IAttributes,
ctrl: app.controller.ColumnChartController) => void;
constructor() {
this.init();
}
public static Factory(): ng.IDirectiveFactory {
let directive = () => {
return new ColumnChartDirective();
};
directive.$inject = [];
return directive;
}
private init() {
this.restrict = "A";
this.replace = false;
this.scope = {
};
this.controller = ["ColumnChartService", app.controller.ColumnChartController];
this.controllerAs = "columnChartController";
this.link = (
scope: ng.IScope,
element: ng.IAugmentedJQuery,
attrs: ng.IAttributes,
ctrl: app.controller.ColumnChartController) => {
ctrl.draw(element[0]);
};
}
}
}
今回は"restrict = "A";"を指定し、属性として使うようにしています。
"Controller"には、先に作成したColumnChartControllerクラスを指定し、
その際ColumnChartServiceを注入しています。
"link"で、そのコントローラーのdrawメソッドをコールしてチャートを描画しています。
モジュールを定義する
必要なクラスは揃ったのでAngularのmoduleを定義します。
/// <reference path="./typings/angularjs/angular.d.ts" />
/// <reference path="./typings/google.visualization/google.visualization.d.ts"/>
/// <reference path="./ColumnChartService.ts" />
/// <reference path="./ColumnChartDirective.ts" />
/// <reference path="./ColumnChartController.ts" />
"use strict";
google.load("visualization", "1", {
packages: ["corechart"]
});
angular.module("app", [])
.service("ColumnChartService", app.service.ColumnChartService)
.directive("columnChart", app.directive.ColumnChartDirective.Factory());
"app"という名前でモジュールを定義しています。
そのモジュールに".service"でサービスの登録、".directive"でディレクティブを、それぞれ
"ColumnChartService"、"columnChart"という名前で登録しています。
ディレクティブの名前は「先頭小文字のキャメルケース」というルールがあるので、
サービスクラスとは違いそのような名前をつけています。
"google.load~"部分ではgoogle.visualization APIをロードしています。
で、先頭部分では必要な型定義ファイルや、作成したクラスを参照する為に"<reference path~>"を記述しています。
tsファイルをコンパイルする
作成したtsファイルをコンパイルして、index.htmlで読み込むjsファイルを生成します。
今回は全ての"*.ts"ファイルをまとめて"app.js"という1つのjsとして生成することにします。
$ tsc --out app.js ./*.ts --target es5 --module commonjs --noImplicitAny --removeComments
上記コマンドを実行後、同階層に"app.js"が出力されるはずです。
index.htmlを作成する
ここまできたら準備は完了。あとはindex.htmlを作成すれば完成です。
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Column Chart Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="./app.js"></script>
</head>
<body>
<div column-chart></div>
</body>
</html>
"<head>"内で必要なスクリプトを読み込ませます。
"<body>"部にはディレクティブ名を"<div>"の属性として書くだけです。
ディレクティブを属性としてhtml中に書くときは、キャメルケースの区切り部分を
"-"で区切って指定するという決まりになっています。
"app.ts"にてディレクティブを登録した際は、名前として"columnChart"という名前で登録しましたが、
この場合は"column-chart"と指定します。
動かしてみる!
ここまできたら、あとはindex.htmlをブラウザで表示させてみて下さい。
これ、でましたか!?
今回のコードは、githubに置きました。
他のチャートも、基本的に同じ要領で描画できるはずです。
次は複合チャート(Combo Chart)をやってみようかと思います。