Dojo Toolkit を使用してモバイル用のチャートを作成する

モバイル機器用のチャート・アプリケーションを手軽に作成する

この記事では、dojox.mobile パッケージと dojox.charting パッケージの機能について探るため、ステップバイステップの例により、Dojo Toolkit を使用してモバイル・チャート・アプリケーションを作成する方法と、タッチ操作をサポートすることでそのアプリケーションを機能強化する方法について説明します。また、レンダリングのパフォーマンスを向上させる方法などの高度なトピックも取り上げます。

Christophe Jolif, Software Engineer, IBM China

Photo of Christophe JolifChristophe Jolif は IBM フランスのアドバイザリー・ソフトウェア・エンジニアです。彼は IBM ILOG Elixir 開発チームのリーダーであり、Dojo Toolkit オープンソース・プロジェクトのコントリビューターでもあります。彼はチームのブログや技術記事に ILOG Elixir に関する記事を書いており、またこの製品の技術ドキュメントへの貢献も行っています。彼は IBM に入社前は ILOG に 10 年以上勤務し、Java、Ajax、Adobe Flex を使用した高度な視覚化コンポーネントを開発していました。



Damien Mandrioli, Software Engineer, IBM China

Photo of Damien MandrioliDamien Mandrioli は IBM のソフトウェア・エンジニアです。彼の業務上の関心事項は、視覚化コンポーネント、Web アプリケーション開発、ユーザー・インターフェースのユーザビリティーです。彼は Dojo Toolkit 開発チームに参加する前は IBM ILOG Elixir 視覚化製品のコンポーネントとデモの開発を 5 年間行っていました。



2011年 9月 16日

はじめに

この記事では、モバイル機器上で実行される魅力的なチャート・アプリケーションを Dojo Toolkit のチャート・フレームワークを使用して作成する方法を説明します。そのなかで、Dojo モバイル・アプリケーションの中でチャート・コンポーネントをインスタンス化し、構成する方法や、そのコンポーネント上でタッチ操作を実現し、より適切にモバイル機器と統合する方法を説明します。さらには、チャート・アプリケーションの高度なオプションとして、ロードとレンダリングを高速化する方法についても説明します。

この記事のソース・コードは、「ダウンロード」することもできます。


Dojo Mobile によるチャート・アプリケーションを作成する

Dojo を使用してモバイル・アプリケーションを作成する場合には、dojox.mobile パッケージを使用することをお勧めします。dojox.mobile パッケージは比較的薄い Dojo レイヤーとして、モバイル指向の軽量な一連のウィジェット、パーサー、遷移フレームワークを備えています。これらの機能がモバイル・アプリケーションにとって重要なことを考えると、ほとんどの Dojo モバイル・チャート・アプリケーションに dojox.mobile パッケージが使われる可能性があります。

dojox.mobile アプリケーションでチャートをインスタンス化する最も容易な方法は、構文解析を利用して dojox.mobile ウィジェットのマークアップの中にチャートのコードを入れる方法です (これは通常の Dijit デスクトップ・アプリケーションの場合と似ています)。まず、アプリケーションのマークアップを定義する HTML ファイルと、その HTML ファイルから参照され、アプリケーションの JavaScript ロジックを含む JavaScript ソース・ファイルが必要です。

この記事では例として、棒グラフを使って販売データを表示する単純なアプリケーションを作成する方法を説明します。この棒グラフは月ごとに区切られており、全体の期間は 3 年間です。リスト 1 のコードを使用して HTML ファイルを作成します。

リスト 1. モバイル・チャート・アプリケーションの最初の HTML ファイル
<!DOCTYPE HTML> 
<html> 
  <head> 
    <title>Dojo Toolkit Mobile Charting</title> 
    <meta name="viewport" content="width=device-width,initial-scale=1, 
      maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
    <meta name="apple-mobile-web-app-capable" content="yes" /> 
    <link rel="stylesheet" type="text/css" 
      href="../../../dojo_current/dojox/mobile/themes/iphone/iphone.css"> 
    <script type="text/javascript" src="../../../dojo_current/dojo/dojo.js" 
      data-dojo-config="parseOnLoad: true"></script> 
    <script type="text/javascript" src="src_01.js" charset="utf-8"></script> 
  </head> 
  <body> 
    <div id="view1" data-dojo-type="dojox.mobile.View"> 
      <h1 id="head1" data-dojo-type="dojox.mobile.Heading">Chart View</h1> 
      <div data-dojo-type="dojox.mobile.RoundRect"> 
        <button id="b1" data-dojo-type="dojox.mobile.Button" 
          class="mblBlueButton">Zoom</button> 
        <button id="b2" data-dojo-type="dojox.mobile.Button" 
          class="mblBlueButton">Unzoom</button> 
        <div data-dojo-type="dojox.charting.widget.Chart" id="chart" 
          style="width: 100%; height: 180px;"> 
          <div class="plot" name="grid" type="Grid" 
               vMinorLines="true"></div>             
          <div class="axis" name="x" 
               fixUpper="minor"   
               majorTickStep="1" 
               minorTicks="false"></div> 
          <div class="axis" name="y" vertical="true" min="0"></div> 
          <div class="plot" name="plot" type="Columns" ></div> 
          <div class="series" name="data" plot="plot" 
            data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33, 
                32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27, 
                28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div> 
        </div> 
      </div> 
    </div> 
  </body> 
