持ち運べる SVG のシンボル

安全な Ganter のバインドと型付きの接続点を持つ、静的な SVG のシンボルを作り、共有します。

Markdown で表示

Ganter のシンボルは、絵と実時間のデータを分けたままにします。絵はふつうの、静的な SVG です。値の対応づけと動きは、すべて Ganter Lab が持つので、取り込んだファイルがスクリプト、イベントの処理、埋め込まれた動きのコード、ネットワークの要求を走らせることはできません。このページは、その作り方の完全な手引きです。シンボルが何を宣言するのか、取り込みが何を受け付けて何を拒むのか、そしてシンボルがステーションの間をどう行き来するのかを述べます。

シンボルは、その絵の上に 3 つのものを宣言します。

  • 可変部:名前の付いた入力(塗り、輪郭、動き、文字、表示と非表示)で、置かれたダッシュボードの実体が、あとで Logic のアドレスか決まった値から与えます。
  • 接続点:外周にある型付きのつなぎ目で、これによってダッシュボードは、シンボルどうしの間に配管、ダクト、電線、軸を通せます。
  • 提案:任意で、ほかのシンボルとの組み合わせを、姿勢まではっきり決めて記録したものです。

システムシンボルと自分のシンボル

カタログには 2 つの出どころがあり、シンボルが並ぶところではどこでも絞り込めます。

出どころ 参照 何であるか
システム system:<stable-key> アプリに同梱される作り付けのライブラリです。中を見ることも書き出すこともできますが、その場で編集することは決してできません。
自分のもの user:<guid> 自分で作った、取り込んだ、複製したシンボルです。編集も削除もできます。

システムシンボルはどれも「自分のシンボル」に複製を差し出します。複製は、その時点で固定された、自分が持つ独立した素材です(絵、表示範囲、収め方、大きさ、可変部、型の設定、接続点、提案が一緒に写されます)。ですから、あとでアプリが更新されて元のものが変わっても、選んだときのまま働き続けます。ユーザーのシンボルを削除するときは確認を求めますし、それをまだ参照しているダッシュボードは、壊れるのではなく代わりの印を見せます。

シンボルの作り方

  • ファイルを取り込むLogic > 素材 > シンボル > シンボルを取り込むは、ふつうの .svg か、丸ごとの .ganter-symbol.json のパッケージを受け付けます。取り込みは必ず新しい素材を、自分の素性とともに作ります。既存のシンボルを上書きすることは決してありませんし、名前がぶつかったときは失敗するのではなく接尾辞(「 2」、「 3」…)で解決します。ファイルの選択は、バイトを 1 つも読む前に 1 MB を超えるファイルを拒否します。ふつうの SVG を取り込んだあと、アプリは安全でない要素をいくつ取り除いたかを、あれば伝えます。
  • アプリの中で作る新しいユーザーシンボルが、名前、SVG のマークアップ、ダッシュボードでの配置(収め方と最初の大きさ)、そして可変部のための編集画面を開きます。シンボルができたあとは、正しい変更が自動で保存されます。接続点の位置は、意図してアプリでは編集できません。型を持つ接続点はパッケージからしか与えられませんし、パッケージが定めた接続点は、そのあとの編集を通じて読み取り専用のまま保たれます。
  • AI に頼む:2 つの道が、まったく同じ決まりを共有します。内蔵の MCP のエンドポイントでは、symbol_validate のツールが取り込みを試しに走らせ、symbol_import が新しい素材として保存します。どちらも、その説明に決まりの全体を運びます。アプリに手の届かない外部のチャットには、シンボルのパネルのチャット用の指示をコピーが、単体で完結した指示を写します。返ってきた SVG かパッケージをファイルとして保存し、ここで取り込んでください。

その周りにある素材のワークスペースについては、Logic を見てください。

ふつうの SVG を用意する

バインドしたい部分にはすべて、変わらない SVG の id を付けてください。取り込んだあと、その id が可変部の対象の選択に出ます。id と可変部の名前は、1 つの文法を共有します。英字か _ で始まり、そのあとは英字、数字、_.:- が続き、最大 128 文字です。

任意の data-ganter-* の属性が、シンボルが持てる唯一の Ganter 固有のマークアップです。

属性 付ける先 何を宣言するか
data-ganter-pivot="x y" バインドできる任意の要素 回転、拡大縮小、回り続ける可変部のための、正確な中心(表示範囲の座標)です。この 3 つの種類の対象の要素には必須です。
data-ganter-spin-ratio 回っている要素の子 目に見える子の回転体の、相対的な速さです。有限で 0 でなく、大きさは最大 100 で、負なら逆に回ります。その要素が自分の中心も宣言していなければ取り除かれます。
data-ganter-role 任意の要素 作成の道具のための、変わらない意味の役割です。情報だけのものです。
data-ganter-fit-width <text> / <tspan> Text の可変部のための、望んで入れる幅の制限です。結び付いた文字がこの表示範囲の単位より広く測れたとき、文字の大きさが収まるまで縮みます。
data-ganter-fit-min-font-size <text> / <tspan> 収めるために縮められる、いちばん小さい文字の大きさです。それより小さくなるときは、要素は代わりの文字を見せ、完全な値は読み上げの名前とツールチップに残ります。
data-ganter-fit-fallback <text> / <tspan> いちばん小さい文字の大きさでも値が収まらないときに見せる文字です。

接続点は SVG の中にはありませんし、SVG の要素の id を対象にもしません。data-ganter-portdata-ganter-port-* という名前の属性は、この形式の一部ではありません。ふつうの SVG の取り込みはそれらを取り除きますし、それを含む厳格なパッケージは拒否されます。

ふつうの SVG の取り込みは、必ず正しい見た目だけのシンボルになります。接続点 0 件、可変部 0 件です。検査は、役割、型、外向きの向き、内部の道すじが宣言されていないので、つなげる接続点がないと伝えます。Ganter が、ファイルの名前、分類、絵からそれらを推し量ることはありませんし、内部の接続点や道すじの編集画面を開くこともありません。

無害化が受け付けるもの

同じ SVG の方針が、どの道(ファイルの取り込み、アプリの中の編集画面、MCP、パッケージ)にも当てはまります。それは意図して、SVG より小さいものです。

  • 残すもの:動きのない図形と構造です。svggdefssymbolusepathrectcircleellipselinepolylinepolygontexttspantitledescclipPathmasklinearGradientradialGradientstoppatternmarker と、その見た目の属性(塗り、輪郭、不透明度、変形、装飾)、そして ARIA のラベルです。
  • 取り除くか拒否するもの<script><style><foreignObject>、イベントの処理、埋め込まれた動き、そして外部と data:file:http(s) の URL です。残るのは、内部の url(#id)href="#id" の参照だけです。
  • 上限:マークアップは最大 512 KB4096 要素です。

安全な塗りは、16 進数の色、CSS の名前付きの色、rgb()rgba()hsl()hsla()、そしてアプリのテーマの語 var(--color-<name>)(たとえば var(--color-success)var(--color-symbol-off))です。テーマの語は、1 つの絵が明るい地と暗い地の両方に合わせるためのものです。テーマごとに 2 つ用意するのではなく、語を参照する 1 つの絵を配ってください。

違反の扱われ方は、道によって変わります。ふつうの SVG は直されます(安全でない要素は取り除かれ、取り除いたそれぞれが警告として伝えられます)。パッケージは厳格で、黙って直されるのではなく、最初の違反を名指しして拒否されます。

持ち運べるパッケージ v2

シンボルを書き出すと、.ganter-symbol.json のファイルができます。外枠の項目はどれも必須です。決まりの 3 つの配列は空でもかまいませんが、なければいけません。

項目 要件
$schema ちょうど https://ganterlab.com/schemas/ganter-symbol-v2.schema.json であること。
format ちょうど ganter-symbol であること。
version ちょうど 2 であること。版 1 のパッケージは、古い読み取りに回されるのではなく拒否されます。
name 表示の名前です。取り込みがこれを上書きすることもありますし、ぶつかったときは自動で接尾辞が付きます。
svg 無害化した静的な SVG で、その根の要素が viewBox の項目と同じ viewBox を持つこと。
viewBox minX minY width height。有限な 4 つの数値で、幅と高さは正であること。
fit containstretchstretch-xstretch-y のいずれか。
footprint { "width": 1..24, "height": 1..12 }。推奨するダッシュボードのます目です。
slots 可変部の宣言(下記)の配列です。
typeConfigurations 共有する接続点の型の選択(下記)の配列です。
terminals 最大 16 件の、そろった接続点(下記)の配列です。
suggestions 順序を持つ、決めた組み合わせ(下記)の配列です。

公開されている Ganter symbol v2 の JSON スキーマが、運ぶための外枠を検証します。そのあと取り込みが、JSON スキーマでは表せない意味の検査を行います。SVG の対象があるかどうか、内部の道すじの形、提案の整合です。パッケージはどの面でも厳格です。安全でないマークアップ、知らない項目、配列の中の null の要素、そして以前の ports[]anchors[]profileconnectionStyle の決まりは、直されるのではなく拒否されます。

パッケージには、ステーションのアドレス、ダッシュボードのバインド、実体ごとの型の選択、データベースの GUID、利用者の素性は、決して入りません。Logic のアドレスを持つ可変部は、そもそも書き出せません。そのアドレスは、置かれた実体のものであって、使い回すシンボルのものではないからです。

大きさ、表示範囲、収め方

表示範囲は、そのシンボルの本来の座標の空間です。接続点と内部の道すじはその中で宣言されますし、SVG の根自身の viewBox とちょうど一致しなければなりません。2 つの表示範囲が食い違うパッケージは拒否されます。正方形でない表示範囲にも完全に対応しているので、長いコンベヤーが正方形の中に住む必要はありません。

収め方は、操作者が描いたダッシュボードの長方形を、絵がどう使うかを述べます。

収め方 振る舞い
contain 縦横の比を保ちます。絵は、ます目の長方形の中に余白を作って収まります。既定です。
stretch 縦横の両方向で長方形を埋めます。必要なら形がゆがみます。
stretch-x 横に伸ばし、縦は本来の比を保ちます。
stretch-y 縦に伸ばし、横は本来の比を保ちます。

大きさは、そのシンボルを最初に置いたときの、ダッシュボードのます目での大きさです。幅は 1 から 24、高さは 1 から 12 です(編集画面の既定は 4 × 4)。これは提案であって、決まりではありません。操作者は、そのあと自由に大きさを変えられます。

取り込みの大きさは、別々の 2 つの関門が抑えます。ファイルの選択は、読む前に 1 MB を超えるものを拒否しますし、無害化は 512 KB4096 要素を超えるマークアップを拒否します。

可変部:バインドの面

可変部は、入力を 1 つ宣言します。どの要素を動かすのか、それに何をするのか、そして入力の値が出力にどう対応するのかです。置かれたダッシュボードの実体が、あとで可変部ごとに信号のもと(Logic のアドレスか、決まった値)を選びます。シンボル自身が、そのもとを保存することはありません。

可変部はそれぞれ、次のものを持ちます。

項目 意味
name ダッシュボードを作る人に見せる引数の名前です。上の識別子の文法に従い、そのシンボルの可変部の中で重ならないこと。
elementId 存在する SVG の要素の id です。1 つの要素が受け取れる可変部は、チャネル 1 つにつき 1 つまでなので、2 つの可変部が同じ要素の塗りを取り合うことはありません。
kind 下の 13 の種類のいずれかです。
inMininMax 入力の範囲です。outMinoutMax に対応づける 2 つの値です。有限な数値で、連続する種類が使い、fillstroke では境目の中間の値として使います。
outMinoutMax その種類の単位での出力の範囲です(度、表示範囲の単位、0..1、1 秒あたりの度)。有限な数値です。
outMinSecondaryoutMaxSecondary 任意の 2 つ目の出力の軸で、translatescale にだけ使います。1 つ目の出力が X、2 つ目が Y です。両方あるか、両方ないかのどちらかです。
onColoroffColor fillstroke の安全な塗りです(境目の 2 つの状態)。fillColorstrokeColor では、onColor が検査のプレビューの色です。

13 の可変部の種類です。

種類 何を動かすか 備考
rotate 要素を回します。入力は度に線形に対応します。 対象は data-ganter-pivot を宣言していること。
opacity 要素の不透明度です。入力は 0..1 に対応します。
fill 入力の範囲の中間より下では offColor、そこ以上では onColor で塗りを描きます。Bool の入力は、そのまま切り替わります。 塗れる図形(<line> は除く)が対象です。
visible 値が真かどうかで、要素を見せるか隠します。
text 要素の文字の内容を、書式を当てた値で置き換えます。 <text><tspan> だけが対象です。幅を抑えた表示にするには、data-ganter-fit-* の属性と組み合わせてください。
translate 表示範囲の単位で要素を動かします。1 つ目の出力が X、任意の 2 つ目が Y です。
scale 要素を拡大縮小します。1 つ目の出力が X、2 つ目が Y です(なければ縦横同じです)。 対象は data-ganter-pivot を宣言していること。
stroke fill と同じ境目の規則で輪郭を描きます。
spin 時間に沿って回り続けます。入力は 1 秒あたりの度の角速度に対応します。data-ganter-spin-ratio を持つ子は、宣言した比で一緒に回ります。 対象は data-ganter-pivot を宣言していること。動きはこちら側で刻むので、オペレーティングシステムの動きの設定には左右されません。
spinEnabled 同じ要素の spin の可変部を、要素を隠さずに止めたり再開したりします。 同じ要素を対象にする spin の可変部が要ります。
fillColor 結び付いた色の値(Color の素材、Color の変数、安全な CSS の色)から、塗りを直接決めます。
strokeColor 結び付いた色の値から、輪郭を直接決めます。
strokeWidth 輪郭の太さを、SVG の利用者の単位で 0.5 から 32 まで直接決めます。単位の接尾辞や CSS は受け付けません。 正しくない、解決しない、品質の悪い入力は、書かれていた stroke-width に戻します。入力を戻す、再配置、破棄でも同じです。

この可変部は絵の見た目を決めるもので、ダッシュボードの接続線の経路を決めることは決してありません。経路の色と幅は、接続線の種類ごとに全体共通です。

バインドは誰のものか

シンボルが宣言するのは引数と、選べる型の候補であって、実時間の信号のもとでも、ある実体の選択でもありません。シンボルのコンポーネントを置いたあと、操作者が可変部を Logic のアドレスか決まった値に対応づけ、その実体で選べる接続線の型をそれぞれ選びます。その選択はステーションの中にとどまり、使い回すシンボルと一緒に書き出されることはありません。対応づけていない可変部は、そのままです。要素は、書かれたとおりの見た目を保ちます。

全体共通の位置と接続線の型

どの接続点も、外周に決められた 16 の位置のカタログから 1 つを参照します。パッケージが保存するのは anchorId だけで、座標を繰り返すことも上書きすることもありません。位置は、表示範囲に対する正規化した割合で次のとおりです。

  • 上:top-left(0, 0)、top-25(0.25, 0)、top-50(0.5, 0)、top-75(0.75, 0)、top-right(1, 0)。
  • 右:right-25(1, 0.25)、right-50(1, 0.5)、right-75(1, 0.75)。
  • 下、時計回りに:bottom-right(1, 1)、bottom-75(0.75, 1)、bottom-50(0.5, 1)、bottom-25(0.25, 1)、bottom-left(0, 1)。
  • 左、時計回りに続けて:left-75(0, 0.75)、left-50(0, 0.5)、left-25(0, 0.25)。

これは外周の位置であって、5×5 のます目ではありません。シンボルが位置を足すことも、自分の位置の座標を保存することもできません。

全体共通の 8 つの接続線の型は、liquidgasair-ductelectricalsignalnetworkmaterialmechanical-shaft です。それぞれの型に結び付く色と見た目の線の幅は、Logic > 素材 > 接続線の種類で設定します。シンボルと接続線は変わらない型の id を保つので、全体で 1 つ変えれば、それを使うすべての経路が描き直されます。パッケージが色や幅を写すことはありませんし、経路に小、標準、大といった違いもありません。

2 つの端点は、同じ型に解決したときに、決まった接続になります。接続点の役割は、作ることと見直すことの助けにはなりますが、それ自体でつなぎ方を禁じるものではありません。

共有する型の選択

複数の媒体で働けるシンボルは、絵を 2 つに増やすのではなく、共有する型の設定を宣言します。

{
  "id": "process-type",
  "name": "Process type",
  "allowedTypes": ["liquid", "gas"],
  "defaultType": "liquid"
}

id は変わらない鍵です。小文字の英字と数字を、1 つずつのダッシュでつなぎ、始まりと終わりは英数字です(大文字は拒否されます)。allowedTypes は空でなく、全体共通の型の id が重ならずに並びます。defaultType はその中になければなりません。name は必須です。process-type を参照するすべての接続点は、置かれたダッシュボードの実体で行った 1 つの選択に従います。1 つの定義が、たとえばプロセスの媒体と排気の媒体のように、独立した設定をいくつも持つこともできますし、ほかの接続点は固定のままにできます。

そろった接続点

つなげる接続点はそれぞれ、全体共通の位置を 1 つ、役割を 1 つ、固定された型 1 つまたは共有する設定 1 つ、元の向きでの外向きの向き、そして内部の到達の道すじを宣言します。

{
  "anchorId": "left-50",
  "role": "input",
  "typeConfiguration": "process-type",
  "direction": "west",
  "internalPath": [
    { "x": 18, "y": 50 },
    { "x": 36, "y": 50 },
    { "x": 48, "y": 62 }
  ]
}

規則は次のとおりで、どれも取り込みのときに守らせます。

  • 接続点は最大 16 件で、位置の id はそれぞれ 1 度までです。
  • roleinputoutputbidirectional のいずれか。directionnortheastsouthwest のいずれかです。
  • type(全体共通の接続線の型)か typeConfiguration(宣言した設定の id)のちょうど 1 つを持つこと。両方でも、どちらもなしでもいけません。
  • 全体共通の位置を SVG の本来の表示範囲に直したものが、internalPath の暗黙の始点です。最初の点としてそれを繰り返さないでください。座標は正規化した割合ではなく、表示範囲の絶対の値で、道すじには少なくとも 1 つの点があります。
  • どの線分も表示範囲の中にとどまり、長さが 0 でなく、水平、垂直、あるいはちょうど 45° であること。続く線分どうしの曲がりは、最大 90° です。
  • 接続点があるなら、SVG に表示範囲があること。

ダッシュボードは、内部の道すじを設備の絵の下に描き、大きさの変更、90° ずつの回転、反転に合わせて変形させ、全体共通の接続線の型の見た目の幅を、シンボルに合わせて拡大縮小せずに保ちます。ですから、片方の中からもう片方の中まで、1 本の線がつながって走ります。

接続点は、全部そろっているか、まったくないかのどちらかです。中途半端な接続点を持つ厳格なパッケージは正しくありません。見た目だけのパッケージは、代わりに空の terminals の配列を使います。足りないところを埋めるために、何かが推し量られることは決してありません。

順序を持つ提案

提案は、相手の正確な姿勢まで含めて、意図した組み合わせを記録します。

{
  "sourceAnchorId": "right-75",
  "targetSymbol": "system:capping-station",
  "targetAnchorId": "left-75",
  "targetRotationDegrees": 0,
  "targetFlipHorizontal": false,
  "targetFlipVertical": false,
  "connectionType": "material"
}

検証はこうです。sourceAnchorId は、このシンボル自身の接続点のどれかでなければなりません。targetSymbol は出どころで修飾した参照でなければならず、持ち運べるパッケージでは system:<stable-key> だけが使えます(利用者の GUID は、それを持つステーションの中でしか意味を持たないからです)。そして、その参照はシステムのカタログに存在し、targetAnchorId に接続点を持つシンボルを名指ししていなければなりません。回転は 090180270 のいずれかで、2 つの反転の印はどちらも必須です。提案はそれぞれ重ならないこと。connectionType を省けるのは、両端の固定された同じ型が、その場面を紛れなく決めるときだけです。どちらかの端が選べるものであれば必須になりますし、そのときは両端で許されている型でなければなりません。

提案には向きがあり、配列の順が優先順位になりますが、ふつうのダッシュボードの接続線に対する許可の一覧では決してありません。suggestions の配列が空のときは、検査は、カタログの相手を勝手に作り出すのではなく、提案された組み合わせがないと伝えます。

取り込みが拒否するもの

失敗した取り込みを、当てずっぽうではなく読み解けるように、拒否の一覧を短くまとめます。ふつうの SVG では、最初のまとまりだけが当てはまり、その中でも取り込みを拒むのは、大きさの上限、整形式でない XML、<svg> の根がないことだけです。許されていないマークアップは、警告を添えて直されます。パッケージでは、下のすべてが取り消しのきかない拒否です。

  • 1 MB を超えるファイル、512 KB を超えるマークアップ、4096 要素を超えるもの。
  • 整形式でない XML、あるいは根が無害化した <svg> でないもの。
  • パッケージでは、許可の一覧が取り除かなければならなかったであろうマークアップ(スクリプト、イベントの処理、外部の参照、許されていない要素や属性)。
  • 有限な 4 つの数値で幅と高さが正、という形でない viewBox、SVG の根のものと違う viewBox、そしてパッケージで根の表示範囲がまったくないもの。

外枠

  • v2 の決まりと違うスキーマ、形式、版。どこかにある知らない項目。namefitfootprint、3 つの配列のどれかが欠けていること。配列の中の null の要素。
  • 4 つの収め方から外れた fit。1〜24 × 1〜12 から外れた大きさ。

可変部

  • 識別子の文法から外れた名前や要素の id。重なった可変部の名前。SVG が持っていない対象の id。対象の要素が受け取れない種類(文字でない要素への text、<line> への fill)。
  • 対象が有限な data-ganter-pivot を持たない rotatespinscale の可変部。同じ要素の spin の可変部がない spinEnabled の可変部。
  • 1 つの要素の同じチャネルに 2 つの可変部があること。種類はそれぞれ自分のチャネルですが、fillfillColor は塗りのチャネルを、strokestrokeColor は輪郭のチャネルを共有するので、1 つの要素が塗りを 2 つ取れないのは、回転を 2 つ取れないのと同じです。
  • 有限でない範囲の数値。片方の端しかない 2 つ目の出力や、translatescale 以外の種類での 2 つ目の出力。安全でない塗り。Logic のアドレスを持つ可変部。

接続

  • 16 件を超える接続点。繰り返された、あるいは知らない位置の id。typetypeConfiguration の両方を持つ、あるいはどちらも持たない接続点。知らない型や設定の id。正しくない内部の道すじ(表示範囲の外、長さ 0 や角度の合わない線分、90° を超える曲がり)。
  • 正しくない id、名前がない、許す型が重なっているか知らないもの、自分の一覧の外にある既定を持つ、型の設定。
  • もとの接続点が存在しない、相手が名指しした接続点を持つシステムシンボルでない、姿勢が 90° ずつの回転でない、あるいは接続線の型が両端で受け入れられない、という提案。

MCP のエンドポイントsymbol_validate は、まさにこの取り込みを試しに走らせ、何も保存せずに、すべてのエラー、警告、注意を伝えます。

パッケージにして配る

パッケージを書き出す(システムのシンボルにも自分のシンボルにも使えます)は、無害化した絵と決まりの全体を持つ <name>.ganter-symbol.json をダウンロードします。$schemaformatversionnamesvgviewBoxfitfootprintslots[]typeConfigurations[]terminals[]suggestions[] で、接続の 3 つの配列は空でもそこにあります。決して運ばれないものは、ステーションのアドレス、実体ごとの型の選択、データベースの素性、利用者の素性、そしてそのステーションの接続線の種類の色と幅です。

受け取る側のステーションでは、同じファイルがシンボルを取り込む(あるいは MCP の symbol_import)を通り、接続点ごと新しいユーザーのシンボルとして着きます。型の素性は変わらない id で、見た目は全体共通なので、取り込んだシンボルの経路は、受け取った側のステーション自身の接続線の種類の見た目にすぐ従います。