2009-04-06 22:53:26
このGoogle Chart APIというのは、つい最近できたものでもないのだけど、私が知ったのはつい3ヶ月ほど前で、使う機会を窺っていた。引っ越しも終わったということで、ちょっと試してみたので報告する。
今日は試しということで、私の本の購入数を日記の○と●の数を集計してGnuplotを使ってグラフを表示させているものを、Google Chart APIで書いてみることにする(と書いても私の読書日記を読んでいない人にはまったく意味不明だろうけど、日々購入した本を記録し、和書の頭には●、洋書の頭には○をつけている。だから、●と○の数を数えると購入した和書と洋書の数を集計できるのだ。もちろん、他の意味で○とか●を使わないように気をつけている)。
MySQLでデータを出して、数え上げた数を使ってURLを生成することにする。今回はPHPでURLを作る。
<?php if(!$con=mysql_connect("localhost","user","password")){ echo"接続失敗"; exit; } if(!mysql_select_db("database",$con)){ echo"データベース選択失敗"; exit; } mysql_query("SET group_concat_max_len=100000"); $sql = "select year,month,group_concat(body) from diary group by year,month order by year desc,month desc limit 12"; if(!$res=mysql_query($sql)){ echo "SQL失敗<BR />"; exit; } // 検索結果表示 $out=""; $month = array(); $wa = array(); $yo = array(); $tl = array(); $values = array(); while($row=mysql_fetch_array($res)){ if(strlen($row[1])==1){ $mn = "0".$row[1]; }else{ $mn = $row[1]; } $mnth = substr($row[0],2,2).$mn; $black = substr_count($row[2],"●"); $white = substr_count($row[2],"○"); $total = $black + $white; // echo $mnth.":".$black."|".$white."|".$total."\n"; array_push($month,$mnth); array_push($wa,$black); array_push($yo,$white); array_push($tl,$total); array_push($values,$total); } // 結果セットの開放 mysql_free_result($res); // データベースから切断 mysql_close($con); $mx = max($values); $url = "http://chart.apis.google.com/chart?chs=400x300&cht=lc&chco=ff0000,00ff00,0000ff&chdl=JapaneseBooks|ForeignBooks|Total&chxt=x,y&"; $url .= "chxr=1,0,".$mx."&"; $url .= "chxl=0:|".$month[11]."|".$month[8]."|".$month[5]."|".$month[2]."|".$month[0]."&"; $url .= "chd=t:".implode(",",array_reverse($wa))."|".implode(",",array_reverse($yo))."|".implode(",",array_reverse($tl))."&"; $url .= "chds=0,".$mx; echo $url."\n"; ?>
MySQLのselect文で、group_concatというのを初めて使った。グループ化されて返ってきた結果の文字列を繋いでくれる呪文である。これが最初はどうも様子がおかしくて、途中で文字列が途切れてしまうのだ。初期状態で長さの上限が設定されているらしい。ということで、mysql_query("SET group_concat_max_len=100000");というようにして、上限を大幅に拡張した。これで最近12ヶ月の和書購入数、洋書購入数が判るようになる。それから両方を足した値も計算してGoogle Chart API用のURLを作る。
ここで設定している条件は、
chs:画像の大きさ
chdl:凡例の項目名
chxt:軸ラベルの指定
cht:グラフ種の指定
chco:色の指定
chxr:軸範囲の設定
chxl:軸ラベルの設定
chd:値の入力
chds:最小値・最大値の設定
となっている。できあがったURLがこれ:
http://chart.apis.google.com/chart?chs=400x300&cht=lc& chco=ff0000,00ff00,0000ff&chdl=JapaneseBooks|ForeignBooks|Total&chxt=x,y& chxr=1,0,23&chxl=0:|0805|0808|0811|0902|0904& chd=t:8,10,17,10,15,12,14,15,12,10,15,3|11,13,4,6,3,0,3,3,1,1,3,3|19,23,21,16,18,12,17,18,13,11,18,6& chds=0,23もちろん、本当は改行なしで使う。できあがったグラフは、これ。
あれ、何だか本の数が少ないなあ。どうもまだgroup_concatの上限に引っかかっているようなのだ。そこでSET group_concat_max_len=300000;と上限を増やしてみると、
mysql> select year,month,length(group_concat(body)) from diary group by year,month order by year desc,month desc limit 12; +------+-------+----------------------------+ | year | month | length(group_concat(body)) | +------+-------+----------------------------+ | 2009 | 4 | 17382 | | 2009 | 3 | 134978 | | 2009 | 2 | 133447 | | 2009 | 1 | 208242 | | 2008 | 12 | 215136 | | 2008 | 11 | 136703 | | 2008 | 10 | 199332 | | 2008 | 9 | 194347 | | 2008 | 8 | 156880 | | 2008 | 7 | 131728 | | 2008 | 6 | 155875 | | 2008 | 5 | 179206 | +------+-------+----------------------------+ 12 rows in set (0.03 sec)となって、上限に引っかかる数値はないことが確認できた。次に日本語のラベルにしたいので、
$washo = urlencode("和書"); $yosho = urlencode("洋書"); $gokei = urlencode("計");として、 $url .= "chdl=".$washo."|".$yosho."|".$gokei."&chxt=x,y&"; という感じにしてみると。
http://chart.apis.google.com/chart?chs=400x300&cht=lc&chco=ff0000,00ff00,0000ff&chdl=%E5%92%8C%E6%9B%B8|%E6%B4%8B%E6%9B%B8|%E8%A8%88&chxt=x,y&chxr=1,0,38&chxl=0:|0805|0808|0811|0902|0904&chd=t:18,14,22,15,27,21,19,31,19,20,18,3|18,22,5,7,11,3,3,7,3,1,3,3|36,36,27,22,38,24,22,38,22,21,21,6&chds=0,38となりグラフはこうなる。 ようやく今まで描かせていたグラフとほぼ同じものが得られた。前は18ヶ月表示させていたが、今回のは12ヶ月である。そのうち、PHPファイルを埋め込むことでグラフが表示されるようにして、どこかで使うことにしようかな。今回は私にとってはGoogle Chart APIよりも、MySQLのgroup_concatの使い方を知ったことの方が意味が大きいような気がする。