</html>

リスト 1 のコードは Dojo の data-type 属性の中で dojox.mobile クラスと dojox.charting クラスを参照しています。このマークアップを適切に構文解析してインスタンス化するために、このマークアップに対応するモジュールを JavaScript ソース・ファイルにインポートする必要があります (リスト 2)。

リスト 2. モバイル・チャート・アプリケーションの最初の JavaScript ソース・ファイル
require(["dojo", "dojox/mobile", "dojox/mobile/parser", 
  "dojox/mobile/Button", "dojox/charting/widget/Chart", 
  "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
  "dojox/charting/plot2d/Grid"]);

この記事で紹介する例では、最近導入された AMD 構文を使用して Dojo アプリケーションの依存関係を管理しています (AMD に関する詳細は「参考文献」を参照)。後方互換性を持たせるために、新しいフォーマットに切り換えたくない場合には、従来の dojo.require フォーマットを使用して依存関係を管理し、同様のアプリケーションを作成することもできます。

このコードに対応するアプリケーションを実行すると、図 1 のような結果が表示されるはずです。

図 1. モバイル・チャート・アプリケーション
モバイル機器用の横長の画面に棒グラフが表示されており、ズーム制御のための 2 つのボタンがあります。

図 1 のグラフは、マークアップで定義された数列のデータ属性としてハードコーディングされたデータを表示した対話機能のない静的なグラフでしかありません。この先に進む前に、このアプリケーションに対して少し調整が必要です。

この時点で、このアプリケーションは Webkit を採用しているモバイル・ブラウザーとデスクトップ・ブラウザー用に調整されています。このアプリケーションを他のデスクトップ・ブラウザー (Firefox など) で適切に実行できるようにしたい場合には、依存関係のリストを更新して dojox/mobile/compat モジュールを追加します (リスト 3)。この例では、Webkit ブラウザーを実行していない場合に dojox/mobile/compat モジュールを読み込むためにのみ、dojo/has という AMD プラグインを使用します。そのため、互換性モジュールが必要です。

リスト 3. Webkit 以外のブラウザーのサポートを追加する
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojox/mobile", "dojox/mobile/parser",
	"dojo/has!webKit?:dojox/mobile/compat", 
	"dojox/mobile/Button", "dojox/charting/widget/Chart", 
	"dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
	"dojox/charting/plot2d/Grid"]);

次のステップでは、表示されるチャート・データとして、アプリケーションにデータをハードコーディングする代わりに、外部のデータ・ソースを使用します。そのためには Dojo Charting と Dojo Core の両方のデータ・ストア API を使用することができます。

dojo.data パッケージと dojox.data パッケージには、さまざまなデータ・ソースからデータをロードして、それらのデータを Dojo コンポーネントに関連付けるためのクラスがあります。この例では、リスト 4 の JSON データがサーバー上にあり、このデータをロードするものとします。

リスト 4. サンプルの JSON データ
{
  "items": 
  [ 
{"value": 0}, {"value": 32}, {"value": 32}, {"value": 45}, {"value": 37}, {"value": 28}, 
{"value": 24}, {"value": 48}, {"value": 44}, {"value": 21}, {"value": 32}, 
{"value": 33}, {"value": 32}, {"value": 34}, {"value": 44}, {"value": 32}, 
{"value": 39}, {"value": 43}, {"value": 44}, {"value": 46}, {"value": 36}, 
{"value": 41}, {"value": 25}, {"value": 27}, {"value": 28}, {"value": 45}, 
{"value": 46}, {"value": 33}, {"value": 34}, {"value": 35}, {"value": 29}, 
{"value": 44}, {"value": 48}, {"value": 48}, {"value": 49}, {"value": 43} 
  ]
}

