Open5

railsでデータ構造を適切に設定してmermaidを使ったフローチャートを表示する

replicareplica

OKITELというサービスで声優さんに録音してもらう際にその音声がどの段階で再生されるかをフローチャートで表示したかった。

replicareplica

まずbin/importmap pin mermaidでmermaid.jsのパッケージをrailsに追加する。
次にjavascriptでimport mermaid from 'mermaid'

replicareplica

yamlでデータ構造を作る

app/models/data/voice_flows.yml
-
  nodes:
    - morning_greeting: おはようございます。〇〇です。(朝架電時の冒頭の挨拶)
    - today_is: 今日は(日付の確認)
    - month: ◯月(日付)
    - day: ◯日(日付)
    - holiday: ◯◯の日(祝日名)
    - week: ◯曜日(曜日名)
    - end_of_sentence: です。(語尾)
  edges:
    - [morning_greeting, today_is]
    - [today_is, month]
    - [month, day]
    - [day, holiday, 祝日]
    - [day, week, 祝日以外]
    - [holiday, end_of_sentence]
    - [week, end_of_sentence]
-
  nodes:
    - did_sleep_well: 今日はよく眠れましたか?(睡眠確認の挨拶)
    - ask_sleep_score: 睡眠スコアをプッシュ入力してください。(睡眠スコアの確認)
    - beep: ピピ!(返事開始の合図)
    - user_reply: ユーザーの返答
    - reply_sleep_score_: 睡眠スコアに応じた返答
    - retry_ask_sleep_score: よく眠れなかったときは1、よく眠れたときは5と、プッシュ入力してください。もう一度(睡眠スコアの再確認)
  edges:
    - [did_sleep_well, ask_sleep_score]
    - [ask_sleep_score, beep]
    - [beep, user_reply]
    - [user_reply, reply_sleep_score_, 成功]
    - [user_reply, retry_ask_sleep_score, 失敗]
    - [retry_ask_sleep_score, beep]

こういう配列ができる

[
{"nodes"=>{"morning_greeting"=>"おはようございます。〇〇です。(朝架電時の冒頭の挨拶)", "today_is"=>"今日は(日付の確認)", "month"=>"◯月(日付)", "day"=>"◯日(日付)", "holiday"=>"◯◯の日(祝日名)", "week"=>"◯曜日(曜日名)", "end_of_sentence"=>"です。(語尾)"}, 
"edges"=>[["morning_greeting", "today_is"], ["today_is", "month"], ["month", "day"], ["day", "holiday", "祝日"], ["day", "week", "祝日以外"], ["holiday", "end_of_sentence"], ["week", "end_of_sentence"]]},
{"nodes"=>{"did_sleep_well"=>"今日はよく眠れましたか?(睡眠確認の挨拶)", "ask_sleep_score"=>"睡眠スコアをプッシュ入力してください。(睡眠スコアの確認)", "beep"=>"ピピ!(返事開始の合図)", "user_reply"=>"ユーザーの返答", "reply_sleep_score_"=>"睡眠スコアに応じた返答", "retry_ask_sleep_score"=>"よく眠れなかったときは1、よく眠れたときは5と、プッシュ入力してください。もう一度(睡眠スコアの再確認)"}, 
"edges"=>[["did_sleep_well", "ask_sleep_score"], ["ask_sleep_score", "beep"], ["beep", "user_reply"], ["user_reply", "reply_sleep_score_", "成功"], ["user_reply", "retry_ask_sleep_score", "失敗"], ["retry_ask_sleep_score", "beep"]]}
]
replicareplica

helperに関数を定義

app/helpers/mermaid.rb
module MermaidHelper
  def voice_flow_chart(kind)
    flow_list = YAML.load_file('app/models/data/voice_flows.yml')
    flow = flow_list.find { |flow| flow['nodes'].keys.include?(kind) }

    return if flow.blank?

    nodes_str = flow['nodes'].map do |key, label|
      "#{key}(\"#{label}\")"
    end.join("\n") #ノードの表示
    edges_str = flow['edges'].map do |edge|
      "#{edge[0]} #{edge[2] && "--\"#{edge[2]}\""}--> #{edge[1]}"
    end.join("\n") # 矢印の表示
    html = <<-EOS
    <pre class='mermaid'>
      graph TD
      #{nodes_str}
      #{edges_str}
      style #{kind} fill:#b0c4de #対象のkindのノードの色だけ変える
    </pre>
    EOS
    html.html_safe
  end
#{edge[2] && "--\"#{edge[2]}\""}

edge

[day, holiday, 祝日]

の時に矢印上に「祝日」という文字を表示させるコード

replicareplica

最後にactors/voice/edit.htmlでフローチャートを表示したい場所に

= voice_flow_chart(@voice.kind)

を書いたら表示できる