@things-factory/integration-ui 9.0.0-beta.20 → 9.0.0-beta.24

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.
@@ -1,808 +0,0 @@
1
- import * as d3 from 'd3';
2
- export class GraphViewer {
3
- constructor(_selector, _options) {
4
- this.classes2colors = {};
5
- this.justLoaded = false;
6
- this.numClasses = 0;
7
- this.options = {
8
- arrowSize: 4,
9
- colors: this.colors(),
10
- highlight: undefined,
11
- infoPanel: true,
12
- minCollision: undefined,
13
- graphData: undefined,
14
- dataUrl: undefined,
15
- nodeOutlineFillColor: undefined,
16
- nodeRadius: 25,
17
- relationshipColor: '#a5abb6',
18
- zoomFit: false
19
- };
20
- this.init(_selector, _options);
21
- }
22
- appendGraph(container) {
23
- this.svg = container
24
- .append('svg')
25
- .attr('width', '100%')
26
- .attr('height', '100%')
27
- .attr('class', 'graph-viewer')
28
- .call(d3.zoom().on('zoom', (event, d) => {
29
- var scale = event.transform.k, translate = [event.transform.x, event.transform.y];
30
- if (this.svgTranslate) {
31
- translate[0] += this.svgTranslate[0];
32
- translate[1] += this.svgTranslate[1];
33
- }
34
- if (this.svgScale) {
35
- scale *= this.svgScale;
36
- }
37
- this.svg.attr('transform', 'translate(' + translate[0] + ', ' + translate[1] + ') scale(' + scale + ')');
38
- }))
39
- .on('dblclick.zoom', null)
40
- .append('g')
41
- .attr('width', '100%')
42
- .attr('height', '100%');
43
- this.svgRelationships = this.svg.append('g').attr('class', 'relationships');
44
- this.svgNodes = this.svg.append('g').attr('class', 'nodes');
45
- }
46
- appendImageToNode(node) {
47
- return node
48
- .append('image')
49
- .attr('height', d => {
50
- return this.icon(d) ? '24px' : '30px';
51
- })
52
- .attr('x', d => {
53
- return this.icon(d) ? '5px' : '-15px';
54
- })
55
- .attr('xlink:href', d => {
56
- return this.image(d);
57
- })
58
- .attr('y', d => {
59
- return this.icon(d) ? '5px' : '-16px';
60
- })
61
- .attr('width', d => {
62
- return this.icon(d) ? '24px' : '30px';
63
- });
64
- }
65
- appendInfoPanel(container) {
66
- return container.append('div').attr('class', 'graph-info');
67
- }
68
- appendInfoElement(cls, isNode, property, value) {
69
- var elem = this.info.append('a');
70
- elem
71
- .attr('href', '#')
72
- .attr('class', cls)
73
- .html('<strong>' + property + '</strong>' + (value ? ': ' + value : ''));
74
- if (!value) {
75
- elem
76
- .style('background-color', d => {
77
- return this.options.nodeOutlineFillColor
78
- ? this.options.nodeOutlineFillColor
79
- : isNode
80
- ? this.class2color(property)
81
- : this.defaultColor();
82
- })
83
- .style('border-color', d => {
84
- return this.options.nodeOutlineFillColor
85
- ? this.class2darkenColor(this.options.nodeOutlineFillColor)
86
- : isNode
87
- ? this.class2darkenColor(property)
88
- : this.defaultDarkenColor();
89
- })
90
- .style('color', d => {
91
- return this.options.nodeOutlineFillColor ? this.class2darkenColor(this.options.nodeOutlineFillColor) : '#fff';
92
- });
93
- }
94
- }
95
- appendInfoElementClass(cls, node) {
96
- this.appendInfoElement(cls, true, node);
97
- }
98
- appendInfoElementProperty(cls, property, value) {
99
- this.appendInfoElement(cls, false, property, value);
100
- }
101
- appendInfoElementRelationship(cls, relationship) {
102
- this.appendInfoElement(cls, false, relationship);
103
- }
104
- appendNode() {
105
- return this.node
106
- .enter()
107
- .append('g')
108
- .attr('class', d => {
109
- var highlight, i, classes = 'node', label = d.labels[0];
110
- if (this.icon(d)) {
111
- classes += ' node-icon';
112
- }
113
- if (this.image(d)) {
114
- classes += ' node-image';
115
- }
116
- if (this.options.highlight) {
117
- for (i = 0; i < this.options.highlight.length; i++) {
118
- highlight = this.options.highlight[i];
119
- if (d.labels[0] === highlight.class && d.properties[highlight.property] === highlight.value) {
120
- classes += ' node-highlighted';
121
- break;
122
- }
123
- }
124
- }
125
- return classes;
126
- })
127
- .on('click', (event, d) => {
128
- d.fx = d.fy = null;
129
- if (typeof this.options.onNodeClick === 'function') {
130
- this.options.onNodeClick(d);
131
- }
132
- })
133
- .on('dblclick', (event, d) => {
134
- this.stickNode(event, d);
135
- if (typeof this.options.onNodeDoubleClick === 'function') {
136
- this.options.onNodeDoubleClick(d);
137
- }
138
- })
139
- .on('mouseenter', (event, d) => {
140
- if (this.info) {
141
- this.updateInfo(d);
142
- }
143
- if (typeof this.options.onNodeMouseEnter === 'function') {
144
- this.options.onNodeMouseEnter(d);
145
- }
146
- })
147
- .on('mouseleave', (event, d) => {
148
- if (this.info) {
149
- this.clearInfo();
150
- }
151
- if (typeof this.options.onNodeMouseLeave === 'function') {
152
- this.options.onNodeMouseLeave(d);
153
- }
154
- })
155
- .call(d3
156
- .drag()
157
- .on('start', this.dragStarted.bind(this))
158
- .on('drag', this.dragged.bind(this))
159
- .on('end', this.dragEnded.bind(this)));
160
- }
161
- appendNodeToGraph() {
162
- var n = this.appendNode();
163
- this.appendRingToNode(n);
164
- // this.appendBoxToNode(n)
165
- this.appendOutlineToNode(n);
166
- if (this.options.icons) {
167
- this.appendTextToNode(n);
168
- }
169
- if (this.options.images) {
170
- this.appendImageToNode(n);
171
- }
172
- return n;
173
- }
174
- appendOutlineToNode(node) {
175
- const outline = node
176
- .append('circle')
177
- .attr('class', 'outline')
178
- .attr('r', this.options.nodeRadius)
179
- .style('fill', d => {
180
- return this.options.nodeOutlineFillColor ? this.options.nodeOutlineFillColor : this.class2color(d.labels[0]);
181
- })
182
- .style('stroke', d => {
183
- return this.options.nodeOutlineFillColor
184
- ? this.class2darkenColor(this.options.nodeOutlineFillColor)
185
- : this.class2darkenColor(d.labels[0]);
186
- })
187
- .append('title')
188
- .text(d => {
189
- return this.toString(d);
190
- });
191
- node
192
- .append('text')
193
- .attr('class', 'node-text')
194
- .attr('x', 0)
195
- .attr('y', 52)
196
- .attr('text-anchor', 'middle') // 텍스트 중앙 정렬
197
- .attr('fill', 'black') // 텍스트 색상을 검은색으로 변경
198
- .text(d => d.text);
199
- return outline;
200
- }
201
- appendBoxToNode(node) {
202
- const rect = node
203
- .append('rect')
204
- .attr('class', 'node-rect')
205
- .attr('width', 160) // 사각형의 너비
206
- .attr('height', 30) // 사각형의 높이
207
- .attr('x', -80) // 사각형의 중심을 기준으로 x 위치 조정
208
- .attr('y', -15) // 사각형의 중심을 기준으로 y 위치 조정
209
- .style('fill', d => {
210
- return this.options.nodeOutlineFillColor ? this.options.nodeOutlineFillColor : this.class2color(d.labels[0]);
211
- })
212
- .style('stroke', d => {
213
- return this.options.nodeOutlineFillColor
214
- ? this.class2darkenColor(this.options.nodeOutlineFillColor)
215
- : this.class2darkenColor(d.labels[0]);
216
- })
217
- .append('title')
218
- .text(d => {
219
- return this.toString(d);
220
- });
221
- node
222
- .append('text')
223
- .attr('class', 'node-text')
224
- .attr('x', 0)
225
- .attr('y', 4)
226
- .attr('text-anchor', 'middle') // 텍스트 중앙 정렬
227
- .attr('fill', 'black') // 텍스트 색상을 검은색으로 변경
228
- .text(d => d.text);
229
- return rect;
230
- }
231
- appendRingToNode(node) {
232
- return node
233
- .append('circle')
234
- .attr('class', 'ring')
235
- .attr('r', this.options.nodeRadius * 1.16)
236
- .append('title')
237
- .text(d => {
238
- return this.toString(d);
239
- });
240
- }
241
- appendTextToNode(node) {
242
- return node
243
- .append('text')
244
- .attr('fill', '#ffffff')
245
- .attr('pointer-events', 'none')
246
- .attr('text-anchor', 'middle')
247
- .attr('y', '24px')
248
- .attr('font-family', 'Material Symbols Outlined')
249
- .attr('font-size', '48px')
250
- .attr('text-anchor', 'middle')
251
- .attr('alignment-baseline', 'top')
252
- .text(d => this.icon(d));
253
- }
254
- appendRelationship() {
255
- return this.relationship
256
- .enter()
257
- .append('g')
258
- .attr('class', 'relationship')
259
- .on('dblclick', (event, d) => {
260
- if (typeof this.options.onRelationshipDoubleClick === 'function') {
261
- this.options.onRelationshipDoubleClick(d);
262
- }
263
- })
264
- .on('mouseenter', (event, d) => {
265
- if (this.info) {
266
- this.updateInfo(d);
267
- }
268
- });
269
- }
270
- appendOutlineToRelationship(r) {
271
- return r.append('path').attr('class', 'outline').attr('fill', '#a5abb6').attr('stroke', 'none');
272
- }
273
- appendOverlayToRelationship(r) {
274
- return r.append('path').attr('class', 'overlay');
275
- }
276
- appendTextToRelationship(r) {
277
- return r
278
- .append('text')
279
- .attr('class', 'text')
280
- .attr('fill', '#000000')
281
- .attr('font-size', '8px')
282
- .attr('pointer-events', 'none')
283
- .attr('text-anchor', 'middle')
284
- .text(d => {
285
- return d.type;
286
- });
287
- }
288
- appendRelationshipToGraph() {
289
- var relationship = this.appendRelationship(), text = this.appendTextToRelationship(relationship), outline = this.appendOutlineToRelationship(relationship), overlay = this.appendOverlayToRelationship(relationship);
290
- return {
291
- outline: outline,
292
- overlay: overlay,
293
- relationship: relationship,
294
- text: text
295
- };
296
- }
297
- class2color(cls) {
298
- var color = this.classes2colors[cls];
299
- if (!color) {
300
- // color = this.options.colors[Math.min(numClasses, this.options.colors.length - 1)];
301
- color = this.options.colors[this.numClasses % this.options.colors.length];
302
- this.classes2colors[cls] = color;
303
- this.numClasses++;
304
- }
305
- return color;
306
- }
307
- class2darkenColor(cls) {
308
- return d3.rgb(this.class2color(cls)).darker(1);
309
- }
310
- clearInfo() {
311
- this.info.html('');
312
- }
313
- color() {
314
- return this.options.colors[(this.options.colors.length * Math.random()) << 0];
315
- }
316
- colors() {
317
- // d3.schemeCategory10,
318
- // d3.schemeCategory20,
319
- return [
320
- '#68bdf6', // light blue
321
- '#6dce9e', // green #1
322
- '#faafc2', // light pink
323
- '#f2baf6', // purple
324
- '#ff928c', // light red
325
- '#fcea7e', // light yellow
326
- '#ffc766', // light orange
327
- '#405f9e', // navy blue
328
- '#a5abb6', // dark gray
329
- '#78cecb', // green #2,
330
- '#b88cbb', // dark purple
331
- '#ced2d9', // light gray
332
- '#e84646', // dark red
333
- '#fa5f86', // dark pink
334
- '#ffab1a', // dark orange
335
- '#fcda19', // dark yellow
336
- '#797b80', // black
337
- '#c9d96f', // pistacchio
338
- '#47991f', // green #3
339
- '#70edee', // turquoise
340
- '#ff75ea' // pink
341
- ];
342
- }
343
- contains(array, id) {
344
- var filter = array.filter(function (elem) {
345
- return elem.id === id;
346
- });
347
- return filter.length > 0;
348
- }
349
- defaultColor() {
350
- return this.options.relationshipColor;
351
- }
352
- defaultDarkenColor() {
353
- return d3.rgb(this.options.colors[this.options.colors.length - 1]).darker(1);
354
- }
355
- dragEnded(event, d) {
356
- if (!event.active) {
357
- this.simulation.alphaTarget(0);
358
- }
359
- if (typeof this.options.onNodeDragEnd === 'function') {
360
- this.options.onNodeDragEnd(d);
361
- }
362
- }
363
- dragged(event, d) {
364
- this.stickNode(event, d);
365
- }
366
- dragStarted(event, d) {
367
- if (!event.active) {
368
- this.simulation.alphaTarget(0.3).restart();
369
- }
370
- d.fx = d.x;
371
- d.fy = d.y;
372
- if (typeof this.options.onNodeDragStart === 'function') {
373
- this.options.onNodeDragStart(d);
374
- }
375
- }
376
- extend(obj1, obj2) {
377
- var obj = {};
378
- this.merge(obj, obj1);
379
- this.merge(obj, obj2);
380
- return obj;
381
- }
382
- icon(d) {
383
- return d.icon;
384
- }
385
- image(d) {
386
- var i, imagesForLabel, img, imgLevel, label, labelPropertyValue, property, value;
387
- if (this.options.images) {
388
- imagesForLabel = this.options.imageMap[d.labels[0]];
389
- if (imagesForLabel) {
390
- imgLevel = 0;
391
- for (i = 0; i < imagesForLabel.length; i++) {
392
- labelPropertyValue = imagesForLabel[i].split('|');
393
- switch (labelPropertyValue.length) {
394
- case 3:
395
- value = labelPropertyValue[2];
396
- /* falls through */
397
- case 2:
398
- property = labelPropertyValue[1];
399
- /* falls through */
400
- case 1:
401
- label = labelPropertyValue[0];
402
- }
403
- if (d.labels[0] === label &&
404
- (!property || d.properties[property] !== undefined) &&
405
- (!value || d.properties[property] === value)) {
406
- if (labelPropertyValue.length > imgLevel) {
407
- img = this.options.images[imagesForLabel[i]];
408
- imgLevel = labelPropertyValue.length;
409
- }
410
- }
411
- }
412
- }
413
- }
414
- return img;
415
- }
416
- init(_selector, _options) {
417
- this.merge(this.options, _options);
418
- if (this.options.icons) {
419
- this.options.showIcons = true;
420
- }
421
- if (!this.options.minCollision) {
422
- this.options.minCollision = this.options.nodeRadius * 2;
423
- }
424
- this.selector = _selector;
425
- this.container = d3.select(this.selector);
426
- // this.container.attr('class', 'graph-container').html('')
427
- if (this.options.infoPanel) {
428
- this.info = this.appendInfoPanel(this.container);
429
- }
430
- this.appendGraph(this.container);
431
- this.simulation = this.initSimulation();
432
- if (this.options.graphData) {
433
- this.loadGraphData();
434
- }
435
- else if (this.options.dataUrl) {
436
- this.loadGraphDataFromUrl(this.options.dataUrl);
437
- }
438
- else {
439
- console.error('Error: both graphData and dataUrl are empty!');
440
- }
441
- }
442
- initSimulation() {
443
- const x = this.svg.node().parentElement.parentElement.clientWidth / 2;
444
- const y = this.svg.node().parentElement.parentElement.clientHeight / 2;
445
- var simulation = d3
446
- .forceSimulation()
447
- .force('collide', d3
448
- .forceCollide()
449
- .radius(d => {
450
- return this.options.minCollision;
451
- })
452
- .iterations(2))
453
- .force('charge', d3.forceManyBody())
454
- .force('link', d3.forceLink().id(d => {
455
- return d.id;
456
- }))
457
- .force('center', d3.forceCenter(x, y))
458
- .on('tick', () => {
459
- this.tick();
460
- })
461
- .on('end', () => {
462
- if (this.options.zoomFit && !this.justLoaded) {
463
- this.justLoaded = true;
464
- this.zoomFit(2);
465
- }
466
- });
467
- return simulation;
468
- }
469
- loadGraphData() {
470
- this.nodes = [];
471
- this.relationships = [];
472
- this.updateWithGraphData(this.options.graphData);
473
- }
474
- loadGraphDataFromUrl(dataUrl) {
475
- this.nodes = [];
476
- this.relationships = [];
477
- d3.json(dataUrl, (error, data) => {
478
- if (error) {
479
- throw error;
480
- }
481
- this.updateWithGraphData(data);
482
- });
483
- }
484
- merge(target, source) {
485
- Object.keys(source).forEach(property => {
486
- target[property] = source[property];
487
- });
488
- }
489
- graphDataToD3Data(data) {
490
- var graph = {
491
- nodes: [],
492
- relationships: []
493
- };
494
- data.results.forEach(result => {
495
- result.data.forEach(data => {
496
- data.graph.nodes.forEach(node => {
497
- if (!this.contains(graph.nodes, node.id)) {
498
- graph.nodes.push(node);
499
- }
500
- });
501
- data.graph.relationships.forEach(function (relationship) {
502
- relationship.source = relationship.startNode;
503
- relationship.target = relationship.endNode;
504
- graph.relationships.push(relationship);
505
- });
506
- data.graph.relationships.sort(function (a, b) {
507
- if (a.source > b.source) {
508
- return 1;
509
- }
510
- else if (a.source < b.source) {
511
- return -1;
512
- }
513
- else {
514
- if (a.target > b.target) {
515
- return 1;
516
- }
517
- if (a.target < b.target) {
518
- return -1;
519
- }
520
- else {
521
- return 0;
522
- }
523
- }
524
- });
525
- for (var i = 0; i < data.graph.relationships.length; i++) {
526
- if (i !== 0 &&
527
- data.graph.relationships[i].source === data.graph.relationships[i - 1].source &&
528
- data.graph.relationships[i].target === data.graph.relationships[i - 1].target) {
529
- data.graph.relationships[i].linknum = data.graph.relationships[i - 1].linknum + 1;
530
- }
531
- else {
532
- data.graph.relationships[i].linknum = 1;
533
- }
534
- }
535
- });
536
- });
537
- return graph;
538
- }
539
- randomD3Data(d, maxNodesToGenerate) {
540
- var data = {
541
- nodes: [],
542
- relationships: []
543
- }, i, label, node, numNodes = ((maxNodesToGenerate * Math.random()) << 0) + 1, relationship, s = this.size();
544
- for (i = 0; i < numNodes; i++) {
545
- label = this.randomLabel();
546
- node = {
547
- id: s.nodes + 1 + i,
548
- labels: [label],
549
- properties: {
550
- random: label
551
- },
552
- x: d.x,
553
- y: d.y
554
- };
555
- data.nodes[data.nodes.length] = node;
556
- relationship = {
557
- id: s.relationships + 1 + i,
558
- type: label.toUpperCase(),
559
- startNode: d.id,
560
- endNode: s.nodes + 1 + i,
561
- properties: {
562
- from: Date.now()
563
- },
564
- source: d.id,
565
- target: s.nodes + 1 + i,
566
- linknum: s.relationships + 1 + i
567
- };
568
- data.relationships[data.relationships.length] = relationship;
569
- }
570
- return data;
571
- }
572
- randomLabel() {
573
- var icons = Object.keys(this.options.iconMap);
574
- return icons[(icons.length * Math.random()) << 0];
575
- }
576
- rotate(cx, cy, x, y, angle) {
577
- var radians = (Math.PI / 180) * angle, cos = Math.cos(radians), sin = Math.sin(radians), nx = cos * (x - cx) + sin * (y - cy) + cx, ny = cos * (y - cy) - sin * (x - cx) + cy;
578
- return { x: nx, y: ny };
579
- }
580
- rotatePoint(c, p, angle) {
581
- return this.rotate(c.x, c.y, p.x, p.y, angle);
582
- }
583
- rotation(source, target) {
584
- return (Math.atan2(target.y - source.y, target.x - source.x) * 180) / Math.PI;
585
- }
586
- size() {
587
- return {
588
- nodes: this.nodes.length,
589
- relationships: this.relationships.length
590
- };
591
- }
592
- stickNode(event, d) {
593
- d.fx = event.x;
594
- d.fy = event.y;
595
- }
596
- tick() {
597
- this.tickNodes();
598
- this.tickRelationships();
599
- }
600
- tickNodes() {
601
- if (this.node) {
602
- this.node.attr('transform', d => {
603
- return 'translate(' + d.x + ', ' + d.y + ')';
604
- });
605
- }
606
- }
607
- tickRelationships() {
608
- if (this.relationship) {
609
- this.relationship.attr('transform', d => {
610
- var angle = this.rotation(d.source, d.target);
611
- return 'translate(' + d.source.x + ', ' + d.source.y + ') rotate(' + angle + ')';
612
- });
613
- this.tickRelationshipsTexts();
614
- this.tickRelationshipsOutlines();
615
- this.tickRelationshipsOverlays();
616
- }
617
- }
618
- tickRelationshipsOutlines() {
619
- const self = this;
620
- this.relationship.each(function (relationship) {
621
- var rel = d3.select(this);
622
- var outline = rel.select('.outline'), text = rel.select('.text'), bbox = text.node().getBBox(), padding = 3;
623
- outline.attr('d', d => {
624
- var center = { x: 0, y: 0 }, angle = self.rotation(d.source, d.target), textBoundingBox = text.node().getBBox(), textPadding = 5, u = self.unitaryVector(d.source, d.target), textMargin = {
625
- x: (d.target.x - d.source.x - (textBoundingBox.width + textPadding) * u.x) * 0.5,
626
- y: (d.target.y - d.source.y - (textBoundingBox.width + textPadding) * u.y) * 0.5
627
- }, n = self.unitaryNormalVector(d.source, d.target), rotatedPointA1 = self.rotatePoint(center, { x: 0 + (self.options.nodeRadius + 1) * u.x - n.x, y: 0 + (self.options.nodeRadius + 1) * u.y - n.y }, angle), rotatedPointB1 = self.rotatePoint(center, { x: textMargin.x - n.x, y: textMargin.y - n.y }, angle), rotatedPointC1 = self.rotatePoint(center, { x: textMargin.x, y: textMargin.y }, angle), rotatedPointD1 = self.rotatePoint(center, { x: 0 + (self.options.nodeRadius + 1) * u.x, y: 0 + (self.options.nodeRadius + 1) * u.y }, angle), rotatedPointA2 = self.rotatePoint(center, { x: d.target.x - d.source.x - textMargin.x - n.x, y: d.target.y - d.source.y - textMargin.y - n.y }, angle), rotatedPointB2 = self.rotatePoint(center, {
628
- x: d.target.x - d.source.x - (self.options.nodeRadius + 1) * u.x - n.x - u.x * self.options.arrowSize,
629
- y: d.target.y - d.source.y - (self.options.nodeRadius + 1) * u.y - n.y - u.y * self.options.arrowSize
630
- }, angle), rotatedPointC2 = self.rotatePoint(center, {
631
- x: d.target.x -
632
- d.source.x -
633
- (self.options.nodeRadius + 1) * u.x -
634
- n.x +
635
- (n.x - u.x) * self.options.arrowSize,
636
- y: d.target.y -
637
- d.source.y -
638
- (self.options.nodeRadius + 1) * u.y -
639
- n.y +
640
- (n.y - u.y) * self.options.arrowSize
641
- }, angle), rotatedPointD2 = self.rotatePoint(center, {
642
- x: d.target.x - d.source.x - (self.options.nodeRadius + 1) * u.x,
643
- y: d.target.y - d.source.y - (self.options.nodeRadius + 1) * u.y
644
- }, angle), rotatedPointE2 = self.rotatePoint(center, {
645
- x: d.target.x - d.source.x - (self.options.nodeRadius + 1) * u.x + (-n.x - u.x) * self.options.arrowSize,
646
- y: d.target.y - d.source.y - (self.options.nodeRadius + 1) * u.y + (-n.y - u.y) * self.options.arrowSize
647
- }, angle), rotatedPointF2 = self.rotatePoint(center, {
648
- x: d.target.x - d.source.x - (self.options.nodeRadius + 1) * u.x - u.x * self.options.arrowSize,
649
- y: d.target.y - d.source.y - (self.options.nodeRadius + 1) * u.y - u.y * self.options.arrowSize
650
- }, angle), rotatedPointG2 = self.rotatePoint(center, { x: d.target.x - d.source.x - textMargin.x, y: d.target.y - d.source.y - textMargin.y }, angle);
651
- return ('M ' +
652
- rotatedPointA1.x +
653
- ' ' +
654
- rotatedPointA1.y +
655
- ' L ' +
656
- rotatedPointB1.x +
657
- ' ' +
658
- rotatedPointB1.y +
659
- ' L ' +
660
- rotatedPointC1.x +
661
- ' ' +
662
- rotatedPointC1.y +
663
- ' L ' +
664
- rotatedPointD1.x +
665
- ' ' +
666
- rotatedPointD1.y +
667
- ' Z M ' +
668
- rotatedPointA2.x +
669
- ' ' +
670
- rotatedPointA2.y +
671
- ' L ' +
672
- rotatedPointB2.x +
673
- ' ' +
674
- rotatedPointB2.y +
675
- ' L ' +
676
- rotatedPointC2.x +
677
- ' ' +
678
- rotatedPointC2.y +
679
- ' L ' +
680
- rotatedPointD2.x +
681
- ' ' +
682
- rotatedPointD2.y +
683
- ' L ' +
684
- rotatedPointE2.x +
685
- ' ' +
686
- rotatedPointE2.y +
687
- ' L ' +
688
- rotatedPointF2.x +
689
- ' ' +
690
- rotatedPointF2.y +
691
- ' L ' +
692
- rotatedPointG2.x +
693
- ' ' +
694
- rotatedPointG2.y +
695
- ' Z');
696
- });
697
- });
698
- }
699
- tickRelationshipsOverlays() {
700
- this.relationshipOverlay.attr('d', d => {
701
- var center = { x: 0, y: 0 }, angle = this.rotation(d.source, d.target), n1 = this.unitaryNormalVector(d.source, d.target), n = this.unitaryNormalVector(d.source, d.target, 50), rotatedPointA = this.rotatePoint(center, { x: 0 - n.x, y: 0 - n.y }, angle), rotatedPointB = this.rotatePoint(center, { x: d.target.x - d.source.x - n.x, y: d.target.y - d.source.y - n.y }, angle), rotatedPointC = this.rotatePoint(center, { x: d.target.x - d.source.x + n.x - n1.x, y: d.target.y - d.source.y + n.y - n1.y }, angle), rotatedPointD = this.rotatePoint(center, { x: 0 + n.x - n1.x, y: 0 + n.y - n1.y }, angle);
702
- return ('M ' +
703
- rotatedPointA.x +
704
- ' ' +
705
- rotatedPointA.y +
706
- ' L ' +
707
- rotatedPointB.x +
708
- ' ' +
709
- rotatedPointB.y +
710
- ' L ' +
711
- rotatedPointC.x +
712
- ' ' +
713
- rotatedPointC.y +
714
- ' L ' +
715
- rotatedPointD.x +
716
- ' ' +
717
- rotatedPointD.y +
718
- ' Z');
719
- });
720
- }
721
- tickRelationshipsTexts() {
722
- this.relationshipText.attr('transform', d => {
723
- var angle = (this.rotation(d.source, d.target) + 360) % 360, mirror = angle > 90 && angle < 270, center = { x: 0, y: 0 }, n = this.unitaryNormalVector(d.source, d.target), nWeight = mirror ? 2 : -3, point = {
724
- x: (d.target.x - d.source.x) * 0.5 + n.x * nWeight,
725
- y: (d.target.y - d.source.y) * 0.5 + n.y * nWeight
726
- }, rotatedPoint = this.rotatePoint(center, point, angle);
727
- return 'translate(' + rotatedPoint.x + ', ' + rotatedPoint.y + ') rotate(' + (mirror ? 180 : 0) + ')';
728
- });
729
- }
730
- toString(d) {
731
- var s = d.labels ? d.labels[0] : d.type;
732
- s += ' (<id>: ' + d.id;
733
- Object.keys(d.properties).forEach(function (property) {
734
- s += ', ' + property + ': ' + JSON.stringify(d.properties[property]);
735
- });
736
- s += ')';
737
- return s;
738
- }
739
- unitaryNormalVector(source, target, newLength) {
740
- var center = { x: 0, y: 0 }, vector = this.unitaryVector(source, target, newLength);
741
- return this.rotatePoint(center, vector, 90);
742
- }
743
- unitaryVector(source, target, newLength) {
744
- var length = Math.sqrt(Math.pow(target.x - source.x, 2) + Math.pow(target.y - source.y, 2)) / Math.sqrt(newLength || 1);
745
- return {
746
- x: (target.x - source.x) / length,
747
- y: (target.y - source.y) / length
748
- };
749
- }
750
- updateWithD3Data(d3Data) {
751
- this.updateNodesAndRelationships(d3Data.nodes, d3Data.relationships);
752
- }
753
- updateWithGraphData(graphData) {
754
- var d3Data = this.graphDataToD3Data(graphData);
755
- this.updateWithD3Data(d3Data);
756
- }
757
- updateInfo(d) {
758
- this.clearInfo();
759
- if (d.labels) {
760
- this.appendInfoElementClass('class', d.labels[0]);
761
- }
762
- else {
763
- this.appendInfoElementRelationship('class', d.type);
764
- }
765
- this.appendInfoElementProperty('property', '&lt;id&gt;', d.id);
766
- Object.keys(d.properties).forEach(property => {
767
- this.appendInfoElementProperty('property', property, JSON.stringify(d.properties[property]));
768
- });
769
- }
770
- updateNodes(n) {
771
- Array.prototype.push.apply(this.nodes, n);
772
- this.node = this.svgNodes.selectAll('.node').data(this.nodes, d => {
773
- return d.id;
774
- });
775
- var nodeEnter = this.appendNodeToGraph();
776
- this.node = nodeEnter.merge(this.node);
777
- }
778
- updateNodesAndRelationships(n, r) {
779
- this.updateRelationships(r);
780
- this.updateNodes(n);
781
- this.simulation.nodes(this.nodes);
782
- this.simulation.force('link').links(this.relationships);
783
- }
784
- updateRelationships(r) {
785
- Array.prototype.push.apply(this.relationships, r);
786
- this.relationship = this.svgRelationships.selectAll('.relationship').data(this.relationships, d => {
787
- return d.id;
788
- });
789
- var relationshipEnter = this.appendRelationshipToGraph();
790
- this.relationship = relationshipEnter.relationship.merge(this.relationship);
791
- this.relationshipOutline = this.svg.selectAll('.relationship .outline');
792
- this.relationshipOutline = relationshipEnter.outline.merge(this.relationshipOutline);
793
- this.relationshipOverlay = this.svg.selectAll('.relationship .overlay');
794
- this.relationshipOverlay = relationshipEnter.overlay.merge(this.relationshipOverlay);
795
- this.relationshipText = this.svg.selectAll('.relationship .text');
796
- this.relationshipText = relationshipEnter.text.merge(this.relationshipText);
797
- }
798
- zoomFit(transitionDuration) {
799
- var bounds = this.svg.node().getBBox(), parent = this.svg.node().parentElement.parentElement, fullWidth = parent.clientWidth, fullHeight = parent.clientHeight, width = bounds.width, height = bounds.height, midX = bounds.x + width / 2, midY = bounds.y + height / 2;
800
- if (width === 0 || height === 0) {
801
- return; // nothing to fit
802
- }
803
- this.svgScale = 0.85 / Math.max(width / fullWidth, height / fullHeight);
804
- this.svgTranslate = [fullWidth / 2 - this.svgScale * midX, fullHeight / 2 - this.svgScale * midY];
805
- this.svg.attr('transform', 'translate(' + this.svgTranslate[0] + ', ' + this.svgTranslate[1] + ') scale(' + this.svgScale + ')');
806
- }
807
- }
808
- //# sourceMappingURL=graph-viewer-old.js.map