この JSON データをロードするためには dojo.data.ItemFileReadStore のインスタンスを使用します。このデータをチャートに使用するためには、データ・ストアのデータ項目をチャートに入力する役割を持つことになる series オブジェクトに dojo.data インスタンスを関連付けます。

まず、HTML の中にある series の宣言を変更し、ハードコーディングされたデータを入力として使用するのではなく、”store” という名前のデータ・ストアを参照するようにしなければなりません。そのために、リスト 6 の series の定義を変更し、リスト 7 のように store="store" を含めるようにします。

リスト 6. これまでの series の定義
            <div class="series" name="data" plot="plot" 
              data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33,
                    32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27,
                  28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div>
リスト 7. これまでの series の定義に store を含める
            <div class="series" name="data" store="store" plot="plot"></div>

同じ HTML ファイルの中で、リスト 8 のマークアップを使用して store を定義することができます。

リスト 8. HTML で store を定義する
	    <div data-dojo-type="dojo.data.ItemFileReadStore" url="data.json"
       		 data-dojo-id="store" urlPreventCache="true" clearOnClose="true"></div>

リスト 8 のコードでは、ItemFileReadStore クラスを使用してサーバー上の data.json ファイルをロードし、ロードした data.json ファイルをデータ系列の入力として使用される store 変数に関連付けています。アプリケーションの中には、ソース・ファイルの require 文の一部として必ずデータ・ストア・クラスが必要です (リスト 9)。

リスト 9. require 文にデータ・ストア・クラスを含める
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
        "dojo/has!webKit?:dojox/mobile/compat", 
        "dojox/mobile", "dojox/mobile/parser", 
        "dojox/mobile/Button", "dojox/charting/widget/Chart", 
        "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
        "dojox/charting/plot2d/Grid"]);

これで、サーバーから入力される毎月のデータをレンダリングするモバイル・チャート・アプリケーションを作成することができました。この例にはまだ、データのインデックスの代わりに対象となる月を表示する X 軸がありません。そこで、リスト 10 に示すように、X 軸でラベル関数を参照するようにします。

リスト 10. ラベル関数を指定する
            <div class="axis" name="x" 
	         fixUpper="minor" majorTickStep="1"
                 minorTicks="false" labelFunc="displayDate"></div>

次にソース・ファイル内に displayDate 関数を定義します (リスト 11)。

リスト 11. JavaScript でラベル関数を実装する
var displayDate;
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
       "dojo/has!webKit?:dojox/mobile/compat", 
       "dojox/charting/action2d/TouchZoomAndPan", 
       "dojox/mobile", "dojox/mobile/parser", 
       "dojox/mobile/Button", "dojox/charting/widget/Chart", 
       "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
       "dojox/charting/plot2d/Grid"], function(dojo){
  var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
                "Oct", "Nov", "Dec"];
  var years = ["08", "09", "10", "11"];
  displayDate = function(idx){
    if ((idx%2) == 0){
     return " ";
    }
			
    var m = parseInt(idx-1);
    if (m%12 == 0){
      // Display the year only for january
      return months[m%12] + " " + years[m/12];
    }else{
      return months[m%12];
    }
  }
});

基本的に、リスト 11 のコードは各データのインデックスをストリングにマッピングします。この例では 3 年にわたる毎月のデータがあるため、指定されたインデックスに対応する月の名前からストリングを作成しています。

以上の結果、図 2 のようなチャートが表示されるはずです。

図 2. 軸ラベルをカスタマイズする
この図は年と月を使用して X 軸のラベルをカスタマイズした様子を示しています。

チャートのタッチ操作を有効にする

Dojo モバイル・チャート・アプリケーションを作成したあとは、このアプリケーションに特定のモバイル機能を追加してみるのはどうでしょう。一例として、タッチ・ジェスチャーを使用してチャートを操作する機能を追加してみましょう。これは比較的簡単です。チャートの他の機能の場合と同じように、チャートの定義の中で 1 行のコードを使用するだけで、タッチ機能を追加することができます。例えばタッチによるズーム機能とパン機能を追加するためには、単純にリスト 12 の内容を HTML マークアップに追加するだけです。

リスト 12. タッチによるズームとパンのサポートを追加する
<div class="action" type="dojox.charting.action2d.TouchZoomAndPan" 
     plot="plot" maxScale="7"></div>

