@yanqirenshi/model.deployment 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +130 -2
- package/dist/check.d.ts +15 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +27 -0
- package/dist/cjs/check.js +32 -0
- package/dist/cjs/defaults.js +119 -0
- package/dist/cjs/fields.js +44 -0
- package/dist/cjs/index.js +46 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/patch.js +141 -0
- package/dist/cjs/schema.js +97 -0
- package/dist/cjs/types.js +7 -0
- package/dist/defaults.d.ts +61 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +111 -0
- package/dist/fields.d.ts +8 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +40 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/patch.d.ts +19 -0
- package/dist/patch.d.ts.map +1 -0
- package/dist/patch.js +130 -0
- package/dist/schema.d.ts +274 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +94 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/package.json +55 -5
- package/src/check.ts +33 -0
- package/src/defaults.ts +138 -0
- package/src/fields.ts +46 -0
- package/src/index.ts +28 -0
- package/src/patch.ts +158 -0
- package/src/schema.ts +100 -0
- package/src/types.ts +94 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// d3.deployment の入力データの JSON Schema(2020-12)。
|
|
3
|
+
//
|
|
4
|
+
// iHub の server/schemas/deployment/{nodes,edges}.schema.json を移したもの。
|
|
5
|
+
// 検査するのは、図の構造にかかわる項目(id・type・size・position・children・link、線の from / to)だけで、
|
|
6
|
+
// 見た目の項目(label・border・background・padding・description)は d3.deployment の入力の形のまま書けるよう
|
|
7
|
+
// additionalProperties を閉じていない(iHub 版は閉じていた)。
|
|
8
|
+
//
|
|
9
|
+
// x-id-start はスキーマの検証には使わない注釈(コレクションが空のときに最初に振る id)。
|
|
10
|
+
// Ajv で使うときは addKeyword({ keyword: 'x-id-start', schemaType: 'number' }) を足す。
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SCHEMAS = exports.EDGES_SCHEMA = exports.NODES_SCHEMA = void 0;
|
|
13
|
+
const defaults_js_1 = require("./defaults.js");
|
|
14
|
+
const ID = { type: ['integer', 'string'] };
|
|
15
|
+
const POINT = {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: { x: { type: 'number' }, y: { type: 'number' } },
|
|
18
|
+
required: ['x', 'y'],
|
|
19
|
+
};
|
|
20
|
+
exports.NODES_SCHEMA = {
|
|
21
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
22
|
+
title: 'システム構成図のノード',
|
|
23
|
+
description: 'd3.deployment に渡すノード。children に子のノードを入れ子で持つ。id は子のノードも含めて一意にする。position は親の中での位置で、ドラッグで動かすと書き換わる。link を付けると、ノードの左下にリンクを出す。見た目の項目 (label・padding・border・background・description) は d3.deployment の入力の形のまま書ける。',
|
|
24
|
+
'x-id-start': 1,
|
|
25
|
+
type: 'array',
|
|
26
|
+
items: { $ref: '#/$defs/node' },
|
|
27
|
+
$defs: {
|
|
28
|
+
node: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
id: ID,
|
|
32
|
+
type: { enum: [...defaults_js_1.NODE_TYPES] },
|
|
33
|
+
label: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: { text: { type: ['string', 'null'] } },
|
|
36
|
+
},
|
|
37
|
+
description: { type: ['string', 'null'] },
|
|
38
|
+
size: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: { w: { type: 'number', minimum: 0 }, h: { type: 'number', minimum: 0 } },
|
|
41
|
+
required: ['w', 'h'],
|
|
42
|
+
},
|
|
43
|
+
position: POINT,
|
|
44
|
+
link: {
|
|
45
|
+
type: ['object', 'null'],
|
|
46
|
+
properties: { url: { type: ['string', 'null'] } },
|
|
47
|
+
},
|
|
48
|
+
children: { type: 'array', items: { $ref: '#/$defs/node' } },
|
|
49
|
+
},
|
|
50
|
+
required: ['id'],
|
|
51
|
+
additionalProperties: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
exports.EDGES_SCHEMA = {
|
|
56
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
57
|
+
title: 'システム構成図の線',
|
|
58
|
+
description: 'ノードの間の線。from.id / to.id はノード (子を含む) の id。position は接続位置の角度 (0=真下・時計回り。省略すると 90=左)。stroke.marker は両端の矢印の有無 (既定: 終点だけ)。',
|
|
59
|
+
'x-id-start': 100,
|
|
60
|
+
type: 'array',
|
|
61
|
+
items: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
id: ID,
|
|
65
|
+
from: { $ref: '#/$defs/end' },
|
|
66
|
+
to: { $ref: '#/$defs/end' },
|
|
67
|
+
stroke: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
color: { type: 'string' },
|
|
71
|
+
width: { type: 'number' },
|
|
72
|
+
marker: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: { start: { type: 'boolean' }, end: { type: 'boolean' } },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
required: ['id', 'from', 'to'],
|
|
80
|
+
additionalProperties: true,
|
|
81
|
+
},
|
|
82
|
+
$defs: {
|
|
83
|
+
end: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
id: ID,
|
|
87
|
+
position: { type: 'number' },
|
|
88
|
+
},
|
|
89
|
+
required: ['id'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
/** コレクション名 → スキーマ */
|
|
94
|
+
exports.SCHEMAS = {
|
|
95
|
+
nodes: exports.NODES_SCHEMA,
|
|
96
|
+
edges: exports.EDGES_SCHEMA,
|
|
97
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// model.deployment の公開型。
|
|
3
|
+
//
|
|
4
|
+
// ここで言う「レコード」は、d3.deployment の data() に渡す入力そのもの({ nodes, edges })の 1 要素。
|
|
5
|
+
// iHub では data/deployment/{nodes,edges}.json の 1 要素。d3.deployment が正規化したあとの datum(_id / _core / _position を持つもの)ではない。
|
|
6
|
+
// ノードと線の図なので model.unchi / model.sitemap と形が近い。ラベルは label.text(unchi と同じ。sitemap は label.contents)。
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Background, Border, Font, Position } from '@yanqirenshi/types';
|
|
2
|
+
import type { DeploymentEdgeRecord, DeploymentNodeRecord, DeploymentNodeType, DeploymentRecord } from './types.js';
|
|
3
|
+
/** ノードの種類 */
|
|
4
|
+
export declare const NODE_TYPES: readonly DeploymentNodeType[];
|
|
5
|
+
/** ノードの枠線・背景の既定(assh0le の Stroke.template / Background.template) */
|
|
6
|
+
export declare const NODE_STYLE_DEFAULTS: {
|
|
7
|
+
readonly border: Required<Pick<Border, "color" | "width" | "type">>;
|
|
8
|
+
readonly background: Required<Pick<Background, "color" | "opacity">>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* ラベルの既定(assh0le の Label.template)。text が無いとき d3.deployment は '????????' を描く
|
|
12
|
+
* (withDefaults では '' を入れる — 「書いていない」ことをインスペクタで見せるため)。
|
|
13
|
+
*/
|
|
14
|
+
export declare const LABEL_DEFAULTS: {
|
|
15
|
+
readonly placeholder: "????????";
|
|
16
|
+
readonly position: Position;
|
|
17
|
+
readonly font: Font;
|
|
18
|
+
};
|
|
19
|
+
/** ノードの既定(Padding / Position.template)。size の 0 は「子に合わせる」 */
|
|
20
|
+
export declare const NODE_DEFAULTS: {
|
|
21
|
+
readonly type: DeploymentNodeType;
|
|
22
|
+
readonly padding: 0;
|
|
23
|
+
readonly position: Position;
|
|
24
|
+
};
|
|
25
|
+
/** 線の見た目(色・太さ・両端の矢印の有無) */
|
|
26
|
+
export interface DeploymentEdgeStyle {
|
|
27
|
+
color: string;
|
|
28
|
+
width: number;
|
|
29
|
+
marker: {
|
|
30
|
+
start: boolean;
|
|
31
|
+
end: boolean;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** 線の既定(Edge.dataTemplate の stroke、端点の角度は Geometry.getPortLineTo の 90=左) */
|
|
35
|
+
export declare const EDGE_DEFAULTS: {
|
|
36
|
+
readonly stroke: DeploymentEdgeStyle;
|
|
37
|
+
readonly position: 90;
|
|
38
|
+
};
|
|
39
|
+
/** 線か(from と to を持つ)。ノードは持たない */
|
|
40
|
+
export declare function isEdge(record: DeploymentRecord | null | undefined): record is DeploymentEdgeRecord;
|
|
41
|
+
/** ノードが描かれる枠線・背景(既定に入力を重ねた、実際に描かれる値) */
|
|
42
|
+
export declare function nodeStyle(node: DeploymentNodeRecord): typeof NODE_STYLE_DEFAULTS;
|
|
43
|
+
/**
|
|
44
|
+
* 線が描かれる値(Edge.normalize と同じ: stroke の color / width / marker はそれぞれ truthy ならそれ)。
|
|
45
|
+
* marker は入力があれば丸ごと置き換わる(片方だけ書くと、もう片方は偽)。
|
|
46
|
+
* d3.deployment のペインタが描くのは終点の矢印(marker.end)だけで、start は描かない。
|
|
47
|
+
*/
|
|
48
|
+
export declare function edgeStyle(edge: DeploymentEdgeRecord): {
|
|
49
|
+
stroke: DeploymentEdgeStyle;
|
|
50
|
+
};
|
|
51
|
+
/** 端点の角度(無ければ 90。Geometry.getPortLineTo と同じ: 0 は 0、それ以外の falsy は 90) */
|
|
52
|
+
export declare function degreeOf(position: number | undefined | null): number;
|
|
53
|
+
/**
|
|
54
|
+
* レコードに、d3.deployment が既定で描いている値を重ねて返す(入力は書き換えない)。
|
|
55
|
+
* インスペクタの初期値に使う。children は重ねない(子は右クリックしたときに自分で通す)。
|
|
56
|
+
*
|
|
57
|
+
* 重ねる項目: ノードは type・padding・position・label.text(無ければ '')・border・background、
|
|
58
|
+
* 線は stroke(矢印を含む)・from.position・to.position。size は view が子に合わせて埋めるので触らない。
|
|
59
|
+
*/
|
|
60
|
+
export declare function withDefaults<T extends DeploymentRecord>(record: T): T;
|
|
61
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnH,aAAa;AACb,eAAO,MAAM,UAAU,EAAE,SAAS,kBAAkB,EAA0B,CAAC;AAE/E,oEAAoE;AACpE,eAAO,MAAM,mBAAmB;qBAC+B,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;yBAChE,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;CACtF,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,cAAc;;uBAEG,QAAQ;mBACI,IAAI;CACpC,CAAC;AAEX,6DAA6D;AAC7D,eAAO,MAAM,aAAa;mBACR,kBAAkB;;uBAEN,QAAQ;CAC5B,CAAC;AAEX,2BAA2B;AAC3B,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa;qBAKnB,mBAAmB;;CAEhB,CAAC;AAEX,iCAAiC;AACjC,wBAAgB,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,IAAI,oBAAoB,CAElG;AAgBD,wCAAwC;AACxC,wBAAgB,SAAS,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,mBAAmB,CAKhF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,oBAAoB,GAAG;IAAE,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAUrF;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAKpE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,gBAAgB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAuBrE"}
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// d3.deployment が「書いていない項目」に既定で描く値。
|
|
2
|
+
//
|
|
3
|
+
// 値の出どころは、d3.deployment の datamodels/Node.js が使う共通基盤 assh0le のデータクラス
|
|
4
|
+
// (Stroke.template = 枠線、Background.template = 背景、Label.template = ラベル、Padding / Position.template)と、
|
|
5
|
+
// datamodels/Edge.js の dataTemplate(stroke と矢印)、Geometry.getPortLineTo(角度の既定 90)。
|
|
6
|
+
// d3.deployment はこのファイルを読む(#146)ので、ここが正。
|
|
7
|
+
//
|
|
8
|
+
// d3.deployment は border.type を正規化するが描画には使わない(dasharray を付けない)ので、モデルも項目にしない。
|
|
9
|
+
/** ノードの種類 */
|
|
10
|
+
export const NODE_TYPES = ['NODE', 'COMPONENT'];
|
|
11
|
+
/** ノードの枠線・背景の既定(assh0le の Stroke.template / Background.template) */
|
|
12
|
+
export const NODE_STYLE_DEFAULTS = {
|
|
13
|
+
border: { color: '#afafb0', width: 1, type: 'solid' },
|
|
14
|
+
background: { color: '#fff', opacity: 1.0 },
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* ラベルの既定(assh0le の Label.template)。text が無いとき d3.deployment は '????????' を描く
|
|
18
|
+
* (withDefaults では '' を入れる — 「書いていない」ことをインスペクタで見せるため)。
|
|
19
|
+
*/
|
|
20
|
+
export const LABEL_DEFAULTS = {
|
|
21
|
+
placeholder: '????????',
|
|
22
|
+
position: { x: 0, y: 0 },
|
|
23
|
+
font: { size: 16, color: '#333333' },
|
|
24
|
+
};
|
|
25
|
+
/** ノードの既定(Padding / Position.template)。size の 0 は「子に合わせる」 */
|
|
26
|
+
export const NODE_DEFAULTS = {
|
|
27
|
+
type: 'NODE',
|
|
28
|
+
padding: 0,
|
|
29
|
+
position: { x: 0, y: 0 },
|
|
30
|
+
};
|
|
31
|
+
/** 線の既定(Edge.dataTemplate の stroke、端点の角度は Geometry.getPortLineTo の 90=左) */
|
|
32
|
+
export const EDGE_DEFAULTS = {
|
|
33
|
+
stroke: {
|
|
34
|
+
color: '#333',
|
|
35
|
+
width: 1.5,
|
|
36
|
+
marker: { start: false, end: true },
|
|
37
|
+
},
|
|
38
|
+
position: 90,
|
|
39
|
+
};
|
|
40
|
+
/** 線か(from と to を持つ)。ノードは持たない */
|
|
41
|
+
export function isEdge(record) {
|
|
42
|
+
return !!(record && record.from && record.to);
|
|
43
|
+
}
|
|
44
|
+
/** 既定に入力の指定(truthy な項目だけ。assh0le の Stroke.build / Background.build と同じ判定)を重ねる */
|
|
45
|
+
function mergeStyle(defaults, given) {
|
|
46
|
+
const out = { ...defaults };
|
|
47
|
+
for (const key of Object.keys(given || {})) {
|
|
48
|
+
const v = given[key];
|
|
49
|
+
if (v)
|
|
50
|
+
out[key] = v;
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/** ノードが描かれる枠線・背景(既定に入力を重ねた、実際に描かれる値) */
|
|
55
|
+
export function nodeStyle(node) {
|
|
56
|
+
return {
|
|
57
|
+
border: mergeStyle(NODE_STYLE_DEFAULTS.border, node.border),
|
|
58
|
+
background: mergeStyle(NODE_STYLE_DEFAULTS.background, node.background),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 線が描かれる値(Edge.normalize と同じ: stroke の color / width / marker はそれぞれ truthy ならそれ)。
|
|
63
|
+
* marker は入力があれば丸ごと置き換わる(片方だけ書くと、もう片方は偽)。
|
|
64
|
+
* d3.deployment のペインタが描くのは終点の矢印(marker.end)だけで、start は描かない。
|
|
65
|
+
*/
|
|
66
|
+
export function edgeStyle(edge) {
|
|
67
|
+
return {
|
|
68
|
+
stroke: {
|
|
69
|
+
color: edge.stroke?.color || EDGE_DEFAULTS.stroke.color,
|
|
70
|
+
width: edge.stroke?.width || EDGE_DEFAULTS.stroke.width,
|
|
71
|
+
marker: edge.stroke?.marker
|
|
72
|
+
? { start: !!edge.stroke.marker.start, end: !!edge.stroke.marker.end }
|
|
73
|
+
: { ...EDGE_DEFAULTS.stroke.marker },
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** 端点の角度(無ければ 90。Geometry.getPortLineTo と同じ: 0 は 0、それ以外の falsy は 90) */
|
|
78
|
+
export function degreeOf(position) {
|
|
79
|
+
if (position === 0)
|
|
80
|
+
return 0;
|
|
81
|
+
return position ? position : EDGE_DEFAULTS.position;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* レコードに、d3.deployment が既定で描いている値を重ねて返す(入力は書き換えない)。
|
|
85
|
+
* インスペクタの初期値に使う。children は重ねない(子は右クリックしたときに自分で通す)。
|
|
86
|
+
*
|
|
87
|
+
* 重ねる項目: ノードは type・padding・position・label.text(無ければ '')・border・background、
|
|
88
|
+
* 線は stroke(矢印を含む)・from.position・to.position。size は view が子に合わせて埋めるので触らない。
|
|
89
|
+
*/
|
|
90
|
+
export function withDefaults(record) {
|
|
91
|
+
if (isEdge(record)) {
|
|
92
|
+
return {
|
|
93
|
+
...record,
|
|
94
|
+
...edgeStyle(record),
|
|
95
|
+
from: { ...record.from, position: degreeOf(record.from.position) },
|
|
96
|
+
to: { ...record.to, position: degreeOf(record.to.position) },
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const node = record;
|
|
100
|
+
const style = nodeStyle(node);
|
|
101
|
+
const label = node.label && typeof node.label === 'object' ? node.label : {};
|
|
102
|
+
return {
|
|
103
|
+
...node,
|
|
104
|
+
type: node.type || NODE_DEFAULTS.type,
|
|
105
|
+
label: { ...label, text: typeof label.text === 'string' ? label.text : '' },
|
|
106
|
+
padding: node.padding || node.padding === 0 ? node.padding : NODE_DEFAULTS.padding,
|
|
107
|
+
position: { ...NODE_DEFAULTS.position, ...(node.position || {}) },
|
|
108
|
+
border: style.border,
|
|
109
|
+
background: style.background,
|
|
110
|
+
};
|
|
111
|
+
}
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DeploymentField, DeploymentRecord } from './types.js';
|
|
2
|
+
/** ノードの項目 */
|
|
3
|
+
export declare const NODE_FIELDS: readonly DeploymentField[];
|
|
4
|
+
/** 線の項目。接続位置はノードの中心から見た角度(0=真下・時計回り。90=左 / 180=真上 / 270=右) */
|
|
5
|
+
export declare const EDGE_FIELDS: readonly DeploymentField[];
|
|
6
|
+
/** レコードに応じた項目の一覧(線 / ノード) */
|
|
7
|
+
export declare function fieldsOf(record: DeploymentRecord): DeploymentField[];
|
|
8
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIpE,aAAa;AACb,eAAO,MAAM,WAAW,EAAE,SAAS,eAAe,EAWjD,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,SAAS,eAAe,EAUjD,CAAC;AAEF,6BAA6B;AAC7B,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,EAAE,CAEpE"}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// 編集できる項目の一覧。インスペクタ(colonoscope の ModelInspector)に渡す。
|
|
2
|
+
//
|
|
3
|
+
// path はレコードの実際の項目を指す。既定値は withDefaults() で重ねてから渡すので、
|
|
4
|
+
// 書いていない項目(枠線の色など)も、図に描かれている値が初期値として出る。
|
|
5
|
+
// type: 'readonly' は表示だけ。options は取りうる値の一覧(検証にも使う)。
|
|
6
|
+
//
|
|
7
|
+
// iHub の SystemConfigurationDiagram.js の fields(label.text / type / id)から始め、
|
|
8
|
+
// d3.deployment が描く説明(ツールチップ)・リンク・幅・高さ・背景色・枠線の色 / 太さ、線の矢印を足した。
|
|
9
|
+
// border.type は d3.deployment が描かないので出さない。
|
|
10
|
+
import { NODE_TYPES, isEdge } from './defaults.js';
|
|
11
|
+
const BOOLEAN_OPTIONS = ['true', 'false'];
|
|
12
|
+
/** ノードの項目 */
|
|
13
|
+
export const NODE_FIELDS = [
|
|
14
|
+
{ path: 'label.text', label: '名称', type: 'text' },
|
|
15
|
+
{ path: 'type', label: '種類', type: 'text', options: NODE_TYPES },
|
|
16
|
+
{ path: 'id', label: 'ID', type: 'readonly' },
|
|
17
|
+
{ path: 'description', label: '説明', type: 'textarea' },
|
|
18
|
+
{ path: 'link.url', label: 'URL', type: 'text' },
|
|
19
|
+
{ path: 'size.w', label: '幅', type: 'number' },
|
|
20
|
+
{ path: 'size.h', label: '高さ', type: 'number' },
|
|
21
|
+
{ path: 'background.color', label: '背景色', type: 'text' },
|
|
22
|
+
{ path: 'border.color', label: '枠線の色', type: 'text' },
|
|
23
|
+
{ path: 'border.width', label: '枠線の太さ', type: 'number' },
|
|
24
|
+
];
|
|
25
|
+
/** 線の項目。接続位置はノードの中心から見た角度(0=真下・時計回り。90=左 / 180=真上 / 270=右) */
|
|
26
|
+
export const EDGE_FIELDS = [
|
|
27
|
+
{ path: 'id', label: 'ID', type: 'readonly' },
|
|
28
|
+
{ path: 'from.id', label: '接続元のノード', type: 'readonly' },
|
|
29
|
+
{ path: 'from.position', label: '接続元の位置 (角度)', type: 'number' },
|
|
30
|
+
{ path: 'to.id', label: '接続先のノード', type: 'readonly' },
|
|
31
|
+
{ path: 'to.position', label: '接続先の位置 (角度)', type: 'number' },
|
|
32
|
+
{ path: 'stroke.color', label: '線の色', type: 'text' },
|
|
33
|
+
{ path: 'stroke.width', label: '線の太さ', type: 'number' },
|
|
34
|
+
// 始点の矢印(marker.start)は d3.deployment のペインタが描かないので項目にしない
|
|
35
|
+
{ path: 'stroke.marker.end', label: '終点の矢印', type: 'text', options: BOOLEAN_OPTIONS },
|
|
36
|
+
];
|
|
37
|
+
/** レコードに応じた項目の一覧(線 / ノード) */
|
|
38
|
+
export function fieldsOf(record) {
|
|
39
|
+
return isEdge(record) ? [...EDGE_FIELDS] : [...NODE_FIELDS];
|
|
40
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DeploymentId, DeploymentNodeType, DeploymentNodeLabel, DeploymentNodeRecord, DeploymentEdgeEnd, DeploymentEdgeStroke, DeploymentEdgeRecord, DeploymentRecord, DeploymentGraph, DeploymentCollection, MergePatch, DeploymentChange, DeploymentMove, DeploymentFieldType, DeploymentField, DeploymentValues, } from './types.js';
|
|
2
|
+
export { NODE_TYPES, NODE_STYLE_DEFAULTS, LABEL_DEFAULTS, NODE_DEFAULTS, EDGE_DEFAULTS, isEdge, nodeStyle, edgeStyle, degreeOf, withDefaults, } from './defaults.js';
|
|
3
|
+
export type { DeploymentEdgeStyle } from './defaults.js';
|
|
4
|
+
export { NODES_SCHEMA, EDGES_SCHEMA, SCHEMAS } from './schema.js';
|
|
5
|
+
export { check, flatten, findById } from './check.js';
|
|
6
|
+
export { NODE_FIELDS, EDGE_FIELDS, fieldsOf } from './fields.js';
|
|
7
|
+
export { ModelError, collectionOf, titleOf, getByPath, mergePatch, movePatch, applyPatch, isColor } from './patch.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,YAAY,EACV,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,oBAAoB,EACpH,oBAAoB,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,EAC3G,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,GACvE,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,UAAU,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAC7E,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,GACrD,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// model.deployment — システム構成図(デプロイメント図。d3.deployment)の「図ごとの知識」。描画はしない(react / d3 に依存しない)。
|
|
2
|
+
//
|
|
3
|
+
// スキーマ: SCHEMAS / NODES_SCHEMA / EDGES_SCHEMA(JSON Schema 2020-12)
|
|
4
|
+
// 整合性ルール: check(data)(id の重複・参照先の存在)/ flatten / findById
|
|
5
|
+
// 既定値の補完: withDefaults(record) / nodeStyle / edgeStyle / degreeOf
|
|
6
|
+
// NODE_TYPES / NODE_STYLE_DEFAULTS / LABEL_DEFAULTS / NODE_DEFAULTS / EDGE_DEFAULTS(d3.deployment が読む)
|
|
7
|
+
// 編集できる項目: fieldsOf(record) / NODE_FIELDS / EDGE_FIELDS
|
|
8
|
+
// patch への変換: movePatch(node, move) / applyPatch(record, values) / mergePatch(record, patch)
|
|
9
|
+
//
|
|
10
|
+
// graph 系(unchi / sitemap / deployment)の 3 つ目。check / flatten / findById / movePatch / mergePatch / getByPath / isColor と
|
|
11
|
+
// 入力の読み取り部品は model.core(#151)のもので、ここでは model.deployment の型を付けて公開している。
|
|
12
|
+
export { NODE_TYPES, NODE_STYLE_DEFAULTS, LABEL_DEFAULTS, NODE_DEFAULTS, EDGE_DEFAULTS, isEdge, nodeStyle, edgeStyle, degreeOf, withDefaults, } from './defaults.js';
|
|
13
|
+
export { NODES_SCHEMA, EDGES_SCHEMA, SCHEMAS } from './schema.js';
|
|
14
|
+
export { check, flatten, findById } from './check.js';
|
|
15
|
+
export { NODE_FIELDS, EDGE_FIELDS, fieldsOf } from './fields.js';
|
|
16
|
+
export { ModelError, collectionOf, titleOf, getByPath, mergePatch, movePatch, applyPatch, isColor } from './patch.js';
|
package/dist/patch.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DeploymentChange, DeploymentCollection, DeploymentMove, DeploymentNodeRecord, DeploymentRecord, DeploymentValues } from './types.js';
|
|
2
|
+
export { ModelError, getByPath, mergePatch, isColor } from '@yanqirenshi/model.core';
|
|
3
|
+
/** レコードを置くコレクション */
|
|
4
|
+
export declare function collectionOf(record: DeploymentRecord): DeploymentCollection;
|
|
5
|
+
/** インスペクタの見出し。ラベルの文字、無ければ「種類 id」(線は「接続元 → 接続先」) */
|
|
6
|
+
export declare function titleOf(record: DeploymentRecord): string;
|
|
7
|
+
/**
|
|
8
|
+
* ドラッグで動かしたノードの位置を保存する patch。
|
|
9
|
+
* 保存してある position に移動量を足し、整数に丸める(position が無いときは 0, 0 から)。
|
|
10
|
+
* 子のノード(COMPONENT を含む)の position は親の中での位置なので、親を動かしても子の patch は要らない。
|
|
11
|
+
*/
|
|
12
|
+
export declare function movePatch(node: DeploymentNodeRecord, move: DeploymentMove): DeploymentChange;
|
|
13
|
+
/**
|
|
14
|
+
* インスペクタの「適用」の値を、保存する patch に変換する。
|
|
15
|
+
* 図に描いている値から変えた項目だけを patch に入れる(変えていない既定の値まで書き込まないため)。
|
|
16
|
+
* 変更が無ければ patch は {}。
|
|
17
|
+
*/
|
|
18
|
+
export declare function applyPatch(record: DeploymentRecord, values: DeploymentValues): DeploymentChange;
|
|
19
|
+
//# sourceMappingURL=patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../src/patch.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACE,gBAAgB,EAAE,oBAAoB,EAAwB,cAAc,EAAE,oBAAoB,EAC9G,gBAAgB,EAAE,gBAAgB,EACnC,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAErF,oBAAoB;AACpB,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,oBAAoB,CAE3E;AAED,mDAAmD;AACnD,wBAAgB,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAUxD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,cAAc,GAAG,gBAAgB,CAE5F;AAmGD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAM/F"}
|
package/dist/patch.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// UI の操作(ドラッグ・インスペクタの適用)を、保存する patch(JSON Merge Patch)に変換する。
|
|
2
|
+
//
|
|
3
|
+
// 戻り値は { collection, id, patch }。利用側(iHub など)は図の種類を知らずにこれを保存すればよい。
|
|
4
|
+
// 入力の検証に失敗したときは ModelError を投げる(メッセージは利用者にそのまま見せられる日本語)。
|
|
5
|
+
// model.sitemap の patch.ts を元にしている(ラベルは label.text、種類は NODE / COMPONENT、線に矢印の有無がある)。
|
|
6
|
+
// 読み取り部品(toColor など)と patch の道具は model.core にある(#151)。
|
|
7
|
+
import { ModelError, changedValues as changedValuesOf, movePatch as movePatchTo, put, toBoolean, toColor, toDegree, toLength, toOption, toOptionalText, toWidth, } from '@yanqirenshi/model.core';
|
|
8
|
+
import { NODE_TYPES, isEdge, withDefaults } from './defaults.js';
|
|
9
|
+
import { fieldsOf } from './fields.js';
|
|
10
|
+
// model.core のものをそのまま公開する(利用側が model.deployment だけを読めばよいように)
|
|
11
|
+
export { ModelError, getByPath, mergePatch, isColor } from '@yanqirenshi/model.core';
|
|
12
|
+
/** レコードを置くコレクション */
|
|
13
|
+
export function collectionOf(record) {
|
|
14
|
+
return isEdge(record) ? 'edges' : 'nodes';
|
|
15
|
+
}
|
|
16
|
+
/** インスペクタの見出し。ラベルの文字、無ければ「種類 id」(線は「接続元 → 接続先」) */
|
|
17
|
+
export function titleOf(record) {
|
|
18
|
+
if (isEdge(record))
|
|
19
|
+
return `${String(record.from.id)} → ${String(record.to.id)}`;
|
|
20
|
+
const text = record.label && typeof record.label === 'object' ? record.label.text : null;
|
|
21
|
+
if (typeof text === 'string' && text !== '')
|
|
22
|
+
return text;
|
|
23
|
+
return `${record.type || ''} ${String(record.id)}`.trim();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ドラッグで動かしたノードの位置を保存する patch。
|
|
27
|
+
* 保存してある position に移動量を足し、整数に丸める(position が無いときは 0, 0 から)。
|
|
28
|
+
* 子のノード(COMPONENT を含む)の position は親の中での位置なので、親を動かしても子の patch は要らない。
|
|
29
|
+
*/
|
|
30
|
+
export function movePatch(node, move) {
|
|
31
|
+
return movePatchTo(node, move, 'nodes');
|
|
32
|
+
}
|
|
33
|
+
// インスペクタの入力のうち、図に描いている値(withDefaults)から変わった項目だけ
|
|
34
|
+
function changedValues(record, values) {
|
|
35
|
+
return changedValuesOf(withDefaults(record), values, fieldsOf(record));
|
|
36
|
+
}
|
|
37
|
+
// 幅・高さは 0 以上(0 は「子に合わせる」)。
|
|
38
|
+
// 枠線・線の太さは 0 より大きい数(d3.deployment は 0 を「書いていない」と見て既定に倒すので、0 は入れられない)
|
|
39
|
+
const LENGTH = { hint: '(0 で子に合わせる)' };
|
|
40
|
+
// ノードの入力 → patch(label.text / type / description / link.url / size / background / border)
|
|
41
|
+
function nodePatch(node, values) {
|
|
42
|
+
const patch = {};
|
|
43
|
+
for (const [path, value] of changedValues(node, values)) {
|
|
44
|
+
switch (path) {
|
|
45
|
+
case 'label.text':
|
|
46
|
+
// 名称は空にできない(d3.deployment は名称の無いノードに '????????' を描く)
|
|
47
|
+
if (value === '')
|
|
48
|
+
throw new ModelError('名称を入力してください。');
|
|
49
|
+
put(patch, path, value);
|
|
50
|
+
break;
|
|
51
|
+
case 'type':
|
|
52
|
+
put(patch, path, toOption(value, NODE_TYPES, '種類'));
|
|
53
|
+
break;
|
|
54
|
+
case 'description':
|
|
55
|
+
put(patch, path, toOptionalText(value));
|
|
56
|
+
break;
|
|
57
|
+
case 'link.url':
|
|
58
|
+
// URL を空にするとリンクごと除く(d3.deployment は url の無い link を描かない)
|
|
59
|
+
if (value === '')
|
|
60
|
+
patch.link = null;
|
|
61
|
+
else
|
|
62
|
+
put(patch, path, value);
|
|
63
|
+
break;
|
|
64
|
+
case 'size.w':
|
|
65
|
+
put(patch, path, toLength(value, '幅', LENGTH));
|
|
66
|
+
break;
|
|
67
|
+
case 'size.h':
|
|
68
|
+
put(patch, path, toLength(value, '高さ', LENGTH));
|
|
69
|
+
break;
|
|
70
|
+
case 'background.color':
|
|
71
|
+
put(patch, path, toColor(value, '背景色'));
|
|
72
|
+
break;
|
|
73
|
+
case 'border.color':
|
|
74
|
+
put(patch, path, toColor(value, '枠線の色'));
|
|
75
|
+
break;
|
|
76
|
+
case 'border.width':
|
|
77
|
+
put(patch, path, toWidth(value, '枠線の太さ'));
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return patch;
|
|
82
|
+
}
|
|
83
|
+
const END_LABELS = { from: '接続元', to: '接続先' };
|
|
84
|
+
// 線の入力 → patch(from / to の角度・stroke・矢印)
|
|
85
|
+
function edgePatch(edge, values) {
|
|
86
|
+
const patch = {};
|
|
87
|
+
for (const [path, value] of changedValues(edge, values)) {
|
|
88
|
+
switch (path) {
|
|
89
|
+
case 'from.position':
|
|
90
|
+
case 'to.position':
|
|
91
|
+
put(patch, path, toDegree(value, `${END_LABELS[path.split('.')[0]]}の位置`));
|
|
92
|
+
break;
|
|
93
|
+
case 'stroke.color':
|
|
94
|
+
put(patch, path, toColor(value, '線の色'));
|
|
95
|
+
break;
|
|
96
|
+
case 'stroke.width':
|
|
97
|
+
put(patch, path, toWidth(value, '線の太さ'));
|
|
98
|
+
break;
|
|
99
|
+
case 'stroke.marker.start':
|
|
100
|
+
put(patch, path, toBoolean(value, '始点の矢印'));
|
|
101
|
+
break;
|
|
102
|
+
case 'stroke.marker.end':
|
|
103
|
+
put(patch, path, toBoolean(value, '終点の矢印'));
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// 矢印を片方だけ書くと d3.deployment の Edge.normalize は marker を丸ごと入力で置き換える(無い側は undefined =
|
|
108
|
+
// start は偽、end は truthy 判定で偽)ので、片方を変えたときはもう片方も描いている値で埋める
|
|
109
|
+
const marker = patch.stroke?.marker;
|
|
110
|
+
if (marker) {
|
|
111
|
+
const effective = withDefaults(edge).stroke.marker;
|
|
112
|
+
if (marker.start === undefined)
|
|
113
|
+
marker.start = effective.start;
|
|
114
|
+
if (marker.end === undefined)
|
|
115
|
+
marker.end = effective.end;
|
|
116
|
+
}
|
|
117
|
+
return patch;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* インスペクタの「適用」の値を、保存する patch に変換する。
|
|
121
|
+
* 図に描いている値から変えた項目だけを patch に入れる(変えていない既定の値まで書き込まないため)。
|
|
122
|
+
* 変更が無ければ patch は {}。
|
|
123
|
+
*/
|
|
124
|
+
export function applyPatch(record, values) {
|
|
125
|
+
return {
|
|
126
|
+
collection: collectionOf(record),
|
|
127
|
+
id: record.id,
|
|
128
|
+
patch: isEdge(record) ? edgePatch(record, values) : nodePatch(record, values),
|
|
129
|
+
};
|
|
130
|
+
}
|