@yanqirenshi/d3.deployment 0.10.0 → 0.11.0
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/README.markdown +6 -1
- package/dist/js/Rectum.js +39 -5
- package/dist/js/datamodels/Edge.js +8 -7
- package/dist/js/datamodels/Node.js +8 -5
- package/jest.config.js +4 -0
- package/package.json +3 -2
package/README.markdown
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
- ノードは `children` で入れ子にできます。宣言サイズより子が大きい場合は親が自動で広がります。
|
|
6
6
|
- ノードはドラッグで移動でき、**親を動かすとサブツリーごと追従**します。
|
|
7
|
+
動かし終えたことは `callbacks.node.dragend(core, node, move)` で受け取れます(v0.11.0+)。
|
|
8
|
+
- 既定値(枠線・背景・線の stroke と矢印・端点の角度 90)は [`@yanqirenshi/model.deployment`](../model.deployment) から取ります。
|
|
9
|
+
インスペクタや保存は model.deployment と組み合わせます(ショーケースの `model.deployment` のデモ)。
|
|
7
10
|
- エッジの取り付け位置はポートの角度で指定します(0=真下・時計回り。90=左 / 180=真上 / 270=右)。
|
|
8
11
|
- **このライブラリは描画のみを行います。** クリックと右クリックはコールバックで通知するだけで、
|
|
9
12
|
編集 UI は利用側が用意します(ショーケースではインスペクタ `@yanqirenshi/colonoscope` を繋いでいます)。
|
|
@@ -35,7 +38,9 @@ export default function Graph({ data }) {
|
|
|
35
38
|
// 描画は行わず通知のみ。core は入力データそのもの
|
|
36
39
|
// contextmenu は右クリック。引数は click と同じで、最後に event(MouseEvent)。
|
|
37
40
|
// 渡したときだけブラウザ標準のメニューを止める。ドラッグ中は呼ばれない
|
|
38
|
-
node: { click: (core, node) => {}, contextmenu: (core, node, event) => {}
|
|
41
|
+
node: { click: (core, node) => {}, contextmenu: (core, node, event) => {},
|
|
42
|
+
// ドラッグの終わり(動いたときだけ)。move は移動量 { dx, dy }。model.deployment の movePatch(core, move) に渡せる
|
|
43
|
+
dragend: (core, node, move) => {} },
|
|
39
44
|
edge: { click: (core, edge) => {}, contextmenu: (core, edge, event) => {} },
|
|
40
45
|
},
|
|
41
46
|
});
|
package/dist/js/Rectum.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports["default"] = void 0;
|
|
8
8
|
var d3 = _interopRequireWildcard(require("d3"));
|
|
9
9
|
var _assh0le = require("@yanqirenshi/assh0le");
|
|
10
|
+
var _model = require("@yanqirenshi/model.deployment");
|
|
10
11
|
var _Node = _interopRequireDefault(require("./datamodels/Node.js"));
|
|
11
12
|
var _Edge = _interopRequireDefault(require("./datamodels/Edge.js"));
|
|
12
13
|
var _Port = _interopRequireDefault(require("./datamodels/Port.js"));
|
|
@@ -32,7 +33,7 @@ function _get() { return _get = "undefined" != typeof Reflect && Reflect.get ? R
|
|
|
32
33
|
function _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; }
|
|
33
34
|
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
34
35
|
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
35
|
-
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
36
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } // 端点の角度の既定(90=左)は図ごとの知識なので @yanqirenshi/model.deployment が持つ(Foolsgolds/Assholes#146)
|
|
36
37
|
/**
|
|
37
38
|
* click / contextmenu のコールバックを呼ぶ。
|
|
38
39
|
*
|
|
@@ -88,7 +89,9 @@ var Rectum = exports["default"] = /*#__PURE__*/function (_Colon) {
|
|
|
88
89
|
return {
|
|
89
90
|
node: {
|
|
90
91
|
click: node.click || null,
|
|
91
|
-
contextmenu: node.contextmenu || null
|
|
92
|
+
contextmenu: node.contextmenu || null,
|
|
93
|
+
// ドラッグの終わり(動いたときだけ)。(core, node, move) を渡す
|
|
94
|
+
dragend: node.dragend || null
|
|
92
95
|
},
|
|
93
96
|
edge: {
|
|
94
97
|
click: edge.click || null,
|
|
@@ -269,7 +272,9 @@ var Rectum = exports["default"] = /*#__PURE__*/function (_Colon) {
|
|
|
269
272
|
value: function fittingPort(port) {
|
|
270
273
|
var port_pos;
|
|
271
274
|
if (port._type === 'FROM') port_pos = port.edge._core.from.position;else port_pos = port.edge._core.to.position;
|
|
272
|
-
|
|
275
|
+
|
|
276
|
+
// 角度が無ければモデルの既定(90=左)。Geometry.getPortLineTo も同じ値に倒すが、既定の出どころはモデル側
|
|
277
|
+
var position = this.positioningPort(port, (0, _model.degreeOf)(port_pos), port.node);
|
|
273
278
|
port.position = position;
|
|
274
279
|
}
|
|
275
280
|
}, {
|
|
@@ -552,17 +557,46 @@ var Rectum = exports["default"] = /*#__PURE__*/function (_Colon) {
|
|
|
552
557
|
// Next.js(Webpack/SWC)のトランスパイルで `this` が書き換わり得るため、
|
|
553
558
|
// 掴んだ要素は sourceEvent から closest() で取り、クロージャで保持する。
|
|
554
559
|
var grabbed = null;
|
|
555
|
-
|
|
560
|
+
|
|
561
|
+
// dragend(callbacks.node.dragend)で移動量を出すために、掴んだときの位置を覚える
|
|
562
|
+
var origin = null;
|
|
563
|
+
var drag = d3.drag().on('start', function (event, node) {
|
|
556
564
|
grabbed = event.sourceEvent.target.closest('g.node, g.component');
|
|
557
565
|
if (grabbed) grabbed.style.cursor = 'grabbing';
|
|
566
|
+
origin = {
|
|
567
|
+
x: node._position.x,
|
|
568
|
+
y: node._position.y
|
|
569
|
+
};
|
|
558
570
|
}).on('drag', function (event, node) {
|
|
559
571
|
self.moveSubtree(place, data, node, event.dx, event.dy);
|
|
560
|
-
}).on('end', function () {
|
|
572
|
+
}).on('end', function (event, node) {
|
|
561
573
|
if (grabbed) grabbed.style.cursor = 'grab';
|
|
562
574
|
grabbed = null;
|
|
575
|
+
self.notifyDragend(node, origin);
|
|
576
|
+
origin = null;
|
|
563
577
|
});
|
|
564
578
|
place.selectAll('g.node, g.component').style('cursor', 'grab').call(drag);
|
|
565
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* ドラッグの終わり。動いたときだけ callbacks.node.dragend(core, node, move) を呼ぶ。
|
|
582
|
+
* core: 入力のレコード(node._core)
|
|
583
|
+
* node: 正規化済みのノード(_position は動かしたあとの位置)
|
|
584
|
+
* move: 移動量 { dx, dy }(世界座標)。model.deployment の movePatch(core, move) にそのまま渡せる
|
|
585
|
+
* 動かさずに離したとき(クリック)は呼ばない(保存が走らないように)。
|
|
586
|
+
* 掴んだノード(node / component)についてだけ呼ぶ(子孫はいっしょに動くが、position は親の中での位置なので変わらない)。
|
|
587
|
+
*/
|
|
588
|
+
}, {
|
|
589
|
+
key: "notifyDragend",
|
|
590
|
+
value: function notifyDragend(node, origin) {
|
|
591
|
+
var callback = this._callbacks.node.dragend;
|
|
592
|
+
if (!callback || !origin) return;
|
|
593
|
+
var move = {
|
|
594
|
+
dx: node._position.x - origin.x,
|
|
595
|
+
dy: node._position.y - origin.y
|
|
596
|
+
};
|
|
597
|
+
if (move.dx === 0 && move.dy === 0) return;
|
|
598
|
+
callback(node._core, node, move);
|
|
599
|
+
}
|
|
566
600
|
/** node を根とするサブツリーの node._id 集合を返す。 */
|
|
567
601
|
}, {
|
|
568
602
|
key: "collectSubtree",
|
|
@@ -4,12 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = void 0;
|
|
7
|
+
var _model = require("@yanqirenshi/model.deployment");
|
|
7
8
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
9
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
8
12
|
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
9
13
|
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
10
14
|
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
11
15
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
12
|
-
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
16
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // 線の既定(stroke と矢印)は図ごとの知識なので @yanqirenshi/model.deployment が持つ(Foolsgolds/Assholes#146)
|
|
13
17
|
/**
|
|
14
18
|
* Edge のデータクラス。入力データの正規化(既定値補完)を行う。
|
|
15
19
|
* 描画は painters/Edges.js が担当する。
|
|
@@ -41,12 +45,9 @@ var Edge = exports["default"] = /*#__PURE__*/function () {
|
|
|
41
45
|
}
|
|
42
46
|
},
|
|
43
47
|
stroke: {
|
|
44
|
-
color:
|
|
45
|
-
width:
|
|
46
|
-
marker: {
|
|
47
|
-
start: false,
|
|
48
|
-
end: true
|
|
49
|
-
}
|
|
48
|
+
color: _model.EDGE_DEFAULTS.stroke.color,
|
|
49
|
+
width: _model.EDGE_DEFAULTS.stroke.width,
|
|
50
|
+
marker: _objectSpread({}, _model.EDGE_DEFAULTS.stroke.marker)
|
|
50
51
|
},
|
|
51
52
|
_id: null,
|
|
52
53
|
_core: null,
|
|
@@ -5,12 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = void 0;
|
|
7
7
|
var _assh0le = require("@yanqirenshi/assh0le");
|
|
8
|
+
var _model = require("@yanqirenshi/model.deployment");
|
|
8
9
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
9
10
|
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
10
11
|
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
11
12
|
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
12
13
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
13
|
-
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // 枠線・背景の既定は図ごとの知識なので @yanqirenshi/model.deployment が持つ(Foolsgolds/Assholes#146)。
|
|
15
|
+
// 値は assh0le の Stroke.template / Background.template と同じ(model.deployment のテストが突き合わせる)。
|
|
14
16
|
/**
|
|
15
17
|
* Node のデータクラス。入力データの正規化(既定値補完)と幾何情報の提供を行う。
|
|
16
18
|
* 描画は painters/Nodes.js が担当する。
|
|
@@ -21,8 +23,6 @@ var Node = exports["default"] = /*#__PURE__*/function () {
|
|
|
21
23
|
this.label = new _assh0le.Label();
|
|
22
24
|
this.rectangle = new _assh0le.Rectangle();
|
|
23
25
|
this.position = new _assh0le.Position();
|
|
24
|
-
this.stroke = new _assh0le.Stroke();
|
|
25
|
-
this.background = new _assh0le.Background();
|
|
26
26
|
this.padding = new _assh0le.Padding();
|
|
27
27
|
}
|
|
28
28
|
///// ////////////////////////////////////////////////////////////////
|
|
@@ -124,9 +124,12 @@ var Node = exports["default"] = /*#__PURE__*/function () {
|
|
|
124
124
|
new_data.label = this.label.build(new_data._core.label);
|
|
125
125
|
new_data.size = this.rectangle.build(new_data._core.size);
|
|
126
126
|
new_data.position = this.position.build(new_data._core.position);
|
|
127
|
-
new_data.border = this.stroke.build(new_data._core.border) || this.stroke.template();
|
|
128
127
|
new_data.padding = this.padding.build(new_data._core.padding);
|
|
129
|
-
|
|
128
|
+
|
|
129
|
+
// 枠線・背景(既定に入力の truthy な項目を重ねる)は model.deployment の nodeStyle
|
|
130
|
+
var style = (0, _model.nodeStyle)(new_data._core);
|
|
131
|
+
new_data.border = style.border;
|
|
132
|
+
new_data.background = style.background;
|
|
130
133
|
data._node = new_data;
|
|
131
134
|
return new_data;
|
|
132
135
|
}
|
package/jest.config.js
CHANGED
|
@@ -10,6 +10,10 @@ module.exports = {
|
|
|
10
10
|
// d3 v7 は ESM-only で CJS ランタイムの jest では読めないため、スタブにマップする
|
|
11
11
|
moduleNameMapper: {
|
|
12
12
|
'^d3$': '<rootDir>/tests/d3-stub.js',
|
|
13
|
+
// model.deployment は ESM のみを main にしている。jest 25 は package.json の exports を見ないので、
|
|
14
|
+
// CommonJS 版(model.deployment の build が dist/cjs/ に出す)へ直接マップする。
|
|
15
|
+
// model.deployment を先にビルドしておくこと(npm run build -w @yanqirenshi/model.deployment)。
|
|
16
|
+
'^@yanqirenshi/model.deployment$': '<rootDir>/../model.deployment/dist/cjs/index.js',
|
|
13
17
|
},
|
|
14
18
|
collectCoverageFrom: [
|
|
15
19
|
"**/src/**/*.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yanqirenshi/d3.deployment",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Deployment diagram renderer (nestable nodes / edges / ports) — dragging a parent moves its whole subtree",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"directories": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"d3": "^7.9.0",
|
|
15
|
-
"@yanqirenshi/assh0le": "^0.5.0"
|
|
15
|
+
"@yanqirenshi/assh0le": "^0.5.0",
|
|
16
|
+
"@yanqirenshi/model.deployment": "^0.1.0"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"@babel/cli": "^7.12.17",
|