2006/05/03(水)GD::Graphのあれこれ(Perl)
2006/05/03 17:06
■GD::Graphの生成画像にイメージマップを貼る
GD::Graph::Mapを使う手もあるがどうも使い勝手が悪い。そこでhotspot()メソッドを使う。
use GD::Graph::points; my $graph = GD::Graph::points->new(400,300); @data = ( ['1st', '2nd', '3rd'], [1, 2, 3], ); my $image = $graph->plot(\@data) or die; my @ret = $graph->get_hotspot(1); for(my $i = 0; $i < @ret; $i++) { print "<area shape=$ret[$i][0] Coords=$ret[$i][1],$ret[$i][4],$ret[$i][2],$ret[$i][3]>\n"; }こんな感じで。第1引数はデータ系列番号(1始まり)、第2引数はデータ系列中のデータ番号(0始まり)。共に省略可。
ソースをざっと見た限りでは、生成したグラフのタイプによってtop, bottom, left, rightがどの順で帰ってくるか違ってるような気がする。
プログラム作成時にテストした方がよい。
なお、どうでもいい話であるが、このメソッドいつも「ホッツポット」と読んでしまう。なんでだ?
■numerical X(x軸を数字として扱う)
GD::Graphは基本では全てのXを見出しとして等価に扱う。
だが、散布グラフや1つの列に2つ以上のデータをプロットする場合など、X座標を数字として扱いたい機会は多い。
GD::Graphのマニュアルにあるとおりこの機能は本来はunsupportedである。従って、ちょっとやり方が複雑。
- x_min_value, x_max_value, x_tick_numberの3つを設定する
- データ系列が3つ以上の値を含む
- x軸のデータが全て数字
この3条件を満たすときに数字として扱ってくれるようだ。
use GD::Graph::points; my $graph = GD::Graph::points->new(400,300); @data = ( [1 ,1, 10], [1, 2, 3], ); $graph->set( x_min_value => 0, x_max_value => 30, x_tick_number => 10, ); my $image = $graph->plot(\@data) or die; open(OUT, ">test.png") or die; binmode OUT; print OUT $image->png(); close(OUT);setメソッド中の3行はどれをコメントアウトしても表示がおかしくなると思う。
■グラフ座標を画像のピクセル座標に変換
val_to_pixel()メソッドを使う。本来プライベートメソッドであるべきものを呼んでる気がするけども。
use GD::Graph::points; my $graph = GD::Graph::points->new(400,300); @data = ( ['1st', '2nd', '3rd'], [1, 2, 3], ); my $image = $graph->plot(\@data) or die; my $green = $image->colorAllocate(0, 255, 0); my @p1 = $graph->val_to_pixel(1, 1); my @p2 = $graph->val_to_pixel(3, 3); $image->line(@p1, @p2, $green); open(OUT, ">test.png") or die; binmode OUT; print OUT $image->png(); close(OUT);(1,1)から(3,3)の間に直線を引く。numerical Xにした場合でもちゃんと動くようだ。
なお、普通の解説とかサンプルは下記参考サイトが詳しい。
お、Rubyにラッパーあるね。まだ触って無いけど。
[マニュアル]
http://search.cpan.org/~bwarfield/GDGraph-1.4307/Graph.pm
[サンプル]
http://x68000.q-e-d.net/~68user/webcgi/gd-graph.html
http://www.linkclub.or.jp/~ma3ki/webutil/gdgraph/howtograph.html