Google Chart 円グラフを作成

JavaScript

今回は Google Chart の円グラフを複数作成する際の注意点と工夫してみた点を書いていこうと思います。

Sample 1 シンプルな円グラフ

まずいきなりサンプルから提示します。シンプルに一つの円グラフを作成するソースがこちら

https://jsfiddle.net/sdoi883/rty70kLs/47/

すごくシンプルなソースですね!HTMLに関して言えば、DIVタグ1行で終わりです。
上記サンプルでは表示するデータをjavascriptの中に含めています。これだと動的に値を変えられないですねー
次は表示データをHTMLに埋める形に変更してみましょう。

Sample 2 データをHTML側に移した円グラフ

https://jsfiddle.net/sdoi883/rty70kLs/49/

どうってことないでしょ?HTMLソースの最後に、配列定義を移しただけです。
このsysDataをjavascript側で拾ってくれます。

ポイントは javascript ソースの2行目に書いてある
google.charts.setOnLoadCallback という呪文。

OnLoadCallback なので、画面がロードされた際に、カッコの中のfunctionを呼びますよーって具合ですね。
なので、HTMLの最後に定義した変数の値もちゃんと認識してくれるようです。便利。

あとはHTMLを出力する処理でsysData部分をそれぞれの言語で組んであげればOKですね。

では、次のステップに行ってみましょー

Sample 3 複数の円グラフ

https://jsfiddle.net/sdoi883/rty70kLs/55/

円グラフの数を増やすと何が変わるか?というと

  • HTMLのDIVが増える(グラフを埋め込むためのタグ)
  • chart変数が増える(グラフを描画するためのオブジェクト)
  • inputDataが増える(グラフ毎にデータの準備が必要)
  • イベントリスナーが増える(クリックされた時のイベントを拾う)

という感じでソースが肥大化していきます。。。冗長的な書き方も嫌ですよね

Sample 4 複数の円グラフ 2

グラフデータの数と、HTMLのDIVタグを変えるだけで円グラフを描画できるようにカスタムしてみましょう。

まず、グラフデータを配列化します。これを回せばグラフが書けそうです。
あとはchart変数が増えるというところも配列化しましょう。このオブジェクトを使いまわすとバグにつながります。
お次にイベントリスナーですが、これは量産する必要がなくなります。

https://jsfiddle.net/sdoi883/rty70kLs/78/

こんな感じです。

あ、ちなみに言うのが遅くなりましたが、selectHandlerというfunctionはグラフの要素がクリックされた時に動きます。

上に示したサンプルだと、クリックされた要素を検知するところで問題が出てしまうんですよね。
どんな問題が発生するかというと

複数のグラフがクリックされると、クリックされた場所を特定できない

はい。。。。これが致命的でした。

それぞれのchartオブジェクトは、自分がグラフ化しているデータのどの行が選択されているかを保持しています。
裏を返せば、自分以外の事は考えていません。何個chartが並んでいようが、関係ありません。

なので、上記サンプルで言えば、1つ目のchartと2つ目のchartで選択されている両方がクリックされているものとして
見えてしまいます。これはこれで、各グラフで選択されているすべての要素を取得するのであればOKですが。。。

でも、大体「今クリックされたものが何か?」を知りたいですよね。。。

はい、対策を取りましょう。

Sample 5 今、クリックした要素がどれか特定する

https://jsfiddle.net/sdoi883/rty70kLs/118/

HTMLの部分はサイズをちょこっと変更しただけで、データの中身等はそのままです。
ソース部分の表示にスペースを取りたかったのでレイアウトを変更しました。

何を変更したかというと、

  • 各グラフの選択状態を記憶する変数を追加
  • 今、クリックされた要素以外の選択状態をクリアする処理を追加
  • 今、クリックされた要素を判定する条件が複雑になるので、判定メソッドを独立

こんな具合です。

チャートを作りながら、選択されていない(初期)状態で変数selectedChartに格納していきます。

チャートがクリックされたら、次のような判定で新たな選択かどうかを決めます。
・前回クリックされたチャートとは違うチャートがクリックされたらOK
・前回クリックされたチャートと同じだが、要素が異なるのであればOK

今回クリックされたチャート以外は初期状態としたいので、arrChart[idx].setSelection([]);を追加しています。
この記述でそのチャートの選択状態はクリアされます。

おわり

どうでしたか?私はこれを解決するのに大分時間がかかりました。。。

まだまだ修行が足りないですね。

同じような悩みを抱えている方のお役に立てればと思います。

ではまた!