ファイルメーカーでJSライブラリを利用したグラフを表示する


今回はファイルメーカー内のデータを利用したグラフ表示についてまとめてみます。
標準で搭載されているグラフ機能は使わず、色々な表現が可能で選択肢が広がるJavaScript(JS)ライブラリを利用します。

サンプルの動作イメージはこんな感じです。
![動作イメージ 棒グラフ](https://qiita-image-store.s3.amazonaws.com/0/68589/95ed30d4-af79-478c-2041-e8fdf60c7c71.png "スクリーンショット 2015-04-04 20.23.12.png")
![動作イメージ 折れ線グラフ](https://qiita-image-store.s3.amazonaws.com/0/68589/b346a11a-ed95-634c-c427-96b8c46ab03e.png "スクリーンショット 2015-04-05 0.42.21.png")

次のグラフは別のライブラリを使っていますが、レーダーチャートなども表示できます。
![別ライブラリを利用したレーダーチャート例](https://qiita-image-store.s3.amazonaws.com/0/68589/d081c87b-8fd4-9a67-60d1-74e669f9c278.png)


グラフはWebビューアを利用し、右側に表示されているデータはファイルメーカーのポータル内にレコード表示しています。数値などを変更すればグラフに反映されます。
また、グラフ左上のドロップダウンで折れ線グラフなど何種類かのグラフに変更できます。

#利用するJSライブラリについて
今回利用するグラフ表示ライブラリは **C3.js**です。
このライブラリはD3.jsという汎用的な可視化ライブラリのラッパーでグラフの種類は限られますが、データの受け渡し方法がファイルメーカーと相性が良かったのでサンプルとして採用しました。
もちろんデータの加工さえ頑張れば、D3.jsを直接使ってオリジナルのデータ可視化を行う事も可能ですし、他のグラフライブラリを利用することも可能です。

各ライブラリのソースはオフラインでも利用できるようにすべてファイルメーカーの中に保持させてグラフ表示に使用します。オフラインに対応したことで、iPadでも問題無くグラフ表示できます。

ライブラリとして利用するソースは以下のものです。
* c3.js [D3.jsのサイト](http://d3js.org)
* c3.js [C3.jsのサイト](http://c3js.org)
* c3.css グラフ表示に使用するスタイルシート


上記に加えて表示用のHTMLソースを使用します。

#ソリューションファイルの説明
##各ライブラリのソースは不可視領域にテキストとして保存
ソースの更新などを考慮して各ソースはテキストとして貼り付けておきます。

貼り付けた各テキストオブジェクトには名前を付けておきます。
![ソースの貼り付け状態とオブジェクト名の設定](https://qiita-image-store.s3.amazonaws.com/0/68589/3670baba-542d-f7a8-34e3-6f781f7ae76c.png "スクリーンショット_2015-04-05_0_17_53.png")

##HTMLソースのbody部のみテキストとして保存
ファイルメーカーのWebビューアに直接書き込むと、バックスラッシュのエンコード量が増えてしまい読みにくいので、body部のみ切り出してライブラリと同様にテキストとして保存します。
サンプルのHTMLコードは以下のようになっています。

```html:body部のコード
    <div id="chart"></div>
    <script src="d3.min.js"></script>
    <script src="c3.min.js"></script>
    <script>
      var chart = c3.generate({
      	padding: { top: 20, right: 100, bottom: 20, left: 100 },
        data: { x: 'x',
          rows: [ 
            ['x','売上'],
            FMPDATA
          ],
          type: 'CHARTTYPE',
        },
        axis: {
          x: {type: 'category', },
          y: {
          	tick: { format: d3.format(",") }
          }
        },
      });
    </script>
```

##webビューア内の設定
WebビューアのWebアドレス欄には以下の設定をします。

```html:webビューアの設定内容
Let([~data = ExecuteSQL ( "select name, val from data" ; "','" ; "" );
~chartData = "['" & Substitute ( ~data ; "¶" ; "'],['" ) & "']";
$$Data = ~chartData
];
	"data:text/html," &
	List (
		"<!DOCTYPE html>";
		"<head>";
		"<meta charset=\"utf-8\">";
		"<meta name=\"format-detection\" content=\"telephone=no\" />";
		"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge, chrome=1\">";
		"<style type=\"text/css\">";
		GetLayoutObjectAttribute ( "c3.min.css" ; "content" );
		"</style>";
		"</head>";
		"<body style=\"border: 0pt;\">"; // optional: scroll=\"no\"
		Substitute ( $$HTML.CONTENTS.CHART;
			[ " src=\"d3.min.js\">" ; ">" & $$LIB.D3.JS ];
			[ " src=\"c3.min.js\">" ; ">" & $$LIB.C3.JS ];
			[ "FMPDATA" ; ~chartData ];
			[ "CHARTTYPE" ; Startup::chartType ]
		);
		"</body>";
		"</html>";
	)
)
```

少し解説をすると、グラフ用のデータをExecuteSQLで取得し、c3でデータとして受け取れる形式に変換。
あとはSubstitute関数で各ライブラリのソースやデータへの置き換えを行っています。
List関数で囲っているのは、コードを読みやすくするためです。


#スクリプトの準備
今回必要なスクリプトは、２つです。
1つ目は起動時にライブラリソースを変数として読み込んで表示するもの。
2つ目はグラフの種類を変更した時に画面を更新するもの。

##起動時用スクリプト
名前を付けた各ソースのテキストをGetLayoutObjectAttribute関数を利用して変数化します。
今回の場合は以下のような感じです。

```FileMakerScript:起動時用スクリプトの内容
1 # JavaScriptライブラリを偏すにセットする 
2 変数を設定 [$$LIB.D3.JS; 値:GetLayoutObjectAttribute ( "d3.min.js" ; "content" )]
3 変数を設定 [$$LIB.C3.JS; 値:GetLayoutObjectAttribute ( "c3.min.js" ; "content" )]
4 変数を設定 [$$LIB.C3.CSS; 値:GetLayoutObjectAttribute ( "c3.min.css" ; "content" )]
5 変数を設定 [$$HTML.CONTENTS.CHART; 値:GetLayoutObjectAttribute ( "html" ; "content" )]
6 ウインドウ内容の再表示 [キャッシュ結合結果を書き込む; キャッシュ外部データを書き込む]
```

##グラフ変更時用スクリプト
設定値が変更された場合にトリガから呼び出されるスクリプトです。
単純に更新処理だけしています。

```FileMakerScript:グラフ変更時用スクリプトの内容
1 ウインドウ内容の再表示 [キャッシュ結合結果を書き込む; キャッシュ外部データを書き込む]
```

以上です。
サンプルファイルではリレーションを貼っていますが、グラフ画面にデータを表示するポータルを表示させるためなので、必須ではありません。

あとはサンプルファイルなどを参照してください。


[サンプルファイル](http://it-komons.jp/filemaker/samples/c3chart_sample.zip)