jqplot(WebView)でグラフを描く


1.はじめに

Titaniumでグラフを描くには大雑把に2つの方法があります
- モジュールを使う
- WebViewを使う
この記事では後者のWebViewを使ってグラフを描く方法を紹介します。

また、ここではWebViewで利用するライブラリに jqplot(無料)を利用します。

ビルド可能なプロジェクトファイル一式は下記URLにおいてあります
https://github.com/YoshikazuOota/jqplotTi

2. 想定する動作環境

ここで紹介している範囲ではAndroid / iOS 両方とも1コードで実行できます。
iOSに比べるとAndroid系では多少描画がもたつきますが、実用レベルの処理速度かと思います。

  • Ti SDK: 3.3.0.GA 以上
  • OS: Android(2.X〜) / iOS(6.X 〜)

3. 処理の流れ

WebViewを使ってグラフを描くコツは、『WebView側でグラフ描画ライブラリのロードを待ってから、書き込みの関数を実行する』と言うことです。
つまり、WebView側の処理系とTitanium側の処理系でイベントをやりとりすることになります。

4. メインコード

上記コード、ざっくり対応付けるように番号を振ってあります。

app.js
var event_name = 'myJqplotEvent';

// グラフ描画データ(詳細は jqplotのドキュメントを参照)
var data = [[3, 7, 9, 1, 4, 6, 8, 2, 5]];
var option = {
  title: 'Plot With Options',
  axes: {
    xaxis: {label: "X Axis", pad: 0},
    yaxis: {label: "Y Axis"}
  }
};


var window = Ti.UI.createWindow({
  backgroundColor: 'white',
  touchEnabled: false // これを付けないとWebView内でスクロールが発生したりして不都合がある
});

// ▼▼▼ ① html読込 ▼▼▼
var webView = Ti.UI.createWebView({
  url: 'html/jqplot.html',
  top: '30dp',
  height: '300dp',
  width: '300dp'
});
window.add(webView);

// ▼▼▼ ③ グラフ描画データ(文字列)送信 ▼▼▼
var chartFunc = function () {
  // 注: webview側のJSには文字列として値を渡すので、オブジェクトは指定できません
  webView.evalJS("jqplot_ti(" + JSON.stringify(data) + ", " + JSON.stringify(option) + ")");
  Titanium.App.removeEventListener(event_name, chartFunc);
};
Titanium.App.addEventListener(event_name, chartFunc);

window.open();
jqplot.html
<html>
<head>
    <title></title>
    <meta name="viewport" content="width=initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
    <script language="javascript" type="text/javascript" src="lib/jquery.min.lib"></script>
    <script language="javascript" type="text/javascript" src="lib/jquery.jqplot.min.lib"></script>
    <link rel="stylesheet" type="text/css" href="lib/jquery.jqplot.min.css" />

    <script type="text/javascript" charset="utf-8">
        $(function(){
            // ▼▼▼ ② ライブラリロード完了 ▼▼▼
            Ti.App.fireEvent('myJqplotEvent'); // event_nameと同じ値
        });
        function jqplot_ti(data, option) {
            $.jqplot('chartdiv', data, option);
        }
    </script>
</head>
<body>
<!-- height, width は Titaniumのjs側で指定する (300dp -10)で 290とする -->
<!-- すいません。どうしてこのような値が適当になるのかわかっていません... -->
<div id="chartdiv" style="height:290 ;width: 290;" ></div>
</body>
</html>

5 処理の流れの説明

① html読込
WebViewでhtmlファイルを読み込みます。  
  
② ライブラリロード完了
jQueryを使ったプログラミングの定石通り、jQuery等のロードを待ってからTitnium側の処理系にイベントを投げます。③のグラフ描画処理は必ず ②のロードを待ってから行わないと正常に実行できません。  

③ グラフ描画データ(文字列)送信
Titanium側の処理系から描画するデータをhtml側の処理系に渡します。この時、描画データは文字列で渡すため、オブジェクトデータは送れません。
もし、必要があればhtml側のjavascriptでオブジェクトを定義するなどの対応が必要です。(具体例:Titanium側から日付型を文字列でhtml側に渡して、html側で日付型にパースする)

6. 気を付けたいハマリポイント

WebViewのhtmlで参照するjavascriptファイル名は *.jsを *.lib等に変更
ファイル拡張子が *.jsのままだとTitaniumのビルド対象と判定されて、ビルド時にエラーになります

7. 最後に

同様の実装で大体のグラフライブラリが利用出来ると思います

ここで紹介したコードは説明用に記述したため、使いづらいと思います。
使用している描画ライブラリは違いますがラッパも作成しております。実装の参考になれば幸いです。
jqChart(商用)のラッパとサンプル: https://github.com/YoshikazuOota/jqchartWrapper

ご質問等ございましたら、できるだけお応えするようにします!!

明日はxtityさんの記事ですね。楽しみです!