Google Meetでコメントをニコニコ動画っぽく流すGoogle Chrome Extensionを改造してみた
はじめに
昨今、リモートワークが増えweb会議をする方が増えているかと思います。
かくいう私も同様にCovid-19の影響で2月頃からほぼ自宅リモート業務を進めています。
弊社のめちゃめちゃ早かった対応をまとめたブログはこちら↓
Google Meetを使い始めたとき、単純に
「コメント見づらぃ、つらぃ」
と思っていました。
そんなとき見つけたのがこのTweetです。
Google Meetのチャットを某サイト風に流す拡張機能を公開しました。https://t.co/o8l39Crmgr pic.twitter.com/zsZpAproxj
— ろぬ (@Yeq6N) May 29, 2020
見つけたときは「これだ!!」と思い、Githubのリポジトリ*1を探し出し、早速コードを拝見しました。
謝辞
大本のChrome Extensionを考案&作成していただいた、ろぬ (@Yeq6N)様*2。
素晴らしいアイディアと該当リポジトリを公開いただきありがとうございます。
この場をお借りしてお礼申し上げます。
作ったもの
NicoNicoStyle4MeetChromeExtension*3
動作イメージ
環境への追加方法
- NicoNicoStyle4MeetChromeExtensionへアクセス
CODE
ボタンからDownload ZIP
し、任意の場所にZIPファイルを解凍し該当ファイルを取得する- Chromeで拡張機能ページにアクセス
- デベロッパーモードを有効化し、
パッケージ化されていない拡張機能を読み込む
で、解凍したフォルダを指定する - ツールバーにあるアイコンから
Activate
を有効化する
追加した機能
- browser_action(拡張機能のアイコンをクリックしたら出てくるやつ)上で、コメントが流れるかどうかを切り替え機能を追加
- デフォルトを含めた7色を指定してコメントを流せるようなタグを作成 & 適応
- Small, Default, Largeの3パターンの文字サイズを指定するタグを作成 & 適応
システム構成
- 主要動作をするcontent_script(上図のscript.js)は、@ろぬ様のNicoStyleMeetの処理をほぼ踏襲
- content_scriptでは、Webページに紐づくlocalStorageに対して、この拡張機能が有効かどうかのフラグを格納
- browser_action(上図のsetting.js)はpopup.htmlのlocalStrageに対して、拡張機能の有効化フラグの状態を格納
- popupを開いた際に、switchの状態を反映させておくため
- browser_actionのpopup.htmlではBootstrapを利用して有効化フラグの変更switchや、タグを挿入するボタンを追加
- setting.jsからscript.jsに有効化フラグや選択されたタグの情報を送信
ディレクトリ構成
NicoNicoStyle4MeetChromeExtension/ ├ image/ # アイコンなどの画像ファイル | ├ icon16.png # 16x16 | ├ icon48.png # 28x48 | └ icon128.png # 128x128 ├ script/ | ├ bootstrap.js # Bootstrapのアコーディオンを使うためのjs | ├ const.js # クラス名の定数などを格納するjs | ├ jquery.min.js # jQueryを使うためのmin.js | ├ script.js # 実際に画面上にコメントを流す等の処理をするcontents_script | └ setting.js # ポップアップ(browser_action)での処理を実行するjs ├ style/ | ├ bootstrap.css # Bootstrapを使うためのスタイルシート | └ style.css # コメントの色などを設定するスタイルシート ├ manifest.json # Chrome Extensionでいちばん大事なやつ └ popup.html # ポップアップ(browser_action)で表示するHTML
開発中のあれこれ
本当はやりたかったこと
本当は図のようにFirebaseのようなMbaaSと連携し、メッセージ内にタグを入れずにExtension内で設定情報とメッセージを一つのpayloadとして登録&Extension内で変更検知し、表示する。
というようなことをしたかったのですが、
- meetってそういえばいろいろな人が使ってる
- メッセージ内にクレデンシャル色の強い情報多い
- そもそもメッセージの内容を外のDBに一時的にでも保存するのって怖い
- Extensionでセキュリティを担保するのツライ
結局
メッセージ内にタグを埋め込んで、外部サービスを介さないように方針転換
工夫したこと
- const.jsを定義
- setting.jsからscript.jsへのデータ送信
chrome.tabs.sendMessage
でsetting.jsからscript.jsにデータを送ることができる- データを受け取る際、
chrome.runtime.onMessage.addListener
のコールバック関数内でのみ取得可能 - 送信するデータをObject型にしkeyの存在判定により、下記の処理をそれぞれ分けている(sample02参照)
- 有効化フラグの変更・保存処理
- 文字色変更タグ付与
- 文字サイズ変更タグ付与
sample01
{ "manifest_version": 2, ~~~~~~~ "content_scripts": [ { "js": [ "./script/jquery.min.js", "./script/const.js", "./script/script.js" ], "css": ["./style/style.css"], "matches": ["https://meet.google.com/*"], "run_at": "document_start" } ], ~~~~~~~ }
sample02
payload
payload: { 'active': true, 'color': 'red', 'size': 'l' }
sample02
データ取得部
chrome.runtime.onMessage.addListener(function(request) { const keys = Object.keys(request) if (keys.includes('active')) { setActivateState(request.active) } if (keys.includes('color')) { setColorTag(request.color) } if (keys.includes('size')) { const size = request.size === 'large' ? 'l' : 's' setSizeTag(size) } })
課題点
- Github Issues
- コメント入力フォームが展開されている状態じゃないとコメントが流れない
- 単純に重い
- セキュリティ問題解決できて、開発に時間割けるなら、リアルタイムDBとか使ってタグ自体がコメントスレッドに残らないようにしたい
本当に一言だけのご連絡
まずはじめに
皆様、長らく更新せず、ほんっっっっっっとうにごめんなさい。
色々忙しく動き回っていたため、執筆できていませんでした…。
今後
現在ある程度落ち着いてきたので、何かネタを見つけ次第、再開していこうと思います。
2020年最初にGoogleSpreadSheet(GSS)のあれこれをまとめてみる
はじめに
皆さん、あけましておめでとうございます。
本年も頑張っていろいろ書いていきますので、よろしくおねがいします。
では早速本編をどうぞ
いつもの
※ JC: 鬼滅の刃(吾峠呼世晴) 9巻 p59〜p62 より、雑コラを作成させていただきました。
まず用語集
名称(和) | 名称(英) | 説明 |
---|---|---|
ワークブック | WorkBook | Googleドライブに保存される1ファイル |
スプレッドシート GoogleSpreadSheet |
SpreadSheet | 行と列による表計算が可能な機能 |
タブ | Tab | ワークブックに対して複数のスプレッドシートを管理する際に用いる機能 |
セル | Cell | スプレッドシート上にある1つの入力枠 |
ファンクション | Function | セル上で実行可能なプログラム |
アドオン | AddOn | GSSで追加可能な拡張機能 |
スクリプト GoogleAppScript(GAS) |
Script | GSS上で実行可能なJavaScript likeな言語 |
GSSの制限について
参考: Sheets Tips - Google Sheets Tips and Tricks | G Suite Tips
対象 | 範囲 | 条件 |
---|---|---|
作成・編集可能なセル数 | 1Spreadsheetあたり | 500万セル |
一度の編集(コピペ)可能な行数 | 1Spreadsheetあたり | 40,000行 |
最大作成列数 | 1Spreadsheetあたり | 18,278列 |
最大タブ数 | 1WorkBookあたり | 200タブ |
GOOGLEFINANCE Function | 1Spreadsheetあたり | 1,000セル |
IMPORTRANGE Function | ワークブック間の1Functionあたり | 50セル |
IMPORTDATA IMPORTHTML IMPORTFEED IMPORTXML |
1Spreadsheetあたり | 50セル |
文字列数 | 1セルあたり | 50,000文字 |
リスト作成
1. ヘッダーを決めよう
リストにおいてヘッダーはとても重要!
どんな情報を見せてどんな情報を見せないかを決める!!
2. Index番号を振ろう
普通に番号を一つづつ入れていってもいいけど、
コピペしたり、削除したときに間が飛んでしまったりするので、
ARRAYFORMULA関数とROW関数を使って連番を勝手に振るようにする。
【A3】Index番号
=ARRAYFORMULA( IFS( ROW(A3:A)=3, "#", B3:B="", "", ROW(B3:B) > 3, ROW(A3:A)-3 ) )
3. データを取得してみよう
参考: SpreadSheetでスクレイピング。Importxml他、便利な関数9+1 - Qiita
上記記事をいろいろ参考にそれぞれの情報を取得していきましょう!!
①対象のURLを列挙(今回はQiitaのAdventCalendarを使っています。)してリストを作成
※ リスト作成のためにリストを作成とは…
【J1J】: 年数
【K1:K】: URL
【J1】:どうせなら年数はURLから正規表現で取得してみる
=VALUE( REGEXEXTRACT( K1, "[0-9]{4}" ) )
コメント:
後々使うことを考えて、正規表現で取得した文字列はVALUE関数を使って数値に変換しておく
②対象のタイトルを取得しよう
【I1:I】タイトル
【I1】のとき
=IMPORTXML( K1, "//*[@class='adventCalendarJumbotron_heading']" )
コメント:
XPATHはChromeの開発者ツールを使えば簡単に取得(コピー)できます。
が
"
が入ったり、Body要素から参照したりして無駄が多いので、取得したい要素にClassやIDが入っている場合は上記のように直接参照したほうが楽でしょう。
③セレクトボックスを設定しよう
セレクトボックスに指定したいところで、右クリック→[データの入力規則]→条件: リストを範囲で指定
を選択し、上記で取得したタイトルを指定
無効なデータの場合:入力を拒否
↑にしておくと、後々使う関数でわざわざIFERRORを入れなくて良いので指定しておくと良いでしょう。
④日付を生成しよう
AdventCalendarは毎年12月のブログのお祭りなので、基本的にYY年12月dd日
となります。
今回はセレクトボックスで選択された対象から年のデータを取ってきます
【B4】
=ARRAYFORMULA( IF( C4:C="", "", TEXT( DATE( VLOOKUP($B$2,I:J, 2,False), 12, ROW(B4:B)-3 ), "YY年MM月dd日" ) ) )
コメント:
Cの列に文字が入っていなかった場合は空にする。
※C列はARRAYFORMULAでデータを入れて、該当しないセルには""
を入れるので、ISBLANKが使えない
文字列がある場合、年、月、日の情報をDATE関数を用いて日付型のデータを作成する。
セレクトボックスで選ばれたタイトルをもとにJ列の年の値をVLOOKUP関数を使って取得する。
月の値は12で固定する。
日の値はROW関数を用いて取得する。
⑤作者情報を取得する(Icon編)
【C4】
=ARRAYFORMULA( IMAGE( IMPORTXML( VLOOKUP($B$2, I:K, 3,FALSE), "//*[@class='adventCalendarCalendar_authorIcon']/@src" ) ) )
コメント:
VLOOKUP関数を用いて、選択されたタイトルから対象のURLを取得する。
IMPORTXML関数を用いて対象のimgタグのsrc
要素を取得する。
※要素内のデータを参照する場合は@src
のように指定する。
IMAGE関数を使ってURLから画像を表示する。
※IMAGE関数は非配列関数なのでARRAYFORMULA関数を使って配列関数の振る舞いを再現する。
⑥作者情報を取得する(ユーザ名編)
【D4】
=IMPORTXML( VLOOKUP($B$2, I:K, 3,FALSE), "//*[@class='adventCalendarCalendar_authorIcon']/@alt" )
コメント:
残念ながら、表示されているユーザ名は下記のとおり、Imgタグと一緒に入ってしまっているので、そのまま取得すると不要なデータが入ってしまうため、今回はimg要素のaltを取得しています。
<a href="/Z-me"> <img alt="Z-me" class="adventCalendarCalendar_authorIcon" src="https://qiita-user-profile-images.imgix.net/{{略}}" width="18" height="18" /> Z-me </a>
⑦記事のリンクを取得する
【F4】
=IMPORTXML( VLOOKUP($B$2, I:K, 3,FALSE), "//*[@class='adventCalendarCalendar_comment']/a/@href" )
⑧記事のタイトルを取得する
【E4】
=ARRAYFORMULA( IF( ISBLANK(F4:F), "", HYPERLINK(F4:F, IMPORTXML( VLOOKUP($B$2, I:K, 3,FALSE), "//*[@class='adventCalendarCalendar_comment']" ) ) ) )
コメント:
例によって、対象の文字列を取得する。
先程取得したリンクを使って、HYPERLINK関数により、文字列にリンクを埋め込む。
HYPERLINK関数も非配列関数なので、ARRAYFORMULA関数を使って配列関数の振る舞いを再現する。
4. チェックボックスを入れてみよう
これはとても簡単!
5. 自動表示させてみよう
① チェックされたらタイトルのリンクを削除させてみる
【E4】
=ARRAYFORMULA( IFS( ISBLANK(F4:F), "", G4:G, IMPORTXML(VLOOKUP($B$2, I:K, 3,FALSE),"//*[@class='adventCalendarCalendar_comment']"), NOT(G4:G), HYPERLINK(F4:F, IMPORTXML(VLOOKUP($B$2, I:K, 3,FALSE), "//*[@class='adventCalendarCalendar_comment']")) ) )
コメント:
チェックボックスはBoolean値をそのまま格納しているので G4:G
のように指定するだけで、IF文の判定に使える。
②チェックされたら書式が変わるようにしてみる
該当の範囲を選択し、[書式ルール]から[カスタム数式]を選択し、チェックボックスの範囲を選択する。
※ このときGの前に$
をつけないと、指定された一番左の列しか書式が反映されないので注意
あとはチェックされたときになってほしい書式を設定
6. 表示をきれいにしてみよう
①表示しなくてもいい列を非表示にする
②交互の背景を設定する
リスト全体を選択し、[表示形式]から[交互の背景色]を選択
好きな感じのフォーマットを選んだり、自分で色を選んで見る
③行固定する
固定したい行まで移動し、ツールバーの[表示]を選択、[固定]を選択し、[現在の行まで固定]を選択
番外編. ミニグラフをセルに表示してみよう
いいね数の時間推移グラフを表示してみる
※Qiita記事以外はいいねがないので今回は非表示
①いいね数を取得します。
【H4:H】
【H4】のとき
=IF( F4:F="","", IFERROR( IMPORTXML( F4, "//*[@class='it-Footer_likeCount']" ), "" ) )
コメント:
IMPORTXMLはARRAYFORMULA関数が使えないので、残念ながらそれぞれのセルにコピペする
②SPARKLINE関数を使ってセル内に結果を出力
=SPARKLINE( H4:H, { "charttype","line"; "color","deepskyblue"; "empty","ignore"; "linewidth",5 } )
- "charttype","line"
- グラフの種類をLineChartに指定
- "color","deepskyblue"
- 色をdeepskyblueに指定
- "empty","ignore"
- 空のセルは無視する
- "linewidth",5
- 先の太さを指定
サンプル
グラフ作成
沢山の種類のグラフがあるので、サンプル中心に紹介します。
時系列データサンプル
日付 | 値 |
---|---|
12/01 | 59 |
12/02 | 54 |
︙ | ︙ |
12/10 | 98 |
※ 以下のサンプルグラフはランダム生成されたデータを利用しています(一部を除く)
Line Chart
直線
曲線
Area Chart
Staircase Chart
Bar Chart
Time Scale Chart
カテゴリ別データ
カテゴリ | 値 |
---|---|
知識 | 4 |
度胸 | 5 |
器用さ | 4 |
優しさ | 5 |
魅力 | 5 |
Pie Chart
Donuts Chart
Rader Chart
Horizontal Bar Chart
その他変わり種
Map Chart
国名 | 人口 |
---|---|
中国 | 1,411,415 |
インド | 1,324,171 |
アメリカ | 322,180 |
インドネシア | 261,115 |
ブラジル | 207,653 |
日本 | 127,749 |
︙ | ︙ |
組織図
項目 | 親項目 | ツールチップ |
---|---|---|
必須 | 生きていくには必要 | |
朝食 | 必須 | しっかり食べよう |
昼食 | 必須 | しっかり食べよう |
夕食 | 必須 | 遅くならないうちに食べよう |
シリアル | 朝食 | |
ヨーグルト | 朝食 | |
コンビニ弁当 | 夕食 | 脂っこいものは気をつけろ |
おにぎり | 昼食 |
データ集計
1. 関数を使って複雑な計算をしよう
①データ(範囲)から和を算出
=SUM({範囲})
②データ(範囲)から平均を算出
=AVERAGE({範囲})
③データ(範囲)から相乗平均を算出
=GEOMEAN({範囲})
④データ(範囲)から中央値を算出
=MEDIAN({範囲})
データ(範囲)から標準偏差を算出
=STDEV({範囲})
2. T検定・Z検定をやってみよう
【A:A】データA
【B:B】データB
①標準偏差を求める
【D1】
=STDEV(A:B)
②Z検定をしてp値を求める
【F2】対象
【D2】
=ZTEST( A:B, F2, D1 )
コメント:
データ範囲と、標準偏差と、対象となる数値を指定
③T検定をしてp値を求める
【D3】
=TTEST( A:A, B:B, 2, 1 )
サンプル
アドオンを使ってみよう
プロジェクト管理
こちらのアドオンをSpreadSheetに追加してあげるだけで、いろいろかけるスグレモノ
詳しくは↓こちら
いろんな図を描いてみよう
Lucidchart Diagrams
詳しくは↓こちら
使えるFunction リスト
Function名 | 使い方 | 詳細 |
---|---|---|
ARRAYFOMULA | ARRAYFORMULA(array_formula) | 複数のデータを配列として扱う |
GOOGLETRANSLATE | GOOGLETRANSLATE(text, [source_language], [target_language]) | Google翻訳機能を使って翻訳結果を表示 |
IMAGE | IMAGE(url, [mode], [height], [width]) | URLから画像を表示 |
QUERY | QUERY(data, query, [headers]) | SQLっぽく任意のデータを整形し出力 |
SPARKLINE | SPARKLINE(data, [options]) | セル内に小さいグラフを表示 |
IMPORTDATA | IMPORTDATA(url) | URLからCSVやTSVデータを取得 |
IMPORTHTML | IMPORTHTML(url, query, index) | HTMLからListやTableの情報を取得 |
IMPORTXML | IMPORTXML(url, xpath_query) | HTMLからXMLデータを取得 |
IMPORTRANGE | IMPORTRANGE(spreadsheet_url, range_string) | 他のSpreadsheetからデータを取得 |
REGEXEXTRACT | REGEXEXTRACT(text, regular_expression) | 任意の文字列から正規表現に一致する部分を取得 |
REGEXMATCH | REGEXMATCH(text, regular_expression) | 任意の文字列が正規表現に一致するかどうかを判別 |
REGEXREPLACE | REGEXREPLACE(text, regular_expression, replacement) | 任意の文字列を正規表現により置換 |
SUBSTITUTE | SUBSTITUTE(search_txt, search_for, replace_with, [occurrence_number]) | 文字列の置換 |
TEXT | TEXT(number, format) | 任意のフォーマット形式の文字列に変換 |
TRIM | TRIM(text) | 文字列前後の半角スペースを削除 |
SPLIT | SPLIT(text, delimiter, [splitByEach], [removeEmptyTxt]) | 文字列を任意のセパレーターで分割 |
FILTER | FILTER(range, condition1, [condition2]) | 該当範囲内にあるデータをフィルタリング |
SORT | SORT(range, col, asc, [col2], [asc2]) | 該当範囲内にあるデータをソート |
UNIQUE | UNIQUE(range) | 該当範囲内にある重複データを削除して表示 |
HLOOKUP | HLOOKUP(search_key, range, index, [is_sorted]) | 任意範囲における横方向の検索 |
VLOOKUP | VLOOKUP(search_key, range, index, [is_sorted]) | 任意範囲における縦方向の検索 |
INDEX | INDEX(reference, [row], [column]) | 該当Cellにあるデータを取得 |
ROW | ROW([cell_reference] | 該当Cellの行数を取得 |
ISBLANK | ISBLANK(value) | 対象が空のCellであるかを判別 |
RAND | RAND() | 0〜1の範囲の数値の乱数を取得 |
RANDBETWEEN | RANDBETWEEN(low, high) | 任意の範囲の数値の乱数を取得 |
ROUND | ROUND(value, [places]) | 該当数値の該当桁数四捨五入値を取得 |
ROUNDDOWN | ROUNDDOWN(value, [places]) | 該当数値の該当桁数の切り捨て値取得 |
ROUNDUP | ROUNDUP(value, [places]) | 該当数値の該当桁数の切り上げ値取得 |
COUNT | COUNT(value1, [value2, ...]) | 該当範囲内の数値の入っているセルの数を取得 |
COUNTA | COUNTA(value1, [value2, ...]) | 該当範囲内のデータがないっているセルの数を取得 |
ZTEST | ZTEST(data, value, [standard_deviation]) | Z検定によるP値を取得 |
AND | AND(logical_1, [logical_2, ...]) | 論理式における論理積 |
OR | OR(logical_1, [logical_2, …]) | 論理式における論理和 |
NOT | NOT(logical) | 論理式における否定 |
IFERROR | IFERROR(value, [value_if_error]) | 与えられた関数がエラー終了した場合に任意のデータを出力 |
IFS | IFS(condition1, value1, [condition2, value2], …) | 複数の論理式に応じたそれぞれの出力を指定 |
SWITCH | SWITCH(exp, case, val, [default or case2, val2], …) | 複数の論理式に応じたそれぞれの出力を指定 |
おわりに
ご読了、ありがとうございます。
まだブログ書き始めてから2ヶ月ほどしか立っていませんが、これからもテック系の話やドキュメント系の話、今まで書いていませんが妄言のたぐいも描いていこうと思います。
↑こちら、まだ見ていない方、興味のある方はぜひ御覧ください。
重ねて、本年もどうぞよろしくおねがいします。
GoogleSpreadSheet (GSS) でGithub Issueを簡単に管理するシートを作ってみた
はじめに
皆さん、お久しぶりです。
私です。
こちらの記事ご覧になった方、
ありがとうございます。 m(_ _)m
ブログを書き始めて改めて思ったことなのですが、
私のブログ、毎回毎回長すぎじゃね?
というわけで、今回は短く、GoogleSpreadSheet(GSS)で簡単なIssue管理をするListのサンプルとその作り方を簡単に共有します。
ネタじゃないブログ画像
やりたいこと
- Issueの番号をIDとして表示(Issueへのリンクを付ける)
- 依存関係のあるIssueが登録できる
- 依存関係のあるIssueが解決されているかどうか分かる
作り方
Issueの番号をIDとして表示(Issueへのリンクを付ける)
これは簡単ですね。
基本的にB列をIssueのURLを入れるところにしています。
[A1] =ARRAYFORMULA( ←全部の行に対して適応 IFS( ROW(B:B)=1,"#", ←1行目は"#"を表示 ISBLANK(B:B),"", ←B列が空の場合は何も表示しない NOT(ISBLANK(B:B)), ←上記以外の場合は ↓B列の数値部分だけ取り出して、"#<<取り出した数値>>" を生成、リンクを付与 HYPERLINK(B:B, "#"®EXEXTRACT(B:B,"[0-9]+")) ) ) ) おまけ [B2:B (各行にコピー)] =IF( ISBLANK(B:B),"", ←B列が空の場合は何も表示しない IMPORTXML(B2,"//*[@id='partial-discussion-header']/div[1]/div/h1/span[1]") ↑Github IssueからIssueタイトルを取得(B2セルに書く場合)
依存関係のあるIssueが登録できる
これは記録できる列を作るだけなのでパス
依存関係のあるIssueが解決されているかどうか分かる
1. Issue がCloseになっているかどうかのパイププラインを作成
2. 依存Issueの数をカウント
[J2:J (各行にコピー)] =COUNTA(D2:G2) ←J2に書く時の場合
3. CloseになっているIssueをカウント
[K2:K (各行にコピー)] =IF( ← K2に書く場合 ISBLANK(D2),0, ← 空白のときは0 COUNTIFS(A:A,"="&D2,I:I,"=Close")) + ← 対象のIssueでCloseになっているものをカウント ↓以下、繰り返し(THE力技) IF(ISBLANK(E2),0,COUNTIFS(A:A,"="&E2,I:I,"=Close")) + IF(ISBLANK(F2),0,COUNTIFS(A:A,"="&F2,I:I,"=Close")) + IF(ISBLANK(G2),0,COUNTIFS(A:A,"="&G2,I:I,"=Close"))
4. SPARKLINE を使ってわかりやすくする
依存Issueのうち何件終わっているかがわかるようにSPARKLINEのBarChart使います
[H2:H (各行にコピー)] =IF( ←H2に書く場合 ISBLANK(B2),"", SPARKLINE(K2, ← CloseされたIssueの数 {"charttype","bar"; ← BarChart指定 "max",J2; ← 依存Issueの数 "color1","#191970" ← BarChartの色 }) )
完成
さいごに
何箇所か回りくどい記述が多いのでもっとスマートな記述をしていきたいこころ
僕的Plant UMLのススメ【図形描画編】
はじめに
こんにちは。
このブログも開始から無事1ヶ月経過しました。
本日は前回(UML知識&環境構築 for mac編)、前々回(Style編)に続いて、いよいよPlantUMLで図形の描画に関しての記述をまとめていきます。
僕的PlantUMLのススメ
- Style編 (前々回)
- UML知識&環境構築 for mac編 (前回)
- 図形描画編 (今回)
構成
PlantUMLは様々な図を表現することができますが、ここでは@ogomrさんの「PlantUML Cheat Sheet」*1に則って、大きく振る舞い図と状態図に分けて解説していきます。
また、可能な限りサンプルを用意していますが、図を含むサンプルは記述が長くなりすぎるので、基本的には▶Sample
みたいな感じで閉じていますので、利用したい方は開いてみてください。
ではいつものようにネタ画像とともに、どうぞ。
目次
目次一覧
1. 全般
1-1. コメント
ここで書くコメントは、PlantUML
での記述中にメモとして残すコメントです。
なので、図には反映されません。
本記事ではわかりやすさのため、サンプルのPlantUML
上にコメントを残していきますので、最初にご紹介します。
書き方
1行のみのコメント
`
複数行のコメント
/` HOGE FUGA `/
sample
@startuml ` 1行のみのコメント ` 簡潔かつわかりやすく書くことが大事 /` 複数行に渡るコメント ガッツリ説明を入れる場合などに使う `/ @enduml
1-2. タイトル・ヘッダー・フッター
項目 | 説明 |
---|---|
title |
ページにタイトルを付ける |
header |
ページにヘッダーを付ける |
footer |
ページにフッターを付ける |
Sample
@startuml ' 表示スタイルの設定 skinparam Shadowing false skinparam Monochrome true ' ==============本題は以下から============= header 僕的Plantumlのススメ\n(ヘッダー) title サンプルのヘッダー\n改行はこちら footer 僕的Plantumlのススメ\n(フッター) ' どのパラメータも \n により改行を入れることができる (hoge) -> (fuga) @enduml
1-3. ページ分割
newpage
を入れることでグラフを分割して、ページを分けることができる
newpage
前後ではスタイルやヘッダー・フッター・タイトルなどすべて受け継がないので、同一ファイル内で複数の画像を生成するというイメージのほうがあっているかも‥
1-4. ノート(メモ)
PlantUMLではあらゆる要素に対して、メモを差し込むことができる。
キーワードは note
で、様々な方法でノートの挿入が可能になっている。
また、差し込んだメモ内には次のHTMLタグなどを利用することができる。
利用可能タグ一覧
<b>
- 太文字指定
<u>
- アンダーライン
<i>
- 斜字体
<s>
,<del>
,<strike>
打ち消し線
<font color="HOGEHOGE">
または<color:#HOGEHOGE>
- 文字色変更
<font size="NN">
または<size:nn>
- フォントサイズ変更
<img src="file">
または<img:file>
- 画像の挿入 *2
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義 !include ./const_contents.plantuml skinparam Shadowing false ' タイトル title ノート(メモの使い方) /'単純なノート 他の要素に直接繋げない場合、名前を付ける必要があるので注意 '/ note "単純なノート" as sinmpeNote ' 複雑なノート note as complexNote 複雑なノート 改行するとそのまま改行される === ' ===で二重線を引くことができる - <b>太文字</b> - **「*」も使える** - <u>アンダーライン</u> - __「_」も使える__ - ~~「~」で波線も使える~~ - <i>斜字体</i> - //「/」も使える// - <s>打ち</s> <del>消し</del> <strike>線</strike> - --「-」も使える-- - <font color="indigo">文字色変更</font> - <size:11>フォントサイズ変更</size> - 画像の挿入 --- ' ---で境界線を引くことができる <img https://pbs.twimg.com/profile_images/3228282688/4a3c9e25b9831f3d74c357cae6c90636_reasonably_small.png> end note /'エレメントとノートを関連付ける 1. 関連付けるエレメントの直後にnoteを入れる 2. ノートに名前をつけ、線でつなぐ '/ (上note) note top: 上にノートをくっつける (右note) note right: 右にノートをくっつける (下note) note bottom 下にノートをくっつける 複数行もできる end note (左note) note left 左にノートをくっつける 複数行もできる end note complexNote ... (右note) complexNote --- (上note) (上note) -right-> (右note) (右note) -down-> (下note) (下note) -left-> (左note) (左note) -up-> (上note) @enduml
1-5. 表示順序
描画の順番を左右方向か、上下方向化を指定する。
defaultは上下方向。
key | sample |
---|---|
top to bottom direction |
|
left to right direction |
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義 !include ./const_contents.plantuml !include ./const_style.plantuml ' タイトル title 表示順序変更\ntop to bottom(default) top to bottom direction (001) --> (002) (002) --> (003) newpage ' ヘッダー・フッターを読み込み & スタイル定義 !include ./const_contents.plantuml !include ./const_style.plantuml ' タイトル title 表示順序変更\nleft to right left to right direction (001) --> (002) (002) --> (003) @enduml
1-6. ライブラリー
PlantUMLではスタンダードライブラリーとして AWS
やAzure
、Cloud Insight
などのLibraryが用意されており、実際にPlantUMLで利用することができる。
Sample
@startuml !include ./const_contents.plantuml !include <aws/common> !include <aws/Storage/AmazonS3/AmazonS3> !include <aws/Storage/AmazonS3/bucket/bucket> skinparam Shadowing false title ライブラリーインポート(AWS) AMAZONS3(s3_internal) AMAZONS3(s3_partner,"Vendor's S3") s3_internal <- s3_partner @enduml
2. 振る舞い図
2-1. 全般
2-1-1. シーケンス番号付
振る舞い図における順序において、上から順に番号付をしてくれる機能。
autonumber <連番開始数(省略可)> <数字送りの幅> "<フォーマット>"
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title シーケンス番号付 autonumber HOGE -> FUGA : 自動連番開始 HOGE <- FUGA : 連番を一時停止 autonumber stop HOGE -> FUGA : 停止中 autonumber resume "<b>[0]" HOGE -> FUGA : フォーマットを変えて再開 HOGE <- FUGA : 再停止 autonumber stop HOGE -> FUGA : 停止中 autonumber 1 10 "<b>0.0: " HOGE -> FUGA : 連番振り直し HOGE <- FUGA : 連番間隔を10に設定 @enduml
2-1-2. 境界線・遅延・間隔
key | 名称 |
---|---|
== <境界線名称> == |
境界線 |
... |
遅延 |
||<間隔px>|| |
間隔 |
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 境界線・遅延・間隔 ' 境界線 == 境界線 == FUGA --> HOGE: Authentication Request HOGE --> FUGA: Authentication Response ' 遅延 ... FUGA --> HOGE: Another authentication Request HOGE --> FUGA: another authentication Response ' 間隔50px ||50|| FUGA --> HOGE: Another authentication Request HOGE --> FUGA: another authentication Response @enduml
2-1-3. 条件
エンジニアの方なら見慣れた if
やelse
を使う処理。
サンプルを見るのが一番早いやつ。
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 条件文 start if (A or B) then (A) :Aを選んだらこっち; elseif (A or B) then (B) :Bを選んだらこっち; stop else :どれも選ばなかったらこっち; stop endif stop @enduml
2-1-4. 繰り返し
ある条件がクリアするまで繰り返す。
繰り返しには後判定
と前判定
の2パターンがある。
key | 繰り返しパターン | 詳細 (処理Aを繰り返す場合) |
---|---|---|
repeat while |
後判定 | Aの処理が終了した後に繰り返すかどうかの判定をする |
while |
前判定 | Aの処理を実施する前に実施するかどうかの判定をする |
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 繰り返し start ' 後判定 repeat :HOGE; repeat while (繰り返す?) ' 前判定 while (繰り返す?) :FUGA; endwhile stop @enduml
2-1-5. 並列処理
複数の処理を同時並行で処理する場合の記述する。
フォークノードやジョインノード等と呼ばれる。
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 並列処理 start if (並列処理する?) then (yes) fork :並列タスク1; fork again :並列タスク2; end fork else (no) :非同期タスク1; :非同期タスク2; endif stop @enduml
2-2. ユースケース図
ユースケース図ではいろいろな記号を使うので、それぞれの書き方をまとめます。
名称 | キーワード | 省略記法 | サンプル |
---|---|---|---|
ユースケース | usecase ユースケース |
(ユースケース省略記法) |
|
アクター | actor アクター |
:アクター省略記法: |
|
ステレオタイプ | <<ステレオタイプ>> |
||
関連(矢印) | -> ,--> ,..|> |
なし |
矢印サンプル
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 矢印 left to right direction :アクター1: -> (ユースケース1) :アクター1: -------> (ユースケース2) :アクター1: ..|> :アクター2: : <<extend>> :アクター2: ..|> :アクター3: : <<include>> :アクター3: -left-> (左) :アクター3: -right-> (右) :アクター3: -up-> (上) :アクター3: -down-> (下) @enduml
ユースケース図Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title ユースケース図 left to right direction actor 顧客 as 顧客 <<ユーザー>> actor 受付 as 受付 <<ユーザー>> actor 受付システム as 受付システム <<システム>> rectangle チェックアウト { 顧客 --> (チェックアウト) (チェックアウト) <-- 受付 (チェックアウト) ..|> (支払い) : <<include>> (問い合わせ) ..|> (チェックアウト) : <<extends>> (問い合わせ) -down-> 受付システム } @enduml
2-3. アクティビティ図
アクティビティ図にも記号が複数あるのでそれぞれまとめます。
名称 | キーワード | 省略記法(ベータ版) | サンプル |
---|---|---|---|
アクティビティ | "アクティビティ" | :アクティビティ; | |
初期ノード | (*)--> |
start | |
終端ノード | -->(*) |
stop | |
動線 | |<動線名称>| |
|<動線名称>| |
導線Sample
上記導線Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title 動線 |α| start |β| :1; |γ| |δ| :2; |ε| :3; |γ| :4; |β| stop @enduml
Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title アクティビティ図 |自宅| start :起床; fork if (時間の猶予) then (ある) :朝ごはんを準備; :朝食; else (ない) endif fork again :テレビをつける; :天気を確認; end fork :出勤の準備; if (終日の天気) then (雨模様) :電車を確認; |屋外| :家を出る; :電車に乗る; |会社| :会社ビルに\n到着; else (晴れ) |屋外| :家を出る; :自転車の状態を確認; :自転車に乗る; while (移動) :自転車で移動; endwhile (会社ビルに到着) |会社| endif :エレベーターに乗る; :執務室階へ移動; :勤怠をつける; stop @enduml
3. 状態図
3-1. クラス図
クラスの関連を示す矢印の記法は3種類あります。
Type | key |
---|---|
関連(Association) | --- |
集約(Aggregation) | o-- |
コンポジション (Composition) |
*-- |
依存(Dependency) | <.. |
汎化(Generalization) | <|-- |
実現(Realization) | <|... |
また、下記のように接続するクラスと関連の矢印の間に"
で1
や*
などの多重度をラベルとしてつけることができます。
Class01 "1" --- "1..n" Class02
関連矢印Sample
サンプル図は上記のもの
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title Class 関連矢印 rectangle 関連\n(Association) { Association01 "0" -- "*" Association02 } rectangle 集約\n(Aggrefation) { Aggrefation01 "1" --o "*" Aggrefation02 } rectangle コンポジション\n(Composition) { Composition01 "1" --* "1..n" Composition02 } rectangle 依存\n(Dependency) { Dependency01 "*" ..> "*" Dependency02 } rectangle 汎化\n(Generalization) { Generalization01 "1..n" --|> "*" Generalization02 } rectangle 実現\n(Realization) { Realization01 "1" ..|> "1" Realization02 } @enduml
クラスは上記で説明した関連を使えば勝手に作成されますが、中身を詳細に書こうと思うと、きちんと定義して上げる必要があります。
定義の仕方は大きく「最初に{}
を使ってフィールドとメソッドを作る方法」と「宣言した後にそれぞれのエレメント等を定義する方法」、2パターンあります。
クラス宣言Sample
サンプル図は上記のもの
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title Class Class 先に宣言するクラス { data : String setData() : Void } 先に宣言するクラス "1" - "1" 後で要素を追加するクラス 後で要素を追加するクラス : data : Object[] 後で要素を追加するクラス : getData() : String @enduml
クラスの中にはデータ・もしくはfunctionの可視性を定義することができます。
Type | Key | 内容 |
---|---|---|
private プライベート |
- |
宣言クラスのみアクセス可能 |
package private パッケージプライベート |
~ |
宣言クラスと同パッケージのみアクセス可能 |
protected プロテクト |
# |
宣言クラス・サブクラスのみアクセス可能 |
public<パブリック> | + |
すべてのクラスからアクセス可能 |
可視性(Visiility)Sample
サンプル図は上記のもの
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml skinparam Shadowing false title 可視性(Visibility) Class Visibility { - privateData : String - privateFunction() : Void # protextedData : String # protextedFunction() : Void ~ packagePrivateData : String ~ packagePrivateFunction() : Void + publicData : String + publicFunction() : Void } @enduml
クラス図はパッケージとしてまとめることができます。
パッケージSample
図は上記
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title パッケージ package Nodeパッケージ <<Node>> { class NodeClass } package 四角パッケージ <<Rectangle>> { class RectangleClass } package フォルダーパッケージ <<Folder>> { class FolderClass } package フレームパッケージ <<Frame>> { class CrameClass } package クラウドパッケージ <<Cloud>> { class CloudClass } package データベースパッケージ <<Database>> { class DatabaseClass } @enduml
クラスで使われる目印文字を指定して利用することができます。
目印文字指定Sample
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml skinparam Shadowing false title 目印文字 Class Hash <<(H,#00bfff)>> Class Analysis <<(A,#fa8072)>> Class Joke <<(J,#f0f8ff)>> Class Idea <<(I,#00ff7f)>> Class Member <<(M,#ffb6c1)>> Class Event <<(E,#00ced1)>> @enduml
3-2. コンポーネント図
関連や矢印等の書き方はクラス図と同じ。
[]
内でくくるとコンポーネントの表記に変わる。
コンポーネント図Sample
上記の図
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml skinparam componentStyle uml2 title コンポーネント図 package "認証認可パッケージ" { [認証] [ユーザー操作] } cloud "CloudファンクションAPI" { [認証API] [ユーザーAPI] } database "BigQuery" { [ユーザーデータ] [閲覧情報] } [認証] <--> [認証API] [ユーザー操作] --> [認証API] [ユーザー操作] <--> [ユーザーAPI] [認証API] <--> [ユーザーデータ] [ユーザーAPI] <--> [ユーザーデータ] [ユーザーAPI] <--> [閲覧情報] @enduml
3-3. オブジェクト図
オブジェクト図はPlantUML上の記述方法がほぼほぼクラス図と同じで、「クラス図からファンクション部分がなくなったもの」という認識で十分です。
使い方も Object
というキーワードを入れると後はClass図のときと同様に利用することができます。
Sample
図は上記
@startuml ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml skinparam Shadowing false top to bottom direction title Object図 rectangle 関連 { rectangle 実現\n(Realization) { Object Realization01 Object Realization02 Realization01 "1" .|> "1" Realization02 } rectangle 汎化\n(Generalization) { Object Generalization01 Object Generalization02 Generalization01 "1..n" -|> "*" Generalization02 } rectangle 依存\n(Dependency) { Object Dependency01 Object Dependency02 Dependency01 "*" .> "*" Dependency02 } rectangle コンポジション\n(Composition) { Object Composition01 Object Composition02 Composition01 "1" -* "1..n" Composition02 } rectangle 集約\n(Aggrefation) { Object Aggrefation01 Object Aggrefation02 Aggrefation01 "1" -o "*" Aggrefation02 } rectangle 関連\n(Association) { Object Association01 Object Association02 Association01 "0" - "*" Association02 } } rectangle 可視性 { Object Visibility { - privateData : String # protextedData : String ~ packagePrivateData : String + publicData : String } } rectangle パッケージ { package データベースパッケージ <<Database>> { Object DatabaseObject } package クラウドパッケージ <<Cloud>> { Object CloudObject } package フレームパッケージ <<Frame>> { Object CrameObject } package フォルダーパッケージ <<Folder>> { Object FolderObject } package 四角パッケージ <<Rectangle>> { Object RectangleObject } package Nodeパッケージ <<Node>> { Object NodeObject } } 可視性 -[hidden]le- パッケージ 関連 -[hidden]do- パッケージ @enduml
4. その他
実はPlantUMLはUMLだけではなく様々なものを扱うことができます。
今回はその中でも使い勝手の良いものをいくつかご紹介します。(サンプルと書き方だけですが…。)
4-1. マインドマップ
@startmindmap
@endmindmap
を使う。
Markdownのリストみたいな書き方。
子要素にする場合は親要素の直後に「親要素の*
の数+1」個の*
を先頭につけて記述。
テキストのみを表示する場合は最後の*
の後に_
を入れる
Sample
図は上記
@startmindmap ' ヘッダー・フッターを読み込み & スタイル定義ファイル読み込み !include ./const_contents.plantuml !include ./const_style.plantuml title マインドマップ * <&star>星のカービィ ** サウンド *** ボイス ****_ 大本 眞基子(カービィ他) ****_ 桜井 政博(デデデ 64, スマブラ) ****_ 緒方 賢一(デデデ アニメ) ****_ 熊崎 信也(デデデ USD, Wii, トリデラ) ****_ 私市 淳(メタナイト) ****_ 齋藤 彩夏(ワドルディ) *** 効果音 ****_ 安藤浩和 ****_ 石川淳 ****_ 小笠原雄太 *** 音楽 ****_ 安藤浩和 ****_ 石川淳 ****_ 小笠原雄太 ** テキスト *** システムメッセージ ****_ 子供向け ****_ 伏線を張りまくる ****_ ネタを作る *** ナレーション ****_ 毛糸のカービィのみナレーションあり ****_ 津賀 有子 *** セリフ ****_ 備えあれば嬉しいな! ****_ 才能は無くても根気だけはある物好きは腐るほどいるでゲス ****_ 環境破壊は気持ちいいぞい ** グラフィック *** 背景 ****_ 美しい系のきれい ****_ 違和感がない程度に異常 *** オブジェクト ****_ 限りなく少ない ****_ ワドルディが時々コントしてる *** カメラワーク ****_ 固定 *****_ 基本2D移動 left side ** 世界観 *** コンテキスト ****_ カービィの周りは平和 ****_ なにげにシリーズを通して深い *** キャラクター ****_ 基本的に可愛らしいビジュアル *** イベント ****_ ギミック多め ****_ HAL部屋 ****_ 裏切り ****_ 敵の敵は味方 *** ストーリー ****_ 可愛らしさ優先 ****_ 割とエグい設定 ****_ 世界の危機(いつもの) ** システム *** 自由度 ****_ 増え続けるコピー能力 ****_ 基本ストーリーをなぞる ****_ 移動に関する自由はほぼ無い *** 操作性 ****_ コピー能力によりコマンド有り ****_ ノーマルの場合は単純明快 *** ゲームバランス ****_ 基本初心者向け ****_ 上級者向けのモードあり @endmindmap
4-2. ツリー
木構造のウィジェットを作る感じで利用可能。
ワイヤーを作る機能に付随している(@startsalt
と@endsalt
で囲む)。
Sample
@startsalt { {T + World ++ America +++ Canada +++ USA ++++ New York ++++ Boston +++ Mexico ++ Europe +++ Italy +++ Germany ++++ Berlin ++ Africa } } @endsalt
4-3. 算術表記
PlantUMLではAsciiMathやJLaTeXMathの構文が利用可能。
Sample
@startuml :<math>int_0^1f(x)dx</math>; :<math>x^2+y_1+z_12^34</math>; note right Try also <math>d/dxf(x)=lim_(h->0)(f(x+h)-f(x))/h</math> <latex>P(y|\mathbf{x}) \mbox{ or } f(\mathbf{x})+\epsilon</latex> end note @enduml
4-4. ワイヤーフレーム
ツリー構造のところで記述したとおり、@startsalt
と@endsalt
で囲んで記述する。
チープなUIだが、いろいろ書くことができる。
Smaple
@startsalt {+ {* ファイル | 編集 | 表示 | ウィンドウ | ヘルプ} {/ ブログ記事編集 | 僕的URMのススメ | PlanUML言語 } { { 保存種別: | ^日時を指定して予約投稿^ } [X] サムネイル画像を変更する [X] Twitterと連携し、投稿されたらツイートする [ ] 投稿時にメールを送信する } [Close] } @endsalt
おわりに
今回も、信じられないくらい長文になりましたが、なんとかPlantUMLシリーズ書ききることができました。
今回ご紹介したPlantUMLはまだいろいろな機能があります。(私はあまり使わないのですが…)
PlantUML自体の記述方法は簡単ですが、使いこなそうと思うと一気に難しくなります。
触れる機会が多いほど、当たり前にかけるようになってくるので、是非仕事だけじゃなく個人的でも、趣味でもいろいろなところで使ってみてください。
ではまた次回。
参考
- @ogomr, Qiita - PlantUML Cheat Sheet -, 最終閲覧 2019-11-04
- PlantUML言語リファレンスガイド, 最終閲覧 2019-11-04
- PlantUMLを使ったUMLの使い方 -PlantUML言語リファレンスガイド(Versin 1.2019.9)-, 最終閲覧 2019-11-04
僕的Plant UMLのススメ【UML知識&環境構築 for mac編】
第0章: ご挨拶
こんにちは
前回から引き続き、Plant UMLに関して書いていきます。
今回は、「そもそもUMLってなんや?」から始まり、「PlantUMLってどうすれば使えるようになるの?」等をご紹介する記事です。
それではいつもどおりネタ画像とともにどうぞ
第1章: 目次
第2章: UMLとは?
UMLの定義
UMLとは(Unified Modeling Language)の略で、統一モデリング言語と訳されることが多いです。
言語
と書かれているので非エンジニアの方は忌避してしまうかもしれませんが、極論を言うと誰でもわかるようにある一定の規格をまとめた図の総称です。
UMLとは、オブジェクト指向のソフトウェア開発において、データ構造や処理の流れなどソフトウェアに関連する様々な設計や仕様を図示するための記法を定めたもの。ソフトウェアのモデリング言語の標準としてとして最も広く普及している。 *1
主にシステムを開発する際の設計時に作成されることが多いです。
そもそも、なぜUMLなどというモノが必要なのかというと、大きく4つの理由があります。
- 開発チーム内でのプロダクト(開発物)に対する共有を図るため
- エンジニアも一人の人間。感じ方・考え方は人それぞれ。
複数の作曲家が「なんか、POPでイカした90秒の曲作って」と依頼を受けた場合、誰一人として同じ曲を作れないのと一緒。
システムも音楽も実体がないので、密な共有がないと同じものを作ることができないのは当たり前。
- エンジニアも一人の人間。感じ方・考え方は人それぞれ。
- 開発にかかわらない人でも、システムのできること・できないこと等の共有を図るため
- 依頼者も開発者もそれぞれ一人の人間。言葉だけですべてのイメージを共有できるのであれば、それはすでに超能力の一種。
エンジニアが「ここの仕様どうしましょうか?」ってめっちゃ聞いてきても、キチンと答えてあげてください。彼らは使う人達の要望をお金と時間と人間関係が良好な限り最大限叶えようと努力しています。
- 依頼者も開発者もそれぞれ一人の人間。言葉だけですべてのイメージを共有できるのであれば、それはすでに超能力の一種。
- 開発チームがいなくても、他のエンジニアが設計を把握するため
作った人が皆やめてもギリギリ生き残る
- プロダクトの問題点を洗い出しやすくするため
- システムの仕様書とか設計とかを書くと、色んな人からレビューをもらうことができ、システムの穴を見つけたりすることができる。
アジャイル手法で開発を進めていない会社で「なんでシステム開発をするときにUMLみたいな図を書くんだ!! さっさと作ればいいじゃないか。」みたいなことを言い出す上司がいたら、上記の理由を言って説明してあげてください。
アジャイル手法を使っているからと言って、全く設計しないところは逆にやばいので気をつけて(特に第3項目)
UMLの種類
前節でご紹介したとおり、UMLはソフトウェアの設計するために用いられる図なので、様々な種類があります。 ここではとりあえず、主要なUMLを列挙し、次節でそれぞれのUMLの細かいところの説明をします。
名称 | 図 |
---|---|
ユースケース図 | |
アクティビティ図 | |
状態図(ステートマシン図) | |
クラス図 | |
ER図 | |
CURD図 | |
データフロー図 | |
シーケンス図 | |
コンポーネント図 |
UMLの使いみち
ユースケース図
丸い枠内の内容をユースケース、人形をアクター(Actor)と呼ぶ。
Actorはシステム(対象)外のシステム(対象)に対して何らかのユースケースを実施可能なすべてのモノを指す。(人だけじゃなくて、外部のBotなどもActorになり得る)
Actorとユースケースが線でつながっている場合は、
(Actor)は(ユースケース)の機能を利用できる
ということを意味する。
inculde | extend |
---|---|
システム設計以外ユースケース図を使う場合
@startuml skinparam Usecase { BorderColor Black FontColor Black } skinparam Actor { BackgroundColor<<Mother>> Pink BorderColor<<Mother>> Pink BackgroundColor<<Father>> Blue BorderColor<<Father>> Blue BackgroundColor<<Me>> DeepSkyBlue BorderColor<<Me>> DeepSkyBlue } skinparam Shadowing false title 母親の権威が強い家庭のユースケース図 :母: as 母 <<Mother>> :父: as 父 <<Father>> :私: as 私 <<Me>> :銀行: as 銀行 母 <.. 父 : <<include>> 父 <.. 私 : <<extend>> 母 --> (引き落とし) (エステ) ..> (買い物) : <<extend>> 母 --> (エステ) 母 --> (家事) 父 --> (入金) 父 --> (出社) 父 --> (買い物) 私 --> (登校) 私 --> (買い物) 銀行 --> (引き落とし) 銀行 --> (入金) @enduml
アクティビティ図
物事の初期状態から最終的な状態までの行動を図示するUML。
記号(構成要素)がたくさんあるけど、詳しく知らなくてもおおよそ分かる。
構成要素一覧
図の特性上、システムのフローはもちろん、私生活の一部も図示することができる。
たぶん利用範囲が一番広い図。
私生活で使う例
@startuml skinparam Shadowing false skinparam Activity { BorderColor Black FontColor Black } title 肉じゃがのレシピ start :材料を準備; note right 準備する材料 ==== ・牛肉または豚肉(250g) ・じゃがいも(中4〜5個) ・玉ねぎ(中1個) ・人参(中1本) ・白滝(1袋) ・サラダ油(大さじ1) ◎ 砂糖(大さじ2と1/2) ◎ みりん(大さじ2と1/2) ◎ 料理酒(大さじ2と1/2) ◎ だし汁(300ml) ◎ 醤油(大さじ3) end note :具材を切る; note right じゃがいも:煮崩れしやすいので大きめに 玉ねぎ・人参・肉:好みに合わせた大きさで切る end note :鍋にサラダ油を引く; :じゃがいも・玉ねぎ・人参を炒める; while (じゃがいもの表面が) is (透き通っていない) :炒め続ける; endwhile (透き通ってきた) :◎で示した調味料を加える; -> 中火で5分間煮付ける; :醤油を加える; :肉を入れて良くほぐす; :肉に重ならないように 白滝を入れる; -> 弱火よりの中火で15分煮付ける; while (じゃがいもが) is (硬い) :煮続ける; endwhile (柔らかくなった) :火を止める; note right 鍋に入れたまま一度冷やすと味がよく染みて良い end note end @enduml
ステートマシン図
対象(オブジェクト)の状態線を表現するためのUML。
対象が主体になるところがポイント。
実施者単体にフォーカスして、どんな動きをするのかを図示する感じ。
具体的なサンプル画像
クラス図
システムを構成するクラスとそれらの関係を表現するUML。
一つのまとまりの持つクラスの属性や機能をわかりやすく示し、それらの関係性を表現する。
PlantUML記述例
@startuml class エンジニア { + 名前 + スキル # 生年月日 - 給料 + システム開発() } class PM { + 名前 # 生年月日 - 給料 + システム設計() + 開発マネジメント() } class 開発部 { + プロジェクト予算 + 参加人数 + システム設計() + システム開発() } PM "1" --* "多" 開発部 エンジニア "多" *-* "多" 開発部 @enduml
ER図
ER図のERとは、Entity Relationshipの略称であり、データベースのテーブル(Entity)とテーブル同士の関連(Relationship)を示したUMLです。
クラス図から機能
がなくなって、主キーや外部キーが増える以外はクラス図とほぼ同じ書き方。
RDBを設計するときによく使われる図。
PlantUML記述例
@startuml class エンジニア { # ID - 名前 - スキル - 生年月日 - 給料 } class PM { # ID - 名前 - 生年月日 - 給料 } class 開発部 { # PM_ID (FK) # ID + プロジェクト予算 + 参加人数 } class 開発部ーエンジニア { # ID # エンジニア_ID (FK) # 開発部_ID (FK) } PM "1" --* "多" 開発部 エンジニア "1" --* "多" 開発部ーエンジニア 開発部ーエンジニア "多" *--* "多" 開発部 @enduml
CURD図
データの操作に着目して機能を洗い出すときに用いるUML。
マトリックス形式で記述できれば何でもOK。
「このデータって更新できないんだっけ?」や「このデータの削除ってどうやってやるんだっけ?」みたいなことを確認できる。
例)
ユーザー情報 | |
---|---|
ユーザー登録 | C |
ユーザー一覧 | R |
ユーザー情報詳細 | R,U |
ユーザー情報削除 | D |
データフロー図
データの入出力や流れを可視化する図
外部実体
、データストア
、プロセス
、データフロー
という4つの要素から記述される。
要素の表現方法は、派閥によって2つある。(Yourdon & DeMarco記法 VS Gane & Sarson記法)
※ Gane & Sarson:GS
要素 | 説明 | YD | GS |
---|---|---|---|
データフロー | データの流れを示す 矢印とその要因 |
||
プロセス | データを書き換えるような 処理を実施する行動(動作) |
||
外部実体 | 対象(システム)に関連する 自分以外の対象 |
||
データストア | データの永続的な保存先 DBやデータレイク等 |
シーケンス図
クラスやオブジェクト間のやり取りを時間軸ごとに表現するUML
バケツリレーみたいに、何がどうするのか
がわかる。
sample
PlantUML記述例
@startuml skinparam Shadowing false autonumber actor 顧客 #Cyan actor 営業 #Cyan actor 顧客管理システム #Blue database 顧客管理DB #Green actor 営業課長 #Cyan actor 部長 #Cyan actor 法務 #Cyan 営業 -> 顧客 : 売り込み 顧客 -> 営業 : 契約申請 営業 -> 顧客管理システム : システム入力 顧客管理システム -> 顧客管理DB : 顧客登録 顧客管理システム -> 営業課長 : 新規申請通知 営業課長 -> 部長 : 承認申請 部長 -> 法務 : 法務チェック申請 法務 -> 顧客管理システム : 申請許可入力 顧客管理システム -> 顧客管理DB : データ更新 顧客管理システム -> 部長 : 承認通知 顧客管理システム -> 営業課長 : 承認通知 顧客管理システム -> 営業 : 承認通知 営業 -> 顧客 : 契約完了通知 @enduml
コンポーネント図
複数のクラスで構成される挙動を、コンポーネントという1つにまとめて、1つのクラスのように取り扱うための表現。
PlantUML記述例
@startuml skinparam Shadowing false package ログイン機能 { [ログイン情報入力コンポーネント] - [ログイン情報検証コンポーネント] } cloud { [ユーザー情報取得API] } database UserDB [ログイン情報検証コンポーネント] --> [ユーザー情報取得API] [ユーザー情報取得API] --> UserDB @enduml
第3章: PlantUMLとは?
テキストベースで記述した様々な図を生成するツール。
前章で、PlantUML記述例
というところに書かれているものがPlantUMLでの記法になります。
公式サイトは、英・独・西・仏・日・韓・露・中の8カ国語分のドキュメントが用意されています。
ただ、ドキュメントがあまり詳しくないので、Ashley Engelund氏が個人でドキュメント(Ashley's PlantUML Doc)を作っています。(前回ご紹介したドキュメントはこちらになります。)
こちらのドキュメントは、メチャチャ詳しく細かくPlantUMLに関して記載してありますので、英語の読解に自身のある方はこちらを見てみるのも良いかもしれません。
PlantUMLを使うメリット
PlantUMLのメリットは色々ありますが、一番メリットが大きいのは、一番最後のMarkdownの中に挿入できるものが増えてきた点です。
*6
例えば、システムを開発する際にそのドキュメントをMarkdownでReadMeとして記述することが多々あるかと思います。
その際に問題になってくるのが、UMLなどの画像ファイルを更新したい場合の対応です。
Markdownファイル上で画像を記述できるということは、画像ファイルのもととなるツールのダウンロードや、画像自体の元ファイルの管理などをする必要がなくなるということと同義です。
つまり、UMLを共同で編集する場合や、共同で確認・更新するという作業をする点で、準備をする必要がないため、すぐに変更したり共有したりすることができます。
PlantUMLを使うデメリット
前節ではメリットを熱く書き連ねましたが、もちろんデメリットも存在します。
中でも一番大きなデメリットは、ローカルでの環境構築が少し面倒
という点です。
Onlineで書くことができるツール・サービスが増えてきていますが、やはりローカル環境で記述してローカルで確認したいということも多いでしょう。
いろいろな方法がありますが、今回はMacユーザの私が活用している、Atomエディター内で編集と表示確認をする方法をご紹介します。
第4章: PlantUML on Atomの環境構築 for Mac
環境・ツール | バージョン |
---|---|
10.11.6 | |
v2.1.15 | |
Atom | v1.25.1 |
v2.6.2 |
- Homebrewの準備
- Homebrewの公式サイトに従って、Homebrewをダウンロード
- Atomの準備
- Atomの公式サイトからダウンロード
- PlantUMLのダウンロード
- PlantUML公式のダウンロードページから、最新の
plantuml.jar
を任意の場所にダウンロード
例)/Users/(hatena)/Documents/plantuml.jar
- PlantUML公式のダウンロードページから、最新の
- 描画機能のダウンロード
brew install graphviz
を実行- 上記実行ができない場合があるので、その場合はMacPortsの指定環境をダウンロード
- Atomパッケージ追加
- Atomを開き、ツールバーから
Atom
→Prefarences
を選択 - サイドバーから
Install
を選択 - 検索窓でlanguage-plantumlとplantuml-viewerを探し、インストール
- Atomを開き、ツールバーから
- plantuml-viewer設定
- サイドバーから
Packages
を選択し、plantuml-viewer
を検索 plantuml-viewer
のsetting
を選択- PlantUML JARの項目のところに、ダウンロードしてきたplantuml.jarを指定(
/Users/(hatena)/Documents/plantuml.jar
)
- サイドバーから
- 使ってみる
- 新しくファイルを作成し、PlantUMLを記述
ctrl-alt-p
を実施するとVuewerが表示される
最終章: おわりに
今回もだいぶ長文になってしまいましたが、ご覧頂きありがとうございます。
環境構築の方法などはいろいろな方がブログや記事にしていたりしますので、いろいろ探しながら試してみるとよいかと思います。
またUMLに関してですが、UMLの書き方にも派閥のようなものがあったりするので、私の説明したものが利用したい環境の使い方と違う可能性はありますのでご注意ください。
次回、PlantUML集最終回です。
やっと図を書き始めます。
なんか僕がやりたかったことをもうQiitaで書いてる方がいて、心が折れそうですが、めげずに最後まで書ききろうかと思います。
ではでは、また次回。
お知らせ
下記イベントで登壇することになりました。
abeja-innovation-meetup.connpass.com
- Vue.js
- Plotly.js
- Atomic Design
に興味のある方はぜひイベント申し込んでみてください!!
参考
- Spiegel, text.Baldanders.info » しっぽのさきっちょ -ATOM エディタを使った作図(PlantUML 編)-, 最終閲覧:2019-10-27
僕的Plant UMLのススメ【Style編】
はじめに
こんにちは
今回から複数回に分けて、Plant UMLに関して書いていこうかと思います。
今回はPlantUMLのフォーマットに関する記事です。
PlantUMLの導入方法や、どうやって書くのかは次回、次次回に書いていこうと思います。
m(_ _)m < Styleだけでめっちゃボリュームがあったから分割しました。 )
書き始めてから量が多いことに気づいたので
公開順序は勘弁してください m(_ _;)m
今回はStyle編となっています。
それでは、ネタ画像とともにどうぞー
Plant UML Style編
書き方
接頭語はskinparam
ネイティブなCSSっぽい
skinparam hogehogeParam1 value1 skinparam hogehogeParam2 value2 skinparam hogehogeParam3 value3 /* 上と下は同じ */ skinparam hogehoge { Param1 value1 Param1 value1 Param1 value1 }
個別に名称を設定することでそれぞれに反映させることができる
Sample
@startuml skinparam Usecase { BorderColor Black FontColor White StereotypeFontColor White BackgroundColor<<UseCase_01>> Green BackgroundColor<<UseCase_02>> Blue } title Set styles on Each Contents usecase (Usecase_01_green) <<UseCase_01>> usecase (Usecase_02_blue) <<UseCase_02>> @enduml
Result
クラス名一覧
図名称 | クラス名 |
---|---|
シーケンス図 | sequence |
ユースケース図 | usecase |
クラス図 | class |
コンポーネント図 | component |
アクティビティ図 | activity |
状態遷移(ステート)図 | state |
一覧
表サンプル
Param Name | 説明 |
---|---|
sample | 図 |
全体共通
- (Class名)FontName
- (Class名)FontColor
- (Class名)FontSize
- (Class名)FontStyle
全体共通一覧
FontColor | 対象のフォントの色を指定 |
---|---|
ActivityFontColor red |
|
FontName | 対象のフォントを変更 |
DatabaseFontName Papyrus |
|
FontSize | 対象のフォントサイズを変更 |
NodeFontSize 18 |
|
FontStyle | 対象のフォントのスタイルを変更 normal , plain, italic, bold |
TitleFontStyle italic |
よく触るスタイルたち
アクター(Actor)
- ActorBackgroundColor
- ActorBorderColor
- ActorStereotypeFontName
- ActorStereotypeFontColor
- ActorStereotypeFontSize
- ActorStereotypeFontStyle
アクタースタイル一覧
BackgroundColor | アクターの頭の色を変更 |
---|---|
ActorBackgroundColor lawnGreen |
|
BorderColor | アクターの枠線の色を変更 |
ActorBorderColor red |
|
StereotypeFont<HOGEHOGE> | ステレオタイプ部分のフォント設定の指定ActorStereotype をクラス名として、共通指定部分と同様 |
エージェント(Agent)
- AgentBackgroundColor
- AgentBorderColor
- AgentBorderThickness
- AgentStereotypeFontName
- AgentStereotypeFontColor
- AgentStereotypeFontSize
- AgentStereotypeFontStyle
エージェントスタイル一覧
BackgroundColor | 内部背景色の指定 |
---|---|
AgentBackgroundColor lawnGreen |
|
BorderColor | 枠線の色を変更 |
AgentBorderColor blue |
|
BorderThickness | 枠線の太さを変更 |
AgentBorderThickness 5 |
|
StereotypeFont<HOGEHOGE> | ステレオタイプ部分のフォント設定の指定ActorStereotype をクラス名として、共通指定部分と同様 |
矢印(Arrow)
- AgentBackgroundColor
- AgentBorderColor
- AgentBorderThickness
- AgentStereotypeFontName
- AgentStereotypeFontColor
- AgentStereotypeFontSize
- AgentStereotypeFontStyle
矢印スタイル一覧
BackgroundColor | 内部背景色の指定 |
---|---|
AgentBackgroundColor lawnGreen |
|
BorderColor | 枠線の色を変更 |
AgentBorderColor blue |
|
BorderThickness | 枠線の太さを変更 |
AgentBorderThickness 5 |
|
StereotypeFont<HOGEHOGE> | ステレオタイプ部分のフォント設定の指定ActorStereotype をクラス名として、共通指定部分と同様 |
バウンダリー(Boundary)
- BoundaryBackgroundColor
- BoundaryBorderColor
- BoundaryStereotypeFontName
- BoundaryStereotypeFontColor
- BoundaryStereotypeFontSize
- BoundaryStereotypeFontStyle
バウンダリースタイル一覧
BackgroundColor | バウンダリーの色を変更 |
---|---|
BoundaryBackgroundColor lawnGreen |
|
BorderColor | バウンダリーの枠線の入を変更 |
BoundaryBorderColor red |
|
StereotypeFont<HOGEHOGE> | ステレオタイプ部分のフォント設定の指定ActorStereotype をクラス名として、共通指定部分と同様 |
凡例(Legend)
- LegendBackgroundColor
- LegendBorderColor
- LegendBorderThickness
凡例スタイル一覧
BackgroundColor | 凡例の色を変更 |
---|---|
LegendBackgroundColor GreenYellow |
|
BorderColor | 凡例の枠線の入を変更 |
LegendBorderColor red |
|
BorderThickness | 凡例の枠線の太さを変更 |
LegendBorderThickness 1 |
ノード(Node)
- NodeBackgroundColor
- NodeBorderColor
- NodeStereotypeFontName
- NodeStereotypeFontColor
- NodeStereotypeFontSize
- NodeStereotypeFontStyle
Nodeスタイル一覧
BackgroundColor | Nodeの色を変更 |
---|---|
NodeBackgroundColor lawnGreen |
|
BorderColor | Nodeの枠線の入を変更 |
NodeBorderColor red |
|
StereotypeFont<HOGEHOGE> | ステレオタイプ部分のフォント設定の指定ActorStereotype をクラス名として、共通指定部分と同様 |
メモ(Note)
- NoteBackgroundColor
- NoteBorderColor
- NoteBorderThickness
- NoteShadowing
- NoteTextAlignment
メモスタイル一覧
BackgroundColor | Noteの色を変更 |
---|---|
NoteBackgroundColor PapayaWhip |
|
BorderColor | Noteの枠線の入を変更 |
NoteBorderColor red |
|
NoteBorderThickness | Noteの枠線お太さを変更 |
NoteBorderThickness 5 |
|
Shadowing | Noteの影の有無 |
NoteShadowing true |
|
TextAlignment | Noteの文字の配置 動いてない?と公式が言ってる |
NoteTextAlignment left |
アクティビティ図 ( Activity
)
- ActivityBackgroundColor
- ActivityBarColor
- ActivityBorderColor
- ActivityBorderThickness
- ActivityEndColor
- ActivityStartColor
- activityDiamondBackgroundColor
- activityDiamondBorderColor
- activityDiamondFontColor
- activityDiamondFontStyle
アクティビティ図スタイル一覧
BackgroundColor | ノードの背景色を変更 |
---|---|
ActivityBackgroundColor lightCyan |
|
BarColor | フォークノード・ジョインノードの色を指定 |
ActivityBarColor red |
|
BorderColor | ノードの枠線の色を変更 |
ActivityBorderColor red |
|
BorderThickness | ノードの枠線の太さ |
ActivityBorderThickness 5 |
|
EndColor | 最終ノードの色を変更 |
ActivityEndColor Fuschia |
|
StartColor | 初期ノードの色を変更 |
ActivityStartColor aqua |
|
DiamondBackgroundColor | ディメンジョン・マージノードの背景色を変更 |
activityDiamondBackgroundColor lawnGreen 以下、Camel-caseに注意 |
|
DiamondBorderColor | ディメンジョン・マージノードの枠線の色を変更 |
activityDiamondBorderColor red |
|
Diamond<HOGEHOGE> | ディメンジョン・マージノード内のフォントの設定activityDiamond をクラス名として共通指定と同様 |
ユースケース図 ( Usecase
)
- UsecaseBackgroundColor
- UsecaseBarColor
- UsecaseBorderColor
- UsecaseBorderThickness
- UsecaseStereotypeFontName
- UsecaseStereotypeFontColor
- UsecaseStereotypeFontSize
- UsecaseStereotypeFontStyle
ユースケースのスタイル一覧
BackgroundColor | ユースケースの背景色を変更 |
---|---|
UsecaseBackgroundColor GreenYellow |
|
BarColor | ユースケースの枠線の色を指定 |
UsecaseBorderColor red |
|
BorderColor | ユースケースの枠線の太さを変更 |
UsecaseBorderThickness 5 |
|
StereotypeFont<HOGEHOGE> | Usecase Stereotypeのフォントの設定activityDiamond をクラス名として共通指定と同様 |
特殊コマンド群
デフォルト ( Default
)
すべてのグラフに反映させるというとても便利なやつ
- MonospacedFontName
- TextAlignment
一覧
MonospacedFontName | 指定されていないすべてのフォント名を指定する |
---|---|
DefaultMonospacedFontName Papyrus |
|
TextAlignment | 指定されていないすべての敵スノの配置を指定するright 右側に配置するとクラッシュするらしい |
DefaultTextAlignment left |
モノクロ ( Monochrome
)
図をモノクロに変える
Monochrome true |
Participant幅 ( ParticipantPadding
)
図のPaddingを指定
ParticipantPadding 200 |
影 ( Shadowing
)
図に影をつけるか否かを指定
Shadowing ture |
Shadowing false |
おわりに
ここまでガリガリ書き連ねてみましたが、PlantUMLのSkinパラメーターはまだまだあります。
今回はよく使う中でも、公式でサンプル画像があるものを中心にご紹介しました。
公式は参考のところに入れておきますが、現状残念ながら下記画像の通り英語版しかありません。
ただ、ページタイトルが日本語になっているので、用意する気はあるっぽいです。 しらんけど。
今回はStyleを中心にご紹介しましたが、次回、次次回と引き続きPlantUMLに関してまとていきます。
ではまた次回。
お知らせ
下記イベントで登壇することになりました。
- Vue.js
- Plotly.js
- Atomic Design
に興味のある方はぜひイベント申し込んでみてください!!
abeja-innovation-meetup.connpass.com
参考
- Ashelye's PlantUML Doc -All Skin Parameters- (最終閲覧: 2019-10-22)