@yanqirenshi/d3.deployment 0.0.7 → 0.2.2
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 +15 -1
- package/dist/components/D3Deployment.js +26 -0
- package/dist/index.js +28 -0
- package/dist/js/Core.js +463 -0
- package/dist/js/Edge.js +119 -0
- package/dist/js/Node.js +307 -0
- package/dist/js/Port.js +64 -0
- package/dist/js/Rectum.js +480 -0
- package/package.json +41 -34
- package/index.js +0 -3
- package/jest.config.js +0 -17
- package/src/D3Deployment.js +0 -309
- package/src/D3DeploymentEdge.js +0 -115
- package/src/D3DeploymentNode.js +0 -305
- package/src/D3DeploymentPort.js +0 -34
- package/tests/D3Deployment.test.js +0 -7
package/src/D3Deployment.js
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import Asshole, {Hierarchy, Geometry} from '@yanqirenshi/assh0le';
|
|
2
|
-
|
|
3
|
-
import D3DeploymentNode from './D3DeploymentNode.js';
|
|
4
|
-
import D3DeploymentEdge from './D3DeploymentEdge.js';
|
|
5
|
-
import D3DeploymentPort from './D3DeploymentPort.js';
|
|
6
|
-
|
|
7
|
-
export default class D3Deployment extends Asshole {
|
|
8
|
-
constructor () {
|
|
9
|
-
super();
|
|
10
|
-
|
|
11
|
-
this._nodes = { list: [], ht: {}, tree: [] };
|
|
12
|
-
this._edges = { list: [], ht: {} };
|
|
13
|
-
this._ports = { list: [], ht: {} };
|
|
14
|
-
|
|
15
|
-
this.id_counter = 1;
|
|
16
|
-
|
|
17
|
-
this._calculator = new Geometry();
|
|
18
|
-
this._node = new D3DeploymentNode();
|
|
19
|
-
this._port = new D3DeploymentPort();
|
|
20
|
-
this._edge = new D3DeploymentEdge();
|
|
21
|
-
|
|
22
|
-
this._painter = {
|
|
23
|
-
NODE: this._node,
|
|
24
|
-
EDGE: this._edge,
|
|
25
|
-
PORT: this._port,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/* **************************** */
|
|
29
|
-
/* Overwrite Asshole function */
|
|
30
|
-
/* **************************** */
|
|
31
|
-
makeSvgAfter () {
|
|
32
|
-
this._node.addFilterShadow(this.getSvgElement());
|
|
33
|
-
}
|
|
34
|
-
/* ******** */
|
|
35
|
-
/* DATA */
|
|
36
|
-
/* ******** */
|
|
37
|
-
data2pool (trees, pool) {
|
|
38
|
-
for (let tree of trees) {
|
|
39
|
-
let id = tree._id;
|
|
40
|
-
|
|
41
|
-
pool.ht[id] = tree;
|
|
42
|
-
pool.list.push(tree);
|
|
43
|
-
|
|
44
|
-
if (tree.children)
|
|
45
|
-
this.data2pool(tree.children, pool);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return pool;
|
|
49
|
-
}
|
|
50
|
-
importNodes (nodes) {
|
|
51
|
-
let node = this._node;
|
|
52
|
-
|
|
53
|
-
let tmp = (nodes || []).map((d) => {
|
|
54
|
-
return node.normalize(d);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const h = new Hierarchy();
|
|
58
|
-
for (let data of tmp)
|
|
59
|
-
h.fitting(data);
|
|
60
|
-
|
|
61
|
-
let pool = this.data2pool(tmp, this._nodes);
|
|
62
|
-
|
|
63
|
-
pool.tree = tmp;
|
|
64
|
-
|
|
65
|
-
return pool;
|
|
66
|
-
}
|
|
67
|
-
importEdges (edges) {
|
|
68
|
-
let edge = this._edge;
|
|
69
|
-
|
|
70
|
-
let id = 1;
|
|
71
|
-
|
|
72
|
-
let tmp = (edges || []).map((d) => {
|
|
73
|
-
d._id = this.id_counter++;
|
|
74
|
-
return edge.normalize(d, id++);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
return this.data2pool(tmp, this._edges);
|
|
78
|
-
}
|
|
79
|
-
makePort (type, node, edge) {
|
|
80
|
-
let port = this._port.normalize({
|
|
81
|
-
node: node,
|
|
82
|
-
edge: edge,
|
|
83
|
-
_id: this.id_counter++,
|
|
84
|
-
_class: 'PORT',
|
|
85
|
-
_type: type,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
this._ports.list.push(port);
|
|
89
|
-
this._ports.ht[port._id] = port;
|
|
90
|
-
|
|
91
|
-
return port;
|
|
92
|
-
}
|
|
93
|
-
makePorts (edges) {
|
|
94
|
-
let nodes = this._nodes.ht;
|
|
95
|
-
|
|
96
|
-
for (let edge of edges){
|
|
97
|
-
let node_from = nodes[edge.from.id];
|
|
98
|
-
let node_to = nodes[edge.to.id];
|
|
99
|
-
|
|
100
|
-
edge.from.node = node_from;
|
|
101
|
-
edge.to.node = node_to;
|
|
102
|
-
|
|
103
|
-
edge.from.port = this.makePort('FROM', edge.from.node, edge);
|
|
104
|
-
edge.to.port = this.makePort('TO', edge.to.node, edge);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
getPortLineFrom (node) {
|
|
108
|
-
return {
|
|
109
|
-
x: Math.floor(node._size.w / 2) + node._position.x ,
|
|
110
|
-
y: Math.floor(node._size.h / 2) + node._position.y
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
getPortLineToPoint (node) {
|
|
114
|
-
let w = node._size.w;
|
|
115
|
-
let h = node._size.h;
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
x: 0,
|
|
119
|
-
y: Math.floor(Math.sqrt((w * w) + (h * h))),
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
getPortLineTo (degree, node) {
|
|
123
|
-
let point = this.getPortLineToPoint(node);
|
|
124
|
-
let x = point.x;
|
|
125
|
-
let y = point.y;
|
|
126
|
-
|
|
127
|
-
let degree_tmp;
|
|
128
|
-
if (degree===0)
|
|
129
|
-
degree_tmp = degree;
|
|
130
|
-
else if (!degree)
|
|
131
|
-
degree_tmp = 90;
|
|
132
|
-
else
|
|
133
|
-
degree_tmp = degree % 360;
|
|
134
|
-
|
|
135
|
-
let radian = this._calculator.deg2rad(degree_tmp);
|
|
136
|
-
let cos = Math.cos(radian);
|
|
137
|
-
let sin = Math.sin(radian);
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
x: Math.floor(x * cos - y * sin),
|
|
141
|
-
y: Math.floor(x * sin + y * cos),
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Port の位置を計算するため、Port と Nodeの中心の直線を算出する。
|
|
146
|
-
*
|
|
147
|
-
* @param {object} port Line を算出する対象の Port。 TODO: これ、つこてなくない?
|
|
148
|
-
* @param {number} port_pos_degree Port の位置。
|
|
149
|
-
* @param {object} node port の Node。 算出した Line の位置を補正するための Node
|
|
150
|
-
*/
|
|
151
|
-
makePortLine (degree, node) {
|
|
152
|
-
let from = this.getPortLineFrom(node);
|
|
153
|
-
let to = this.getPortLineTo(degree, node);
|
|
154
|
-
|
|
155
|
-
return {
|
|
156
|
-
from: {
|
|
157
|
-
x: from.x,
|
|
158
|
-
y: from.y,
|
|
159
|
-
},
|
|
160
|
-
to: {
|
|
161
|
-
x: to.x + from.x,
|
|
162
|
-
y: to.y + from.y,
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
positioningPort (port, port_pos_degree, node) {
|
|
167
|
-
let calc = this._calculator;
|
|
168
|
-
|
|
169
|
-
let lines_entity = this._node.getFourSides(node);
|
|
170
|
-
let line_port = this.makePortLine(port_pos_degree, node);
|
|
171
|
-
|
|
172
|
-
return calc.getCrossPoint(lines_entity, line_port) || {x:0, y:0};
|
|
173
|
-
}
|
|
174
|
-
fittingPort (port) {
|
|
175
|
-
let port_pos;
|
|
176
|
-
|
|
177
|
-
if (port._type==='FROM')
|
|
178
|
-
port_pos = port.edge._core.from.position;
|
|
179
|
-
else
|
|
180
|
-
port_pos = port.edge._core.to.position;
|
|
181
|
-
|
|
182
|
-
let position = this.positioningPort(port,
|
|
183
|
-
port_pos,
|
|
184
|
-
port.node);
|
|
185
|
-
|
|
186
|
-
port.position = position;
|
|
187
|
-
}
|
|
188
|
-
fittingEdge (edge) {
|
|
189
|
-
edge.from.position = {
|
|
190
|
-
x: edge.from.port.position.x,
|
|
191
|
-
y: edge.from.port.position.y,
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
edge.to.position = {
|
|
195
|
-
x: edge.to.port.position.x,
|
|
196
|
-
y: edge.to.port.position.y,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* data を元に描画用のデータに変換する。
|
|
201
|
-
* 変換したデータを保管する。
|
|
202
|
-
* data.edge を元に port のデータも作成する。
|
|
203
|
-
* @param {object} data { node: [], edges: [] }
|
|
204
|
-
*/
|
|
205
|
-
data (data) {
|
|
206
|
-
if (arguments.length===0)
|
|
207
|
-
return this._nodes.list;
|
|
208
|
-
|
|
209
|
-
this.importNodes(data.nodes);
|
|
210
|
-
this.importEdges(data.edges);
|
|
211
|
-
|
|
212
|
-
this.makePorts(this._edges.list);
|
|
213
|
-
|
|
214
|
-
// fitting ports
|
|
215
|
-
for (let port of this._ports.list)
|
|
216
|
-
this.fittingPort(port);
|
|
217
|
-
|
|
218
|
-
// fitting edges
|
|
219
|
-
for (let edge of this._edges.list)
|
|
220
|
-
this.fittingEdge(edge);
|
|
221
|
-
|
|
222
|
-
this.draw();
|
|
223
|
-
|
|
224
|
-
return this;
|
|
225
|
-
}
|
|
226
|
-
elementDataList () {
|
|
227
|
-
|
|
228
|
-
return [].concat(
|
|
229
|
-
this._nodes.list,
|
|
230
|
-
this._edges.list,
|
|
231
|
-
this._ports.list
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
///// ////////////////////////////////////////////////////////////////
|
|
235
|
-
///// Flatten
|
|
236
|
-
///// ////////////////////////////////////////////////////////////////
|
|
237
|
-
flattenCore (data, lev) {
|
|
238
|
-
let out = [data];
|
|
239
|
-
|
|
240
|
-
let children = data.children.reduce((acc, val) => {
|
|
241
|
-
val._level = lev;
|
|
242
|
-
return acc.concat(this.flattenCore(val, lev * 10));
|
|
243
|
-
}, []);
|
|
244
|
-
|
|
245
|
-
return out.concat(children);
|
|
246
|
-
}
|
|
247
|
-
flatten () {
|
|
248
|
-
let data = this._nodes.tree;
|
|
249
|
-
|
|
250
|
-
if (!data)
|
|
251
|
-
return [];
|
|
252
|
-
|
|
253
|
-
let lev = 10;
|
|
254
|
-
return data.reduce((acc, val) => {
|
|
255
|
-
val._level = lev;
|
|
256
|
-
return acc.concat(this.flattenCore(val, lev * 10));
|
|
257
|
-
}, []);
|
|
258
|
-
}
|
|
259
|
-
getDrawElements () {
|
|
260
|
-
let out = this.flatten();
|
|
261
|
-
|
|
262
|
-
// port に level を設定
|
|
263
|
-
for (let port of this._ports.list) {
|
|
264
|
-
port._level = port.node._level;
|
|
265
|
-
out.push(port);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// edge に level を設定
|
|
269
|
-
for (let edge of this._edges.list) {
|
|
270
|
-
let lev_from = edge.from.port._level;
|
|
271
|
-
let lev_to = edge.to.port._level;
|
|
272
|
-
if (lev_from > lev_to)
|
|
273
|
-
edge._level = lev_from - 1;
|
|
274
|
-
else
|
|
275
|
-
edge._level = lev_to - 1;
|
|
276
|
-
|
|
277
|
-
out.push(edge);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// ソートして返す
|
|
281
|
-
return out.sort((a, b) => {
|
|
282
|
-
return (a._level < b._level) ? -1 : 1;
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
///// ////////////////////////////////////////////////////////////////
|
|
286
|
-
///// Draw
|
|
287
|
-
///// ////////////////////////////////////////////////////////////////
|
|
288
|
-
painter(element_class) {
|
|
289
|
-
let painter = this._painter[element_class];
|
|
290
|
-
|
|
291
|
-
return painter || null;
|
|
292
|
-
}
|
|
293
|
-
drawElement (place, element) {
|
|
294
|
-
let painter = this.painter(element._class);
|
|
295
|
-
|
|
296
|
-
if (!painter)
|
|
297
|
-
return;
|
|
298
|
-
|
|
299
|
-
painter.draw(place, element);
|
|
300
|
-
}
|
|
301
|
-
draw() {
|
|
302
|
-
let place = this.getLayerForeground();
|
|
303
|
-
|
|
304
|
-
let elements = this.getDrawElements();
|
|
305
|
-
|
|
306
|
-
for (let element of elements)
|
|
307
|
-
this.drawElement(place, element);
|
|
308
|
-
}
|
|
309
|
-
}
|
package/src/D3DeploymentEdge.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import * as d3 from 'd3';
|
|
2
|
-
|
|
3
|
-
export default class D3DeploymentEdge {
|
|
4
|
-
dataTemplate () {
|
|
5
|
-
return {
|
|
6
|
-
from: {
|
|
7
|
-
id: null,
|
|
8
|
-
port: null,
|
|
9
|
-
node: null,
|
|
10
|
-
position: { x:0, y:0 },
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
to: {
|
|
14
|
-
id: null,
|
|
15
|
-
port: null,
|
|
16
|
-
node: null,
|
|
17
|
-
position: { x:0, y:0 },
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
stroke: {
|
|
21
|
-
color: '#333',
|
|
22
|
-
width: 1.5,
|
|
23
|
-
marker: {
|
|
24
|
-
start: false,
|
|
25
|
-
end: true,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
_id: null,
|
|
30
|
-
_core: null,
|
|
31
|
-
_class: 'EDGE',
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
normalize (data) {
|
|
35
|
-
let new_data = this.dataTemplate();
|
|
36
|
-
|
|
37
|
-
new_data._core = data;
|
|
38
|
-
|
|
39
|
-
if (data.id)
|
|
40
|
-
new_data._id = data.id;
|
|
41
|
-
|
|
42
|
-
if (data.from.id)
|
|
43
|
-
new_data.from.id = data.from.id;
|
|
44
|
-
|
|
45
|
-
if (data.to.id)
|
|
46
|
-
new_data.to.id = data.to.id;
|
|
47
|
-
|
|
48
|
-
if (data.stroke) {
|
|
49
|
-
if (data.stroke.color)
|
|
50
|
-
new_data.stroke.color = data.stroke.color;
|
|
51
|
-
|
|
52
|
-
if (data.stroke.width)
|
|
53
|
-
new_data.stroke.width = data.stroke.width;
|
|
54
|
-
|
|
55
|
-
if (data.stroke.marker)
|
|
56
|
-
new_data.stroke.marker = data.stroke.marker;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
data._edge = new_data;
|
|
60
|
-
|
|
61
|
-
return new_data;
|
|
62
|
-
}
|
|
63
|
-
///// ////////////////////////////////////////////////////////////////
|
|
64
|
-
///// Draw
|
|
65
|
-
///// ////////////////////////////////////////////////////////////////
|
|
66
|
-
draw (place, data) {
|
|
67
|
-
let lineData = [
|
|
68
|
-
{
|
|
69
|
-
"x": data.from.position.x,
|
|
70
|
-
"y": data.from.position.y,
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"x": data.to.position.x,
|
|
74
|
-
"y": data.to.position.y
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
stroke: data._core.stroke,
|
|
78
|
-
},
|
|
79
|
-
];
|
|
80
|
-
console.log(data._core);
|
|
81
|
-
let lineFunction = d3.line()
|
|
82
|
-
.x(function(d) { return d.x; })
|
|
83
|
-
.y(function(d) { return d.y; });
|
|
84
|
-
|
|
85
|
-
let path = place
|
|
86
|
-
.append("path")
|
|
87
|
-
.datum(lineData)
|
|
88
|
-
.attr("fill", "none")
|
|
89
|
-
.attr("d", lineFunction)
|
|
90
|
-
.attr('marker-end', d => {
|
|
91
|
-
if (!d[2].stroke.marker || d[2].stroke.marker.end)
|
|
92
|
-
return "url(#edge-arrow)";
|
|
93
|
-
|
|
94
|
-
return null;
|
|
95
|
-
})
|
|
96
|
-
.style('stroke-linecap', 'round')
|
|
97
|
-
.style('fill', (d) => {
|
|
98
|
-
return d[2].stroke.color;
|
|
99
|
-
})
|
|
100
|
-
.style("stroke", (d) => {
|
|
101
|
-
return d[2].stroke.color;
|
|
102
|
-
})
|
|
103
|
-
.style("stroke-width", (d) => {
|
|
104
|
-
return d[2].stroke.width;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
var len = path.node().getTotalLength();
|
|
109
|
-
var margin = 12;
|
|
110
|
-
var t = len - (margin * 2);
|
|
111
|
-
path
|
|
112
|
-
.attr('stroke-dasharray', `0 ${margin} ${t} ${margin}`)
|
|
113
|
-
.attr( 'stroke-dashoffset', 0);
|
|
114
|
-
}
|
|
115
|
-
}
|