blockdiag（edge_layout=flowchart）に言うことを聞かせる

**概要**
blockdiagでフローチャートを描こうとするも、コレジャナイ出力が得られることが少なくない。
いろいろ使ってみる中で解決できた・できなかった事例について、記録を残していく。

## ちょっとの修正で直せたもの
### if分岐が横から出ない

#### 状況
`edge_layout=flowchart`を設定しているにも関わらず、if分岐がひし形の下から出てしまう。
![break.png](https://qiita-image-store.s3.amazonaws.com/0/147798/6d705037-91e4-7ee8-861a-1ee718f1926b.png)

#### 回避策
ダミーのノード`d`を`b0`と横並びさせる。
これは、横から分岐を出すには2つのノードが横並びになっている必要があるため。
ダミーノードは`shape=none`を使うのが無難。クラス化しておくと使いやすい。
ダミーノードには矢印が付いて欲しくないので、分岐側のエッジは`dir=none`として頭を消しておく。

```:break_1.diag
blockdiag{
	orientation = portrait;
	edge_layout = flowchart;

    bp [shape=beginpoint];
    lin [shape=flowchart.loopin];
	c [shape=flowchart.condition];
	b0 [shape=box];
    lout [shape=flowchart.loopout];
	ep [shape=endpoint];

    class dummy [shape=none];
    d [class=dummy];

    // main
	bp -> lin -> c -> b0 -> lout -> ep;

    // break
	c -> d -> ep [dir=none];
}
```
![break_1.png](https://qiita-image-store.s3.amazonaws.com/0/147798/35223d5e-f51c-c7b8-6cf8-fdfe2aaeb44c.png)


### if分岐の左右が思い通りにならない
#### 状況 
ifの「そっちじゃない方（`b0`）」が下に分岐し、とっても不格好になる。
ループを巻き込んじゃったりすると左右にずれてしまい、もう目も当てられない事態になる。

![if.png](https://qiita-image-store.s3.amazonaws.com/0/147798/4a1a27d9-78bc-b244-b768-ce8b917c672b.png)

#### 回避策
なんと、分岐の左右はノードを定義した順序に依存している模様。
というわけで、「分岐の真下に配置したいノード（`b1`）」を分岐（`c`）の直後に定義する。
こういうの、ちゃんとコードを読み漁って情報を集めたほうが良いかもしれない。

![if_1.png](https://qiita-image-store.s3.amazonaws.com/0/147798/c92f3f5f-a918-5f1e-0947-cdf2cf2a69c5.png)

```:if_1.diag
blockdiag{
	orientation = portrait;
	edge_layout = flowchart;

    bp [shape=beginpoint];
    lin [shape=flowchart.loopin];
	c [shape=flowchart.condition];

    // b1 -> b0
	b1 [shape=box];
	b0 [shape=box];

	lout [shape=flowchart.loopout];
	ep [shape=endpoint];

	bp -> lin -> c -> b1 -> lout -> ep;
	c -> b0 -> ep;
}
```

### めっちゃ横に膨らむ
#### 状況

分岐の仕方や数によってはフローチャートが横に膨らんでいく場合がある。
スライドの端にちょこっと載せるとか、縦長が嬉しい場合にちょっと直したくなる。
以下の終端が複数あるフローチャートを題材にしてみる。
![end2.png](https://qiita-image-store.s3.amazonaws.com/0/147798/719ede66-30ec-e64e-9054-39b57eb28a7e.png)

#### 回避策1：下に回り込ませる
1つめの終端(`hoge`)から、2つめの終端への分岐の開始点（`b1`）に見えないエッジ（`style=none`）を引いてあげる。
この2ノードが縦に揃えられることで、レイアウトが変わる。

![end2_1.png](https://qiita-image-store.s3.amazonaws.com/0/147798/99eb0992-4a49-90e6-f1ee-656216ddbb93.png)

```:end2_1:diag
blockdiag{
	orientation = portrait;
	edge_layout = flowchart;

    bp [shape=beginpoint];
    lin [shape=flowchart.loopin];
	c [shape=flowchart.condition];
	b0 [shape=box];
	b1 [shape=box];
    lout [shape=flowchart.loopout];
	ep0 [shape=endpoint, label="hoge"];
	ep1 [shape=endpoint, label="fuga"];

    // dummy
    class dummy [shape=none];
    d [class=dummy];

    // main
	bp -> lin -> c -> b0 -> lout -> ep0;

    // break
	c -> d [dir=none];
    d -> b1 -> ep1;

	// invisible edge
	ep0 -> b1 [style=none];
}
```

#### 回避策2：回り道を縮める

上図だが、回り道の矢印が膨らんでいてあまりダイエットできていない。
この「回り具合」は`span_width`及び`node_width`依存なので、これらを小さく設定する。
ただし、`node_width`を縮めてノードまで細くなっては意味ないので、
ノードのサイズ設定に関しては`class`を定義してそちらにまとめて書いてやると良い。

![end2_2.png](https://qiita-image-store.s3.amazonaws.com/0/147798/270a04e2-ef9f-f116-5270-11cf52b18c4d.png)


```:end2_2.diag
blockdiag{
	orientation = portrait;
	edge_layout = flowchart;

	node_width = 20;
	span_width = 20;

	class box [shape=box, width=128];
	class if [shape=flowchart.condition, width=128];
	class lin [shape=flowchart.loopin, width=128];
	class lout [shape=flowchart.loopout, width=128];

    bp [shape=beginpoint];
    lin [class=lin];
	c [class=if];
	b0 [class=box];
	b1 [class=box];
    lout [class=lin];
	ep0 [shape=endpoint, label="hoge"];
	ep1 [shape=endpoint, label="fuga"];

    class dummy [shape=none];
    d [class=dummy, width=10];

    // main
	bp -> lin -> c -> b0 -> lout -> ep0;

    // break
	c -> d [dir=none];
    d -> b1 -> ep1;

	// invisible edge
	ep0 -> b1 [style=none];
}
```
`class`定義より上は「おまじない」として使いまわすのが望ましいかもしれない。
`bp`と`ep`のラベルが潰れているが、これも適切な`width`を設定すれば直せる。


## どうにもならなさそうなもの
### 戻りの矢印が引けない
基本的に下から上（左から右）のノードに矢印を引くことが想定されていない模様。
そもそも戻り矢印なんか使わない努力をするべきかも。

- ループは`flowchart.loopin(loopout)`を使って書く
- 折り返し（`folded`）は使わず、`terminator`などをつかって2つ以上に区切る

### 左から回り込めない
もし出来る方法があったらマジで教えてほしい。
ただ、実際やるとなるとマッピングの難易度的な意味で開発者への負荷が爆上がりしそう。

### 文字数制限がキツい
特に`flowchart.condition`などがそうだが、文字数制限がキツい。
また、エッジのラベルも同様（TとかFくらいしか書かないけど）。
横長いノードが嫌なら、`height`を増やしてテキストを改行するのが無難か。
改行は`label="1行目\n2行目"`のように書くと普通にできる。

## まとめ

上手に使いこなせていないのでつらい。