パワーポイントなどで図を描こうとすると、レイアウトやサイズなどがなかなか決められず、サクッと描くことができない性分です。
設定を変更できるから迷うのであって、いっその事、ガチガチに制約があった方が割り切れていいんじゃないかと、よくある、テキストで描かれた図を作成するツールを検討してみました。
そのようなツールはいくつかあるのですが、一番シンプルで分かりやすかった「Graph::Easy」を使ってみることにしました。
Graph::Easyの使い方はそれほど難しくないのですが、CUIツールなので使っていないとすぐに忘れてしまうため、個人用備忘録としてここにまとめました。
インストール
Graph::EasyはPerlのモジュールなのでcpanを使ってインストール
cpan Graph::Easy
cpanが入っていない場合は下記でcpanをインストール
sudo apt-get install build-essential
使い方
ファイルを介した方が後々楽なのでその方法を記す。結果は標準出力に出力されるので、必要ならばリダイレクトでファイルに出力する
graph-easy <インプットファイルパス>
書き方
基本:ノードに線を引く
- 線の向きは「直線」「矢印」「双方向矢印」
- 線の種類は「-」「.」「=」
- 他にもあるが、テキストなので違いはほとんど分からず、これで十分
■入力■ [A]--[B]->[C]<->[D] [E]..[F].>[G]<.>[H] [I]==[J]=>[K]<=>[L] ■出力■ +---+ +---+ +---+ +---+ | A | --- | B | --> | C | <--> | D | +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ | E | ... | F | ..> | G | <..> | H | +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ | I | === | J | ==> | K | <==> | L | +---+ +---+ +---+ +---+
ノードの並びは、アウトプットが左でインプットが右に決まっている。右から左、つまり「[B]<-[C]」という書き方はできない。そういう場合は「[C]->[B]」の行を追加する。
■入力■ [A]->[B] [C]->[B] ■出力■ +---+ +---+ +---+ | A | --> | B | <-- | C | +---+ +---+ +---+
線に名前をつける。ノードの表示名を変える
■入力■ [A]--{label:line}[B] [C]{label:node}--[D] ■出力■ +------+ line +---+ | A | ------- | B | +------+ +---+ +------+ +---+ | node | ------- | D | +------+ +---+
線に名前をつける方法は他に「[A]- line ->[B]」」というやり方もあるが、これは向きの無い線(「--」など)には使えないので、「label」を使ったやり方に統一しておいた方が覚えることが少なくて済む。
分岐・合流
■入力■ [A]->[B]->[C] [D]->[B] [B]->[E] ■出力■ +---+ | E | +---+ ^ | | +---+ +---+ +---+ | A | --> | B | --> | C | +---+ +---+ +---+ ^ | | +---+ | D | +---+
各線のつながりを1つ1つ分けて書いていけば、Graph::Easyがよしなにつないでくれる。
1点からの分岐・1点への合流
■入力■ [A]->{start:front,0}[B] [A]->{start:front,0}[C] ■出力■ +---+ +---+ | A | -+-----> | B | +---+ | +---+ | +---+ +-----> | C | +---+ ■入力■ [A]->{end:back,0}[C] [B]->{end:back,0}[C] ■出力■ +---+ +---+ | A | ------+-> | C | +---+ | +---+ | | | +---+ | | B | ------+ +---+
線の途中の分岐・合流
■入力■ [L1]{shape:edge} [L2]{shape:edge;label:""} [A]--[L1]->[B]--[L2]->[C] [L1]->[D] [E]->[L2] ■出力■ +---+ L1 +---+ +---+ | A | -------------> | B | ------------> | C | +---+ +---+ +---+ | ^ | | v | +----+ +---+ | D | | E | +----+ +---+
「{shape:edge}」でノードを線の途中のポイントとすることができる。ポイント名をlabelで無名にすると、名前が表示されなくなる。
グループ化
■入力■ (GroupA [A]->[B]) [B]->[C] [A]->[D] ■出力■ + - - - - - - - - - -+ ' GroupA ' ' ' ' +------+ +---+ ' +---+ ' | A | --> | B | ' --> | C | ' +------+ +---+ ' +---+ ' ' + - - - - - - - - - -+ | | v +------+ | D | +------+
「()」で囲むとグループになる。ただ、イマイチ使い勝手が良くないので、あまり凝ったことはせず、アクセント程度に用いるのがよさげ。
全体の向きの変更
■入力■ graph{flow:south} [A]->[B] ■出力■ +---+ | A | +---+ | | v +---+ | B | +---+
何も設定しないと図は左から右に描かれるが、「graph{flow:[north|south|east|west]}」で全体の向きを指定できる。
線が出ていく面と、入っていく面の指定
■入力■ [A]->{start:north; end:south}[B] ■出力■ +----+ | | +---+ | +---+ | A | | | B | +---+ | +---+ | ^ +----+
どうしても、この面から線が出て、この面へ入っていくのを決めたい時は、指定することが可能。どちらか一方だけの指定も可能。
同じ面から複数の線を並行に出す
■入力■ [A]->{start:east}[B] [A]->{start:east}[C] [A]->{start:east}[D] ■出力■ +---+ +---+ | | --> | B | | | +---+ | | +---+ | A | --> | C | | | +---+ | | +---+ | | --> | D | +---+ +---+
同じ面から複数線を定義すると、複数の線が並行に並ぶ。
ノードの枠線を変える
■入力■ [A]->[B]{border:dotted} ■出力■ +---+ ..... | A | --> : B : +---+ :...:
他にもあるが、テキストなので違いはほとんど分からず、これで十分
テキスト折り返し
■入力 [A\nB]->[C]{label:C\nD} ■出力■ +---+ +---+ | A | | C | | B | --> | D | +---+ +---+
「\n」で改行を入れられる。
画像出力
dot形式で出力して画像化する場合
「dot」を使って画像を作成しているのでdotが必要。dotは「Graphviz」をインストールすると付いてくる。
sudo apt-get install graphviz
「-png」オプションでpng出力
graph-easy <入力ファイル名> -png
画像サイズを指定する場合は、一旦「dot」形式で出力して、それを「dot」に渡してオプションで指定する。
graph-easy <入力ファイル名> -as_dot | dot -Tpng -Gsize=1 -Gdpi=500 -o <出力ファイル名>
上記は500pxの出力例。縦横のどちらか大きい方の最大値が指定値になる。(縦のみ、横のみのサイズ指定は無理そう)
テキストを画像化する場合
「Imagemagick」を使ってテキストを画像化する。Imagemagickが入っていない場合はインストール。
sudo apt-get install imagemagick
色、サイズを指定して出力
graph-easy <入力ファイル名> | \ head -c -1 | \ convert -background "#ffffff" -fill "#000000" -font "FreeMono" -size 100x100 \ label:@- <出力ファイル名>
最後に改行が入るので「head -c -1」で取り除いている。
幅を指定して縦をよしなにする場合は、「-size 100x」と縦を指定しない。ただし、その時の出力画像の縦サイズは、1フォント分の縦になるので、テキストの縦行数から実際の縦幅を計算して、「-size 100x<計算後の縦サイズ>」で再度出力し直す。
縦を指定して横をよしなにする場合は、「-size x100」と幅を指定しない。