- 設計
フローチャートの書き方と記号一覧|分岐・繰り返しの例とMermaid
フローチャート(流れ図)とは、処理の手順を、意味の決まった記号と線でつないで表した図です。 記号の形は日本産業規格 JIS X 0121(情報処理用流れ図・プログラム網図・システム資源図記号)で決められていて、この規格に沿って描くと、読む人によって解釈が分かれにくい図になります。
この記事では、JIS X 0121の記号を「名前・形・意味・Mermaidでの書き方」の4列で一覧にし、順次・分岐・多分岐・繰り返し(前判定・後判定)・サブルーチン呼び出しを、Mermaidのコードと同じ処理のPythonコードを並べて説明します。繰り返しは、判断記号で書く方法とループ端記号で書く方法の2通りを比べます。
確認環境:Mermaid 12.1.0(@mermaid-js/mermaid-cli 12.0.0 と Chromium で描画)/Python 3.11.2。掲載したMermaidのコードは、エラーの例を除き、すべて図として出力できることを確認しています。Pythonのコードは実行した出力を載せています。
フローチャートの記号早見表(よく使う8種)
| 名前(JIS X 0121) | 形 | 意味 | Mermaidでの書き方 |
|---|---|---|---|
| 端子 | 両端が丸い長方形 | 開始と終了 | S(["開始"]) |
| 処理 | 長方形 | 計算や代入などの処理 | A["合計 = 単価 × 数量"] |
| 判断 | ひし形 | 条件によって出口を1つ選ぶ | D{"在庫数 >= 注文数"} |
| データ | 平行四辺形 | データの入力と出力 | A[/"点数を入力"/] |
| ループ端 | 上の角(始端)または下の角(終端)を落とした四角形 | 繰り返しの始まりと終わり | L1@{ shape: notch-pent, label: "ループ1" } |
| 定義済み処理 | 左右に縦線が入った長方形 | 別の場所で定義した処理(サブルーチン)の呼び出し | P[["税込み金額を求める"]] |
| 準備 | 六角形 | 初期値の設定など、あとの動作のための準備 | A{{"合計 = 0"}} |
| 線 | 実線(必要なら矢先を付ける) | 処理の流れ | A --> B |
まずは「端子・処理・判断・データ・線」の5つがあれば、ほとんどの手順を描けます。繰り返しとサブルーチンを描くときに、ループ端と定義済み処理を足します。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「フローチャートの書き方と記号一覧|分岐・繰り返しの例とMermaid」
JIS X 0121の記号一覧(全25種)
JIS X 0121:1986 は国際規格 ISO 5807 に対応した規格で、記号をデータ記号・処理記号・線記号・特殊記号の4つに分けています。Mermaidの列は、Mermaid 12.1.0で描画できた書き方です。@{ shape: … } の形の指定は、公式ドキュメントでv11.3.0以降の機能とされています。
データ記号(10種)
| 名前 | 形 | 意味 | Mermaidでの書き方 |
|---|---|---|---|
| データ | 平行四辺形 | 媒体を指定しないデータ | d1[/"データ"/] |
| 記憶データ | 左右の辺が弧になった四角形 | 処理に適した形で記憶されているデータ | d2@{ shape: bow-rect, label: "記憶データ" } |
| 内部記憶 | 左と上に線を1本ずつ足した四角形 | 内部記憶を媒体とするデータ | d3@{ shape: win-pane, label: "内部記憶" } |
| 順次アクセス記憶 | 円の下から横へ線が伸びた形 | 順次アクセスだけが可能なデータ(磁気テープなど) | 専用の形はなし。円 d((" ")) などで代用 |
| 直接アクセス記憶 | 横向きの円柱 | 直接アクセスが可能なデータ(磁気ディスクなど) | d4@{ shape: h-cyl, label: "直接アクセス記憶" } |
| 書類 | 下の辺が波形の四角形 | 人が読める媒体上のデータ(印字出力など) | d5@{ shape: doc, label: "書類" } |
| 手操作入力 | 上の辺が斜めの四角形 | 手で操作して入力するデータ(キーボードなど) | d6@{ shape: sl-rect, label: "手操作入力" } |
| カード | 左上の角を落とした四角形 | カードを媒体とするデータ | d7@{ shape: notch-rect, label: "カード" } |
| せん孔テープ | 上下の辺が波形の四角形 | せん孔テープを媒体とするデータ | d8@{ shape: flag, label: "せん孔テープ" } |
| 表示 | 左がとがり、右が丸い形 | 人が利用する情報を表示する媒体上のデータ(画面など) | d9@{ shape: curv-trap, label: "表示" } |
処理記号(7種)
| 名前 | 形 | 意味 | Mermaidでの書き方 |
|---|---|---|---|
| 処理 | 長方形 | 任意の種類の処理 | p1["処理"] |
| 定義済み処理 | 左右に縦線が入った長方形 | サブルーチンやモジュールなど、別の場所で定義された処理 | p2[["定義済み処理"]] |
| 手作業 | 上の辺が長い台形 | 人手による任意の処理 | p3@{ shape: trap-t, label: "手作業" } |
| 準備 | 六角形 | その後の動作に影響を与える設定(初期値の設定など) | p4{{"準備"}} |
| 判断 | ひし形 | 1つの入口といくつかの出口をもち、条件の評価に従って出口を1つだけ選ぶ | p5{"判断"} |
| 並列処理 | 2本の平行な横線 | 2つ以上の並行した処理を同期させる | p6@{ shape: fork, label: " " }(太い横棒で代用) |
| ループ端 | 上の角を落とした四角形(始端)と、下の角を落とした四角形(終端) | ループの始まりと終わり。2つは同じ名前をもつ | p7@{ shape: notch-pent, label: "ループ端" }(始端の形) |
線記号(4種)
| 名前 | 形 | 意味 | Mermaidでの書き方 |
|---|---|---|---|
| 線 | 実線 | データまたは制御の流れ。向きを明示する必要があるときは矢先を付ける | A --> B(矢先あり)、A --- B(矢先なし) |
| 制御移行 | 途中に矢先を付けた線 | ある処理から別の処理へ制御がすぐに移ること | 専用の線はなし。A -- "制御移行" --> B とラベルで補う |
| 通信 | 稲妻形の線 | 通信線によるデータの転送 | 専用の線はなし。A -- "通信" --> B とラベルで補う |
| 破線 | 破線 | 2つ以上の記号の間の択一的な関係。注釈の対象範囲を囲むのにも使う | A -.- B |
特殊記号(4種)
| 名前 | 形 | 意味 | Mermaidでの書き方 |
|---|---|---|---|
| 結合子 | 小さい円 | 同じ流れ図のほかの部分への出口・入口。対応する結合子には同じ名前を書く | s2(("A")) |
| 端子 | 両端が丸い長方形 | 外部環境への出口・入口。プログラムの流れの開始と終了 | s1(["端子"]) |
| 注釈 | 破線でつないだ、片側が開いた角かっこ | 説明や注を付け加える | s3@{ shape: brace, label: "注釈" } と -.- |
| 省略 | 3つの点 | 記号や記号の集まりを省いたことを示す(線に対してだけ使う) | 専用の形はなし。A -- "…" --> B とラベルで補う |
一覧をまとめて描画するコード
上の表のうち、Mermaidに形があるものをまとめて描くコードです。
flowchart TB
subgraph データ記号
d1[/"データ"/]
d2@{ shape: bow-rect, label: "記憶データ" }
d3@{ shape: win-pane, label: "内部記憶" }
d4@{ shape: h-cyl, label: "直接アクセス記憶" }
d5@{ shape: doc, label: "書類" }
d6@{ shape: sl-rect, label: "手操作入力" }
d7@{ shape: notch-rect, label: "カード" }
d8@{ shape: flag, label: "せん孔テープ" }
d9@{ shape: curv-trap, label: "表示" }
end
subgraph 処理記号
p1["処理"]
p2[["定義済み処理"]]
p3@{ shape: trap-t, label: "手作業" }
p4{{"準備"}}
p5{"判断"}
p6@{ shape: fork, label: " " }
p7@{ shape: notch-pent, label: "ループ端" }
end
subgraph 線記号と特殊記号
s1(["端子"])
s2(("A"))
s3@{ shape: brace, label: "注釈" }
s4["線の例"]
s1 --> s2
s2 --- s4
s4 -.- s3
end
Mermaid 12.1.0のループ端(notch-pent)は上の角を落とした始端の形で、下の角を落とした終端の形は用意されていません。この記事では、始端と終端に同じ形を使い、同じループ名を書いて対応を示す方法をとります。
フローチャートの書き方(5つの手順と基本ルール)
| 手順 | すること |
|---|---|
| 1 | 描く範囲を決める(どこから始まり、どこで終わるか)。端子を2つ置く |
| 2 | 処理を上から順に書き出す。1つの記号には1つの処理を書く |
| 3 | 条件で分かれるところを判断記号にし、出口に Yes/No などのラベルを付ける |
| 4 | 繰り返すところを、判断記号へ戻る線、またはループ端で囲む |
| 5 | まとまった処理を定義済み処理に切り出し、別の流れ図として描く |
| 基本ルール | 理由 |
|---|---|
| 流れは上から下、左から右へ | 読む向きがそろい、矢先がなくても流れを追える |
| 逆向きの流れには必ず矢先を付ける | JIS X 0121でも、向きを明示する必要があるときに矢先を付けるとされている |
| 開始と終了の端子は1つずつ | 入口と出口がはっきりする |
| 判断記号の出口には必ずラベルを付ける | どの条件でどちらへ進むかが図だけでわかる |
| 線はなるべく交差させない | 交差が多いところは結合子や定義済み処理で分ける |
| 記号の中は短く「何をするか」を書く | 細かい説明は注釈に回す |
制御構造ごとの描き方(MermaidとPythonの対応)
プログラムの流れは「順次・分岐・繰り返し」の3つの組み合わせで表せます。それぞれについて、Mermaidのコード、同じ処理のPythonコード、実行結果の順に載せます。
| 制御構造 | 使う記号 | Pythonの構文 |
|---|---|---|
| 順次 | 処理・データを線で縦につなぐ | 文を上から順に書く |
| 分岐 | 判断(出口2つ) | if 〜 else |
| 多分岐 | 判断(出口3つ以上) | if 〜 elif 〜 else、match |
| 前判定の繰り返し | 判断を先に置き、処理から判断へ戻る | while 条件: |
| 後判定の繰り返し | 処理を先に置き、判断から処理へ戻る | while True: と break |
| 回数の決まった繰り返し | ループ端(始端と終端) | for |
| サブルーチン呼び出し | 定義済み処理 | 関数の呼び出し |
順次
flowchart TD
S(["開始"]) --> A[/"単価と数量を入力"/]
A --> B["合計 = 単価 × 数量"]
B --> C[/"合計を表示"/]
C --> E(["終了"])
price = 120 # 単価と数量を入力
quantity = 5
total = price * quantity # 合計 = 単価 × 数量
print(total) # 合計を表示
600
分岐(if 〜 else)
flowchart TD
S(["開始"]) --> A[/"在庫数と注文数を入力"/]
A --> D{"在庫数 >= 注文数"}
D -- Yes --> B["在庫数 = 在庫数 − 注文数"]
B --> C[/"「出荷します」を表示"/]
D -- No --> F[/"「入荷待ちです」を表示"/]
C --> E(["終了"])
F --> E
stock = 8 # 在庫数と注文数を入力
order = 10
if stock >= order: # 在庫数 >= 注文数
stock = stock - order
print("出荷します")
else:
print("入荷待ちです")
入荷待ちです
判断記号から出る線に -- Yes --> のようにラベルを書きます。分かれた流れは、終了の前で1本に合流させます。
多分岐(if 〜 elif 〜 else)
JIS X 0121の判断記号は「いくつかの出口」をもてるので、3つ以上に分かれる場合も1つのひし形から線を出して描けます。
flowchart TD
S(["開始"]) --> A[/"点数を入力"/]
A --> D{"点数"}
D -- "80以上" --> B1["評価 = A"]
D -- "60以上80未満" --> B2["評価 = B"]
D -- "60未満" --> B3["評価 = C"]
B1 --> C[/"評価を表示"/]
B2 --> C
B3 --> C
C --> E(["終了"])
score = 72 # 点数を入力
if score >= 80: # 80以上
grade = "A"
elif score >= 60: # 60以上80未満
grade = "B"
else: # 60未満
grade = "C"
print(grade) # 評価を表示
B
値そのもので分かれる場合は、判断記号の中に調べる対象だけを書き、出口のラベルに値を書きます。Pythonでは match 文(3.10以降)が対応します。
flowchart TD
S(["開始"]) --> A[/"コマンドを入力"/]
A --> D{"コマンド"}
D -- "add" --> B1[/"「追加します」を表示"/]
D -- "list" --> B2[/"「一覧を表示します」を表示"/]
D -- "その他" --> B3[/"「使い方を表示します」を表示"/]
B1 --> E(["終了"])
B2 --> E
B3 --> E
command = "list"
match command: # 値そのもので分かれる多分岐
case "add":
print("追加します")
case "list":
print("一覧を表示します")
case _:
print("使い方を表示します")
一覧を表示します
前判定の繰り返し(while)
先に条件を調べ、成り立つ間だけ処理を繰り返します。 最初から条件が成り立たなければ、処理は1回も実行されません。
flowchart TD
S(["開始"]) --> A["在庫数 = 3"]
A --> D{"在庫数 < 10"}
D -- Yes --> B["在庫数 = 在庫数 + 4"]
B --> D
D -- No --> C[/"在庫数を表示"/]
C --> E(["終了"])
stock = 3
while stock < 10: # 先に条件を調べる(前判定)
stock = stock + 4
print(stock)
11
在庫数は 3 → 7 → 11 と変わり、11になったところで条件(10未満)が成り立たなくなって繰り返しを抜けます。
後判定の繰り返し
先に処理を1回実行し、そのあとで条件を調べます。 処理は必ず1回は実行されます。入力のやり直しのように「まず1回やってみる」処理に向いています。Pythonには後判定専用の構文がないため、while True: と break で書きます。
flowchart TD
S(["開始"]) --> A[/"数量を入力"/]
A --> D{"数量 >= 1"}
D -- No --> A
D -- Yes --> C[/"数量を表示"/]
C --> E(["終了"])
inputs = iter([0, -2, 3]) # 入力される値(1回目、2回目、3回目)
while True:
quantity = next(inputs) # 先に1回実行する
print("入力:", quantity)
if quantity >= 1: # あとで条件を調べる(後判定)
break
print("数量:", quantity)
入力: 0
入力: -2
入力: 3
数量: 3
前判定と後判定の見分け方
| 観点 | 前判定 | 後判定 |
|---|---|---|
| 判断記号の位置 | 繰り返す処理の前 | 繰り返す処理の後 |
| 戻る線 | 処理から判断へ戻る | 判断から処理へ戻る |
| 処理の最小実行回数 | 0回 | 1回 |
| Pythonでの書き方 | while 条件: |
while True: の最後で if 条件: break |
繰り返しの2通りの書き方(判断記号とループ端記号)
「1から5までの合計を求める」という同じ処理を、2通りで描きます。Pythonのコードはどちらも同じです。
total = 0
for i in range(1, 6): # i = 1, 2, …, 5
total = total + i
print(total)
15
判断記号で書く
flowchart TD
S(["開始"]) --> A{{"合計 = 0、i = 1"}}
A --> D{"i <= 5"}
D -- Yes --> B["合計 = 合計 + i"]
B --> I["i = i + 1"]
I --> D
D -- No --> C[/"合計を表示"/]
C --> E(["終了"])
初期化(i = 1)、条件(i <= 5)、増分(i = i + 1)がそれぞれ別の記号になり、戻る線が1本入ります。流れを1歩ずつ追えるので、繰り返しの仕組みを説明するときに向いています。
ループ端記号で書く
flowchart TD
S(["開始"]) --> A{{"合計 = 0"}}
A --> L1@{ shape: notch-pent, label: "ループ1<br>i = 1, 2, …, 5" }
L1 --> B["合計 = 合計 + i"]
B --> L2@{ shape: notch-pent, label: "ループ1" }
L2 --> C[/"合計を表示"/]
C --> E(["終了"])
始端と終端に同じ名前(ループ1)を書き、始端に「i = 1, 2, …, 5」と繰り返しの条件をまとめます。戻る線がなくなり、上から下への一本道になるので、繰り返しが入れ子になっても線が交差しません。
どちらを使うか
| 観点 | 判断記号で書く | ループ端記号で書く |
|---|---|---|
| 記号の数(この例) | 7個 | 7個 |
| 戻る線 | あり | なし |
| 条件を書く場所 | ひし形の中 | 始端または終端の中 |
| 前判定・後判定の表し方 | ひし形の位置で表す | 条件を始端に書けば前判定、終端に書けば後判定 |
| 向いている場面 | 流れを1歩ずつ説明したい、後判定を目立たせたい | 繰り返しが多い・入れ子になる、for に対応させたい |
1つの図の中では、どちらかに統一すると読みやすくなります。
サブルーチン呼び出し(定義済み処理)
まとまった処理は定義済み処理の記号(左右に縦線が入った長方形)に置きかえ、中身は別の流れ図として描きます。Pythonでは関数の定義と呼び出しに対応します。
flowchart TD
subgraph main["主処理"]
S(["開始"]) --> A[/"金額のリストを入力"/]
A --> L1@{ shape: notch-pent, label: "ループ1<br>金額を1件ずつ取り出す" }
L1 --> P[["税込み金額を求める"]]
P --> O[/"税込み金額を表示"/]
O --> L2@{ shape: notch-pent, label: "ループ1" }
L2 --> E(["終了"])
end
subgraph sub["税込み金額を求める"]
S2(["開始(金額)"]) --> D{"金額 >= 0"}
D -- Yes --> B["税込み = 金額 × 1.1 を四捨五入"]
D -- No --> B2["税込み = 0"]
B --> E2(["戻る(税込み)"])
B2 --> E2
end
from decimal import Decimal, ROUND_HALF_UP
def with_tax(amount): # 定義済み処理「税込み金額を求める」
if amount >= 0:
return int((Decimal(amount) * Decimal("1.1")).quantize(Decimal("1"), rounding=ROUND_HALF_UP))
return 0
amounts = [1000, 255, -50] # 金額のリストを入力
for amount in amounts: # ループ1:金額を1件ずつ取り出す
print(with_tax(amount)) # 税込み金額を表示
1100
281
0
- 主処理の側は「税込み金額を求める」という名前だけを書き、計算の中身には触れません。
- 呼び出される側は、端子に「開始(受け取る値)」「戻る(返す値)」を書くと、関数の引数と戻り値に対応します。
- 定義済み処理の名前と、呼び出される側の流れ図の名前を同じにしておくと、対応を取り違えません。
Mermaidでエラーになる例と直し方
Mermaidのflowchartでは、小文字の end が subgraph を閉じる予約語です。ノードの名前に使うと次のエラーになります。
flowchart TD
S(["開始"]) --> A["合計 = 単価 × 数量 (税抜き)"]
A --> end
Error: Parse error on line 3:
...量 (税抜き)"] A --> end
----------------------^
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'end'
この記事のほかのコードのように、E(["終了"]) と別の名前(E)を付けて表示名を引用符の中に書けば描画できます。かっこや記号を含む表示名も、引用符で囲んでおくとそのまま表示されます。
読みやすいフローチャートにするチェックリスト
| 確認すること | 見るところ |
|---|---|
| 開始と終了の端子が1つずつあるか | 終了が複数あるときは合流させる |
| すべての記号が、開始から線をたどって届くか | 孤立した記号がないか |
| 判断記号のすべての出口にラベルがあるか | Yes/No、または値 |
| 判断記号の出口は条件を漏れなく覆っているか | 「80以上」「60以上80未満」「60未満」のように境目を確かめる |
| 繰り返しに、終わる条件があるか | 条件に使う値が繰り返しの中で変わっているか |
| ループ端の始端と終端に同じ名前があるか | 入れ子のときは「ループ1」「ループ2」と分ける |
| 入出力がデータ記号、計算が処理記号になっているか | 記号の使い分け |
| 1つの図が1ページに収まっているか | 長いときは定義済み処理や結合子で分ける |
よくある質問
Q. JIS X 0121の記号をすべて覚える必要はありますか? A. 手順を表す流れ図なら、端子・処理・判断・データ・線の5つに、ループ端と定義済み処理を足した7つでほとんど描けます。磁気テープやカードなどの媒体を表す記号は、システム全体のデータの流れを表す図で使うもので、必要になったときに一覧表を見れば足ります。
Q. 繰り返しは、判断記号とループ端記号のどちらで描くのがよいですか? A. どちらもJIS X 0121にある記号で、同じ処理を表せます。流れを1歩ずつ追わせたいときは判断記号、繰り返しが多く線の交差を減らしたいときはループ端記号が向いています。1つの図の中では統一してください。
Q. 入力と出力は、どの記号で描きますか? A. 媒体を決めないときは平行四辺形の「データ」を使います。キーボードからの入力であることを示したいときは「手操作入力」、画面への出力は「表示」、印刷物は「書類」と、媒体に合わせた記号に置きかえられます。
Q. 判断記号の出口は2つまでですか? A. 規格上は「いくつかの択一的な出口」をもてるので、3つ以上でも描けます。出口が多くて読みにくいときは、判断記号を2段に分けるか、値と行き先の対応を表にまとめて注釈で添えます。
まとめ
- フローチャートの記号は JIS X 0121(ISO 5807 に対応)で決められており、データ記号10・処理記号7・線記号4・特殊記号4の計25種があります。
- よく使うのは端子・処理・判断・データ・線の5つ。繰り返しにループ端、サブルーチンに定義済み処理を足します。
- 流れは上から下、左から右。逆向きの線には矢先を付け、判断記号の出口には必ずラベルを書きます。
- 前判定は判断が処理の前(最小0回)、後判定は判断が処理の後(最小1回)。ひし形の位置と戻る線の行き先で見分けます。
- 繰り返しは判断記号でもループ端記号でも描けます。 戻る線をなくしたいときはループ端、1歩ずつ説明したいときは判断記号を選びます。
- Mermaidでは
@{ shape: … }でJISの記号に近い形を指定でき、ループ端はnotch-pent、定義済み処理は[[ ]]で書けます。
参考・出典
- JIS X 0121:1986「情報処理用流れ図・プログラム網図・システム資源図記号」(記号の名称と意味。閲覧に使用したページ): https://kikakurui.com/x0/X0121-1986-01.html
- Mermaid「Flowcharts Syntax」(ノードの形、
@{ shape: … }の一覧、v11.3.0以降): https://mermaid.js.org/syntax/flowchart.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「フローチャートの書き方と記号一覧|分岐・繰り返しの例とMermaid」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。