PEAR::Image_Graphvizを使って山手線の路線図を書いてみた
GraphvizはAT&Tが作ったグラフ構造を描画するツールで、こんな図やこんな図をSVG形式、pngやgifで出力できます。
で、PEARにもPEAR::Image_Graphvizが登録されています。このパッケージの仕組みはかなりベタベタで、dotコマンド(Graphvizで用意されているコマンドの1つ)にパラメータを渡して実行・実ファイルを作成してそれを返す、といったものになりますので、当然コマンド群をインストールしておく必要があります。
PHPスクリプトの例は、pear/Image/GraphViz.phpのコメントにもありますが、次の様な感じです。
<?php require_once 'Image/GraphViz.php'; $graph = new Image_GraphViz(); $graph->addNode( 'Node1', array( 'URL' => 'http://link1', 'label' => 'This is a label', 'shape' => 'box' ) ); $graph->addNode( 'Node2', array( 'URL' => 'http://link2', 'fontsize' => '14' ) ); $graph->addNode( 'Node3', array( 'URL' => 'http://link3', 'fontsize' => '20' ) ); $graph->addEdge( array( 'Node1' => 'Node2' ), array( 'label' => 'Edge Label' ) ); $graph->addEdge( array( 'Node1' => 'Node2' ), array( 'color' => 'red' ) ); $graph->image(); ?>
このコードで、
のようなsvgファイルが出力されます。ただし、日本語を使う場合、
する必要があるんですが、毎回mb_convert_encodingとかしてると面倒なので、
<?php require_once 'Image/GraphViz.php'; class Image_GraphViz2 extends Image_GraphViz { function _convertEncoding($str) { return mb_convert_encoding($str, 'utf-8', 'auto'); } function Image_GraphViz2($directed, $attributes, $name) { parent::Image_GraphViz($directed, $attributes, $name); } function parse() { return $this->_convertEncoding(parent::parse()); } }
みたいなクラスを作ってしまった方が早いと思います。
ここまでを踏まえて、タイトル通り、山手線の路線図を書いてみました。次の様なコードになります。
<?php error_reporting(E_ALL); require_once 'Image/GraphViz.php'; class Image_GraphViz2 extends Image_GraphViz { function _convertEncoding($str) { return mb_convert_encoding($str, 'utf-8', 'auto'); } function Image_GraphViz2($directed, $attributes, $name) { parent::Image_GraphViz($directed, $attributes, $name); } function parse() { return $this->_convertEncoding(parent::parse()); } } ?> <?php $stations = array('品川', '田町', '浜松町', '新橋', '有楽町', '東京', '神田', '秋葉原', '御徒町', '上野', '鶯谷', '日暮里', '西日暮里', '田端', '駒込', '巣鴨', '大塚', '池袋', '目白', '高田馬場', '新大久保', '新宿', '代々木', '原宿', '渋谷', '恵比寿', '目黒', '五反田', '大崎'); $default_options = array('fontsize' => '12', 'fontname' => '/usr/share/fonts/ja/TrueType/kochigothic.ttf'); $graph_attributes = array(); $graph = new Image_GraphViz2(false, $graph_attributes, '山手線'); $prev_station = null; foreach ($stations as $station) { $graph->addNode($station, $default_options); if (is_null($prev_station)) { $graph->addEdge(array($stations[count($stations) - 1] => $station)); } else { $graph->addEdge(array($prev_station => $station)); } $prev_station = $station; } $graph->image('png'); // var_dump($graph->parse());
まあ、路線図書いたからってどうってことないんですが(^^;、何らかのフローを機械的に描きたいときとかは便利かな、と。PHPソースからフローチャートを生成する - Shin x blogで紹介されていたツールも、頑張ればできるかも。。。