Skip to content

フレーム

フレームを使うと、ひとつの図に複数のマージビューを同居 させられ ます。icon / connector / region / notedoc { … } の設定 ブロックに frames セレクタを付けておくと、レンダリング時にフレーム 番号を指定するだけで、そのフレームに該当するすべての宣言を 1 枚の フラットな図にまとめて描画します。

フレームは「タイムステップ」ではなく タグ として捉えてください。 フレーム 2 は「時刻 t=2 のキーフレーム」ではなく「2 というタグが 付いたスライス(+タグなしのすべて)」です。小さな違いですが重要 で、描画パイプライン自体は無変更のまま、「どの宣言をパイプライン に流すか」だけをフレームが決めている、という構造になっています。

3 フレームのストーリー

Frame 1 / 1–3
frame-basic (SVG, frame 1)

図にホバーすると ◀ / ▶ ボタンが現れ、3 フレームを行き来できます。 右側のソースは常に同じで、コンポーネントが選ばれたフレームのマージ 結果を再描画しているだけです。

左から右に読むと:

  • フレーム 1(ベースレイヤーのみ)— user / api / db の 3 アイコンが静かに並ぶだけ。コネクタもノートも無し。
  • フレーム 2 では色替えされた apiuser → api のログイン コネクタ、API ノードを指す "Stateless" ノートが追加される。
  • フレーム 3 では user アイコンが塗りつぶし/アクセント版に 差し替わり、api → db のクエリコネクタと解説ノートが追加される。

どのフレームでも共通のベースノードはそのまま残り、[2] / [3] タグで追加情報を重ねていく形です。

構文

[frame-spec]行頭(コマンド語の前)または インライン (通常の引数として)どちらにも書けます。意味は同じで、同じ文の 両方に書くとパースエラーになります。

gg
icon :user @A1 tabler/user "User"               # すべてのフレーム — ベースレイヤー

# 行頭形式 — 関連する複数の文で frame タグを列揃えしたいとき推奨:
[2] icon :user tabler/user "User login"
[2] user --> api "login"
[2] note @B1 (api) "Stateless,\nauto-scaled"

# インライン形式 — 単発でタグを付け加えたいときに:
icon [3-5] :user tabler/filled/user "Session"
region [3] @B1:B2 "spotlight"
note @A2 (user) "explained from f=2" [2-]

# doc 設定の上書き — こちらも行頭 / インラインどちらでも:
[2] doc { theme: { primary: '#ff0000' } }
doc [3-] { theme: { primary: '#0d9488' } }

行頭形式は、あるフレーム番号の追加宣言がいくつも並んだときに特に 読みやすくなります([2] が列 1 で揃うので、フレームごとの構造が 一目で把握できます)。

TS API も同等 — frames? は各 def に対して任意に指定できます:

ts
import type { DiagramDef } from 'gridgram'

export const def: DiagramDef = {
  nodes: [
    { id: 'user', pos: 'A1', src: t('user'), label: 'User' },

    // 単一フレーム(数値形式)
    { id: 'user', src: t('user'), label: 'User login', frames: 2 },

    // リスト形式 — 個別の 2 フレーム
    { id: 'user', src: t('user'), label: 'Again', frames: [4, 6] },

    // 範囲 — ネストしたタプル
    { id: 'user', src: tf('user'), label: 'Session', frames: [[3, 5]] },

    // 無限範囲
    { id: 'late', pos: 'B1', src: t('bell'), frames: [[5, Infinity]] },
  ],
}

frame-spec の文法早見表:

形式意味
(省略)すべてのフレームに存在(ベース)
[2] / 2単一フレーム
[2, 3, 5]フレーム 2・3・5(3 つの単独)
[[2, 5]] / [2-5]範囲 2..5 閉区間
[5-] / [[5, ∞]]フレーム 5 以降すべて
[2, 4-6, 9-]上記の混在

マージ規則

frame=N が指定されたとき、gridgram はすべての宣言について次の 処理を順に行います:

  1. フィルタframes が N に該当するか、frames フィールド のない宣言だけを残す。それ以外は当該フレームから除外。
  2. id でマージ — 残った宣言のうち id を共有するものは、宣言 順に deep-merge(フィールド単位で後勝ち)。これにより icon [2] :user label="login" のように、possrc を 再宣言せずにラベルだけ上書きできる。
  3. 匿名宣言はそのまま — note や region は id を持たないので、 frames が該当すれば独立したエントリとして追加される。

doc [N] { … } ブロックは、マッチすればベース設定(theme・columns など)へ deep-merge されます。たとえば「フレーム 2 だけプライマリ 色を差し替える」といった用途に使えます。

オートポジションは フレームごとに再評価 されます。そのフレーム での宣言順で再計算されるので、フレーム 3 にだけ現れるノードは そのフレーム内で空いているセルに割り当てられ、フレーム 2 で省略 されたノードはそのフレーム内で詰めて配置されます。

フレーム対応の整合性チェック

フレームに依存するチェック(未解決参照・セル重複・リージョンの 4 連結性)は フレーム単位 で実行されます。パーサはドキュメント に登場するすべてのフレーム番号を走査するので、たとえばフレーム 3 でのみ発生する衝突もパース時に検出され、(frame 3) の注釈付きで 報告されます:

Duplicate cell B2: icon "a" and icon "b" (frame 3)

同一 id が エラーとなるのは両方の宣言に frames が無い場合のみ です。片方にでも [N] が付いていれば、マージ扱いとして許容され ます。

特定フレームの描画

bash
gg diagram.gg --frame 2 -o diagram-f2.svg

…TS API でも同様:

ts
import { renderDiagram } from 'gridgram'
const { svg } = renderDiagram(def, { frame: 2 })

frame を省略すると gridgram は フレーム 1 を描画します。 これにより、フレームを知らないツールでもフレームを使った図を そのまま描画できます。

どんなときにフレームが便利か

同じアーキテクチャ図を、書き直さずに複数スライドや複数段落に渡って ナレーションしたいときに真価を発揮します:

  • フローのステップ解説(ログイン → セッション → ログアウト)
  • インシデントの発生前・発生中・復旧後
  • 同じ図の異なるサブシステムをハイライト
  • ノート群を丸ごと差し替えて、同じ図に別の注釈を載せる

フレームは レイアウトアニメーションの仕組みではありません — gridgram はフレーム間の補間を行いません。必要な場合は各フレームを 書き出してお好みのアニメーションツールへ渡してください。

このページを編集Last updated: