@yanqirenshi/d3.classes
v0.13.0
Published
UML Class Diagram visualization library using d3.js
Maintainers
Readme
CLASS.js
d3.jsを使用してUMLクラス図を描画するTypeScriptライブラリです。
インストール
npm install使い方
基本的な使い方
import { ClassDiagram } from 'class.js';
const diagram = new ClassDiagram('#container', {
width: 800,
height: 600
});
// クラスを追加
const userClass = diagram.addClass({
name: 'User',
attributes: [
{ name: 'id', type: 'number', visibility: 'private' },
{ name: 'name', type: 'string', visibility: 'public' }
],
methods: [
{ name: 'getName', returnType: 'string', visibility: 'public' }
],
x: 100,
y: 100
});
// 関係を追加
diagram.addRelationship({
type: 'inheritance', // association, inheritance, aggregation, composition, dependency
from: { x: 200, y: 200 },
to: { x: 200, y: 100 }
});
diagram.render();JSONデータから読み込み
import { ClassDiagram, DiagramInput } from 'class.js';
const data: DiagramInput = {
classes: [
{
name: 'Animal',
stereotype: 'abstract',
attributes: [{ name: 'name', type: 'string', visibility: 'protected' }],
methods: [{ name: 'speak', returnType: 'void', visibility: 'public' }],
x: 300,
y: 50
},
{
name: 'Dog',
attributes: [{ name: 'breed', type: 'string', visibility: 'private' }],
methods: [{ name: 'speak', returnType: 'void', visibility: 'public' }],
x: 300,
y: 200
}
],
relationships: [
{
type: 'inheritance',
from: { x: 400, y: 200 },
to: { x: 400, y: 130 }
}
]
};
const diagram = new ClassDiagram('#container');
diagram.loadFromData(data).render();識別子と接続先変更(v0.6.0+)
クラス・関係線とも任意の id を指定できます(省略時は追加順に
class-N / rel-N が振られる)。識別子はレンダリングされる
g.class-box / g.relationship の data-id 属性にも反映されるため、
ホスト側で「クリックされた要素がどれか」を DOM から特定できます。
diagram.addClass({ id: 'SessionLine', name: ..., position: { x: 0, y: 0 } });
diagram.addClass({ id: 'UserLine', name: ..., position: { x: 300, y: 0 } });
diagram.addRelationship({
id: 'rel-1',
type: 'association',
from: { classId: 'SessionLine', point: 'right' },
to: { classId: 'UserLine', point: 'left' },
});
diagram.render();
// id で取得して接続先(クラス・接続辺)を付け替える(即再描画)
const rel = diagram.getRelationship('rel-1');
rel?.setConnection(
{ classId: 'SessionLine', point: 'right' },
{ classId: 'UserLine', point: 'top' },
);ClassDiagram.getClass(id)/ClassDiagram.getRelationship(id)で取得Relationship.setConnection(from, to)は座標指定({ x, y })も可Relationship.id/.from/.toで現在の状態を参照できる- 重複 id はエラー(黙って上書きしない)。自動採番は明示 id と衝突する番号をスキップする
属性の型表示とラベル属性(v0.7.0+)
- 属性の型が未指定(文字列指定・
type省略)なら「: 型」は表示されません (以前のように: anyへ補完しません)。"user"→+ user kind: 'label'を指定すると可視性記号・型とも表示せず名前だけを描画します (enum のバリアント列挙などのラベル用途)。
{
name: name('SessionLine'),
stereotype: 'enumeration',
attributes: [
'user', // → 「+ user」
{ name: name('assistant'), kind: 'label' }, // → 「assistant」
],
position: { x: 0, y: 0 },
}角丸とヘッダの配色(v0.10.0+)
クラス box は既定で角丸(半径 4px)になります。radius: 0 を指定すると
従来どおりの直角に戻せます。
ヘッダ(クラス名の行)には背景色と文字色を指定できます。
background / font は @yanqirenshi/types の共有型(Background / Font)です。
{
name: name('ユーザー'),
stereotype: 'entity',
position: { x: 100, y: 100 },
radius: 8, // 角丸半径(px)。既定 4、0 で直角
header: {
background: { color: '#89c3eb' }, // 既定は塗りなし(本体と同色)
font: { color: '#ffffff' }, // 既定は黒
},
}| オプション | 既定 | 内容 |
|---|---|---|
| radius | 4 | 角丸半径(px)。0 で直角 |
| header.background.color | なし | ヘッダ背景色。未指定なら塗らない(本体の白のまま) |
| header.background.opacity | なし | ヘッダ背景の不透明度 |
| header.font.color | black | クラス名の文字色 |
| header.font.size | 14px | 指定時のみ上書き |
| header.font.weight | bold | 指定時のみ上書き |
header.font が効くのはクラス名だけです。
ステレオタイプは box の外に描かれるため対象外です(v0.11.0 で変更 — 下記)。
描画される要素は以下のとおりです。 ヘッダ背景は本体 rect の上・テキストの下に入ります。
rect.box-body— 本体(rxにradius)rect.box-header-bg— ヘッダ背景(rxにradius。上2隅が角丸)rect.box-header-bg-foot— 下2隅の丸みを直角で埋める帯(radius: 0のときは描かれない)
なお radius がヘッダ高(常に 30px)の半分 = 15 を超えると、ヘッダ背景の丸みは
SVG の仕様でその半分に頭打ちになり、本体の角丸のほうが大きくなります
(角の 1px 程度で背景が枠線からわずかにはみ出します)。
ヘッダに背景色を敷く場合、radius は 15 までを推奨します。
ステレオタイプの表示位置(v0.11.0+)
stereotype は box の外・上辺より上 に、中央揃え・斜体・12px・黒で描かれます
(v0.10.0 まではヘッダの1行目として box の中に描いていました)。
«abstract» ← box の外(ベースライン y: -6)
┌──────────────────┐
│ 動物 │ ← ヘッダ(クラス名の1行)
├──────────────────┤
│ # 名前 string │
└──────────────────┘- ヘッダは常に1行になったため、ステレオタイプを持つクラスの box 高さが 従来より 20px 縮みます。ステレオタイプの有無で高さは変わりません。
positionの意味は変わりません(これまでどおり box の左上)。 ステレオタイプは box の上にはみ出して描かれるだけなので、既存図のボックス位置と 接続点の幾何は一切変わりません。- 文字色は黒固定で、
header.fontは適用されません。box の外は背景がキャンバスなので、 ヘッダ用の白文字などをそのまま当てると読めなくなるためです。 - 要素は
text.box-stereotypeで、g.class-boxの中にあります (ドラッグすると box と一緒に動きます)。
注意: box の上辺に接続する関係線(point: 'top')は、真上から来るとステレオタイプの
文字と重なります。
幾何は変えていないので、重なる場合は接続辺を変えて回避してください
(例: point: 'left' / point: 90 など)。
説明(description)の保持(v0.12.0+)
クラス・属性・メソッドに description(文字列の配列。1行1要素)を持たせられます。
d3.classes は description を描画しません。 データとして保持するだけで、 box の見た目もレイアウト(高さ)も一切変わりません。 インスペクタなどでの表示は利用側の責務です。
diagram.addClass({
id: 'user',
name: name('User'),
description: ['利用者を表す。', '認証の主体。'],
attributes: [
{ name: name('id'), type: 'number', description: ['主キー。', '発行後は不変。'] },
],
methods: [
{ name: name('login'), returnType: 'boolean', description: ['認証する。'] },
],
position: { x: 0, y: 0 },
});ClassBox から属性・メソッドを辿って読めます。
const box = diagram.getClass('user');
box.description; // ['利用者を表す。', '認証の主体。']
box.attributes.map((a) => a.description); // [['主キー。', '発行後は不変。']]
box.methods.map((m) => m.description); // [['認証する。']]未指定は空配列 [] に正規化されます(undefined にはなりません)。
属性・メソッドの文字列ショートハンド(attributes: ['foo'])も [] です。
利用側は常に配列として扱えます。
クリックコールバックは無いので、要素の特定は従来どおり DOM 側で行います
(g.class-box の data-id を拾って getClass(id))。
name.description との違い(重要)
同じオブジェクトに description が2つ並びます。名前も似ていますが別物です。
| 場所 | 型 | 位置づけ |
|---|---|---|
| name.description | string | 共有型 Name(@yanqirenshi/types)のフィールド。名前についての補足。d3.classes では参照していません(描画も API も無し) |
| description | string[] | v0.12.0 で追加。要素そのものの説明。上記のとおり getter から読めます |
Name は全パッケージが使う共有型なので変更できません。
説明を持たせたいときはトップレベルの description を使ってください。
開発
# 開発サーバー起動
npm run dev
# ビルド
npm run build
# テスト
npm test
# 型チェック
npm run typecheck