plot 属性により、チャートの特定のプロット (この例では plot という名前のプロット) にアクションを追加することができます。その他にも、例えばズームを許可するかどうか (enableZoom="false")、あるいはチャートに適用できるスケールの最大値 (maxScale="7") など、さまざまなオプションを使用することができます。

便利なタッチ操作の別の例として、チャートにタッチした場合にデータ・インジケーターを表示する機能があります。さらには、2 つのタッチ・ポイント間の傾向を表示するデュアル・データ・インジケーターも考えられます。

リスト 13 のコードを使用すると、チャートに一度触れた場合に図 3 のような結果が表示されます。

リスト 13. タッチ・インジケーターのサポートを追加する
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot" 
     series="data" dualIndicator="true"></div>
図 3. インタラクティブで単純なタッチ・インジケーター
この図は単純なタッチ・インジケーターを示しています。インジケーターとして、タッチされたデータ・ポイントの値が表示されています。

デュアル・タッチ・ジェスチャーを使用すると、図 4 のような結果が表示されます。

図 4. インタラクティブなデュアル・タッチ・インジケーター
この図はデュアル・タッチ・インジケーターを示しています。インジケーターとして、タッチされた 2 つのデータ・ポイント間の差がパーセントで表示されています。

タッチ操作には、データ・インジケーターの色やフォントを変更する機能など、他にもいくつかパラメーターがあります。さらには、2 つのタッチ・ポイント間の傾向がプラスかマイナスかによってインジケーターの塗りつぶし色を変更するかどうかを決定することもできます。リスト 14 は、このようなインジケーターを JavaScript で作成する方法の例を示しています。

リスト 14. タッチ・インジケーターを JavaScript で構成する
var indicatorFillFunc = function(v1, v2){
  if(v2){
    return v2.y>v1.y?"green":"red";
}else{
  // single touch point
    return "#ff9000";
  }
};
var indicator = new TouchIndicator(chart, "plot", {
               series: "series", dualIndicator: true, 
               font: "normal normal bold 12pt Helvetica",
               fillFunc: indicatorFillFunc
});

モバイル機器によっては (例えば Android 2.2 や 2.3 を搭載した機器など)、ブラウザーでの複数のタッチ・イベントをサポートしていないものもあります。その場合は、ズーム・インやズーム・アウトなど、デュアル・タッチを利用する特定のアクションを、すべての機器で利用可能なボタンやタッチ操作にマッピングする必要があるかもしれません。この記事の例の場合では、最初から非アクティブのままになっているボタンがユーザー・インターフェースの中にあるので、ここで少しコードを追加し、これらのボタンに対してクリック操作やタッチ操作を行った場合にボタンが応答するようにしましょう。リスト 15 はズーム機能を指定する方法を示しています。

リスト 15. ズーム機能を指定する
          <button id="b1" data-dojo-type="dojox.mobile.Button" 
		    onclick="zoomChart()"
            class="mblBlueButton">Zoom</button>
          <button id="b2" data-dojo-type="dojox.mobile.Button"
		  	onclick="zoomChart(true)" 
            class="mblBlueButton">Unzoom</button>

リスト 15 のコードは Zoom ボタンと Unzoom ボタンの両方の zoomChart 関数を呼び出します。Zoom アクションと Unzoom アクションは非常に似ているため、1 つの引数を持つ 1 つの関数のみを使用し、引数に true を設定すると Unzoom アクションが実行されるようにします。

リスト 16 に示すように、JavaScript ソース・ファイルで zoomChart 関数を定義します。考え方としては、現在表示されている部分の境界を取得して新しい範囲を計算し、Dojo チャート・コンポーネントの zoomIn 関数に渡します。

リスト 16. JavaScript で zoom 関数を実装する
  zoomChart = function(back){
    var chart = dijit.byId("chart").chart;
    var b = chart.getAxis("x").getScaler().bounds;
    var r = 1.25;
    if (back){
      // Unzoom
      chart.zoomIn("x", [b.from / r, b.to * r]);
    }else{
      // Zoom
     chart.zoomIn("x", [b.from * r, b.to / r]);
    }
};

アプリケーションを最適化する

これで、完全に動作する Dojo モバイル・チャート・アプリケーションを作成することができましたが、このアプリケーションはまだ完全には最適化されていません。

