f

2013-11-17

Fancy arrow in LaTeX

発表やフロー図などを作成するときに矢印を使うことがある。しかし、LaTeXで標準で実装されている矢印は主に数式で使われるようなもので矢印が小さい。矢印の中に文字を書き込むといった処理は簡単にはできないし、矢印が小さいので見栄えも悪くかなり使いづらい。
フロー図などで使われる大きな矢印をLaTeXでも簡単に使えるようなコマンドはないかと以前から探していたのだが、昨日(11月16日)ようやくその手がかりを見つけた。

1.1 矢印コマンド

以下の参考リンクでClaudio Fiandrino氏の回答でTikZを使って\tikzfancyarrowというコマンドを定義する方法が書いてある。
定義
  • \tikzfading[name=arrowfading, top color=transparent!0, bottom color=transparent!95]
    \tikzset{arrowfill/.style={#1,general shadow={fill=black, shadow yshift=-0.8ex, path fading=arrowfading}}}
    \tikzset{arrowstyle/.style n args={3}{draw=#2,arrowfill={#3}, single arrow,minimum height=#1, single arrow,
    single arrow head extend=.3cm,}}
    ​
    \NewDocumentCommand{\tikzfancyarrow}{O{2cm} O{FireBrick} O{top color=OrangeRed!20, bottom color=Red} m}{
    \tikz[baseline=-0.5ex]\node [arrowstyle={#1}{#2}{#3}] {#4};
    }
    
このコマンドの書式は以下。
\tikzfancyarrow[<height>][<color>][<tikz option>]{<contents>}
引数の役割は以下の表にまとめた。
引数役割
<height>矢印の最低長さ
<color>矢印の枠の色
<tikz option>tikzのオプション
<contents>矢印の中に書く文字
[<height>][<color>][<tikz option>]はオプションなので書かなくてもよい。指定がなければ標準値が適用される。
このコマンドのままでもそれなりに有用だが、個人的にいくつか不満がある。
  1. 引数が多すぎる。
  2. 影が不要。
  3. グラデーションが不要。
  4. 矢印の枠が不要。
  5. <contents>を指定しないと指定した場合と矢印の柄の太さが異なる。
2-4は標準の設定でどうにかなりそうだが、1と5が自分には致命的だ。まず2-4の不満は以下2点にまとめられる。
  • 影やグラデーションは印刷するときにちんと印刷されないときがある。
  • 矢印の枠はごちゃごちゃした印象を与えることが多く、ない方がすっきりする。
1の不満について、引数は多ければ多いほどどのオプションが何の設定だったか忘れるので効率が悪い。Claudio Fiandrino氏の提案した\tikzfancyarrowは矢印の柄の長さだけを指定したければ、
\tikzfancyarrow[1cm]{hoge}
とすれば良いのだが、回転だけさせたければ
\tikzfancyarrow[][][rotate=90]{hoge}
というように前2つのオプションを空にしないといけない。これは見た目も悪いし効率も悪く覚えにくくなっている(と思う)。
5の不満について、この\tikzfanyarrowコマンドは必須引数として矢印の中身の文字を要求している。このコマンド自体がtikzのsingle arrowであるためだ。このコマンドは矢印の中身の文字にフィットするように幅と高さを自動で調整してくれるため通常は便利なものだ。しかし、矢印の中身を書かずに矢印だけを書きたいことが往々にしてある。もちろん以下のように文字を指定しなければそれは可能だ。
\tikzfancyarrow{}
ただし、このようにすると矢印の柄の太さが、引数に文字を指定した場合と不揃いになってしまう。これは矢印を並べてみた場合に見た目が悪くなってしまうので避けたい。

1.2 矢印コマンドの改良

以上の1--5の不満点を解消し、普段使いに適する矢印を作成するためClaudio Fiandrino氏の\tikzfancyarrowコマンドを自分用に修正してみた。以下にそのコマンドの定義を記す。
\usepackage{tikz}
\usepackage{xparse}
\usetikzlibrary{shapes,arrows}
%% define fancy arrow. \tikzfancyarrow[<option>]{<text>}. ex: \tikzfancyarrow[fill=red!5]{hoge}
  \tikzset{arrowstyle/.style n args={2}{inner ysep=0.1ex, inner xsep=0.5em, minimum height=2em, draw=#2, fill=black!20, font=\sffamily\bfseries, single arrow, single arrow head extend=0.4em, #1,}}
  \NewDocumentCommand{\tikzfancyarrow}{O{fill=black!20} O{none}  m}{
    \tikz[baseline=-0.5ex]\node [arrowstyle={#1}{#2}] {#3 \mathstrut};}
修正点
    • 影の設定を除去。
    • O{none}により標準をdraw=noneとして枠を消去。
    • 標準の矢印の色をfill=black!20にした。
    • \mathstrutコマンドにより支柱を立て、コマンドの引数に文字列を指定しなかった時と指定した時の矢印の柄の太さを統一。
本当はオプション引数を1つだけにしたかったがうまくいかず、やむを得ずdrawの値を指定するオプション引数も指定した。
\tikzfancyarrow[<tikz option>][<frame color>]{<contents>}
ただ、第1オプションにより広範な設定ができる<tikz option>を持ってきたので、基本的には<tikz option>で枠の色もdraw=<color name>というように指定すればよい。
使い方
    • 上記コマンドの定義をプリアンブルに記入。
    • 以下のコマンドを入力。
      \tikzfancyarrow[<tikz option>]{<contents>}
      
これで矢印がかける。<tikz option>はオプションなので書かなくても良い。標準の色はblack!20で、<contents>を指定しなければ2emの柄の長さの矢印になる。矢印の色は<tikz option>でfill=blue!20, draw=redのようにすることで指定可能。標準では矢印は右向きになる。 左向きの矢印が必要なら、shape border rotate=180を設定する。<tikz option>にはtikzで使えるオプションがだいたいなんでも使える。以下でよく使うオプションとその説明をまとめる。
オプション引数役割
minimum height矢印の柄の最低長さ。
minimum width矢印の先端の太さ。矢印全体の大きさを変えるならこの値を変えると楽。
rotate矢印全体の回転角度。rotateboxと同機能。
shape border rotate文字の向きはそのままで矢印だけ回転。
double arrow両端を矢印にする。
text width文字列の幅を指定。矢印内で複数行書くときに必要。これを設定していると強制改行\\が有効。\parは不可。
  • \tikzfancyarrow{hoge}
    \tikzfancyarrow[minimum width=5em]{} % big arrow
    \tikzfancyarrow[fill=blue!20]{hoge} % blue arrow
    \tikzfancyarrow[rotate=90]{hoge} % rotate whole arrow
    \tikzfancyarrow[shape border rotate=90]{hoge} % rotate arrow keeping text direction
    \tikzfancyarrow[text widt=3ex]{hoge hoge hoge hoge} % multple line
    
LyX用の設定
  • このtikzfancyarrowコマンドはこの先スライドで頻繁に使うことが想定されるのでLyXで差し込み枠にコマンドを定義しておく。以下の内容を[Document] ▷ [Settings…] ▷ [Local Layout]に記述
    注意: 以下の設定はLyX 2.1.xでないと使えない。また、ヘッダーにFomat 48を書いておくこと。
    Format 48
    
    InsetLayout  Flex:Tikzfancyarrow
    LyXtype  custom
    Labelstring  tikzfancyarrwo
    latextype  command
    LatexName  tikzpicture
    requires  tikzpicture
    decoration  classic
    #passthru  true
      Argument  1
        AutoInsert  1
        LabelString    "Option|n"
        Tooltip        "Option. [fill], [double arrow], [minimum height]: arrow base length, [minimum width]: arrow head length, [rotate]: degree of whole rotation, [shape border rotate]: degree of only arrow rotation, [text width]"
        Mandatory  0
        Decoration     conglomerate
        Font
          Color        blue
        EndFont
      EndArgument
    preamble
      \usepackage{tikz}
      \usetikzlibrary{shapes.arrows}
    endpreamble
    end

0 件のコメント:

コメントを投稿