最初に取り組む最適化は、レンダリング時間の改善です。モバイル機器は通常、デスクトップ機器に比べて CPU やメモリーに関する処理が低速なため、デスクトップ機器よりもレンダリングに時間がかかります。デフォルトで、Dojo はチャート上にレンダリングされた対象をキャッシュに入れません。タッチ操作を使用してチャートをズームまたはパンする場合、レンダリング対象の多くは、破棄された後、再作成される可能性があります。静的なチャートの場合には、キャッシュを有効にしない方が最初のレンダリングが速くなるため望ましいですが、動的なチャートの場合には、キャッシュを有効にした方が望ましいです。いくつかのチャート要素に対しては、enableCache パラメーターを使用することができます。

コード内で、チャート要素に対して enableCachetrue に設定します (リスト 17)。

リスト 17. レンダリングを最適化する
<div data-dojo-type="dojox.charting.widget.Chart" id="chart" 
    style="width: 100%; height: 180px;">
<div class="plot" name="grid" type="Grid"
    vMinorLines="true" enableCache="true"></div>
    <div class="axis" name="x" enableCache="true"
        fixUpper="minor"   
        majorTickStep="1"
        minorTicks="false"
        labelFunc="displayDate"></div>
    <div class="axis" name="y" vertical="true" min="0"></div>
    <div class="plot" name="plot" type="Columns" enableCache="true"></div>
    <div class="series" name="data" store="store" plot="plot"></div>
    <div class="action" type="dojox.charting.action2d.TouchZoomAndPan" 
        plot="plot" maxScale="7"></div>
</div>

この例では Y 軸のキャッシュを有効にしていません。ズーム・インやズーム・アウトを行う場合、Y 軸付近のチャートが再レンダリングされることはなく、従って最適化してもメリットはありません。

モバイル・チャート・アプリケーションのレンダリングを最適化するための別の方法として、不必要なレンダリングを防止する方法があります。例えば、縦棒グラフに縁取りや影が付いている場合があります。これらの縁取りや影は絶対に必要なものではありませんが、レンダリングには時間がかかります。そのため、これらを削除することを検討するとよいかもしれません。別の例として、データ・インジケーターの縁取りを削除する方法も考えられます。そのためにはデータ・インジケーターの縁取りに対応するスタイル・プロパティーを null に設定します (リスト 18)。

リスト 18. 不必要なレンダリングを削除する
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot" 
     series="data" dualIndicator="true" outline="null" lineOutline="null"
     markerOutline="null"></div>

アプリケーションのロード時間の最適化は重要ですが、ネットワーク接続が必ずしもデスクトップ・アプリケーションほど高速とは限らないモバイル機器では特に重要です。Dojo では新しい AMD ローダーを利用できるため、さまざまな必須ファイルを同期してロードする代わりに非同期でファイルをロードし、ロード全体でのパフォーマンスを向上させることができます。そのためには Dojo の最初の構成に async パラメーターを追加します (リスト 19)。

リスト 19. 非同期のロードを有効にする
    <script type="text/javascript" src="../../../dojo_current/dojo/dojo.js"
      data-dojo-config="parseOnLoad: true, async: true"></script>

アプリケーションにとって絶対に必要なわけではないユーティリティーを削除することで、さらにロード時間を改善することができます。例えば、このモバイル・チャート・アプリケーション全体は、dojox.mobile パーサーを利用するマークアップを使用して定義されました。この軽量のパーサーは通常の Dojo のパーサーよりもはるかに軽量ですが、それでもこのパーサーを使用した場合よりもさらにアプリケーションのダウンロード・サイズを削減したい場合には、このパーサーを完全に削除し、JavaScript でアプリケーションを作成することもできます。


まとめ

この記事では、モバイル Web アプリケーションの中で Dojo のチャート・パッケージを使用する方法について説明しました。このパッケージをモバイル機器用に調整することで、マウスやボタンの代わりにタッチ・イベントを利用して操作を行えるようになります。またこの記事では、ロード時間とレンダリング時間を改善するための高度なオプションについても説明しました。

この記事で説明した内容をさらに追求したい場合には、Dojo のチャート機能を容易に拡張することができます。Dojo のチャート機能の上に独自の機能を作成することもできます。例えば、Dojo のフレームワークに用意されている以外のタッチ操作が必要な場合には、Dojo のチャート・アクション・パッケージを拡張して独自の対話動作を実現することもできます。


ダウンロード

内容ファイル名サイズ
Source codesource.zip10KB

参考文献

学ぶために

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=756725
ArticleTitle=Dojo Toolkit を使用してモバイル用のチャートを作成する
publish-date=09162011