1
|
|
|
import { DependencyLink, DependencyNode, Network } from '../components/types'; |
2
|
|
|
import { |
3
|
|
|
createSimulation, |
4
|
|
|
createSVGContainer, |
5
|
|
|
createZoom, |
6
|
|
|
generateLabelPath, |
7
|
|
|
generateMarkers, |
8
|
|
|
generateLinkPath, |
9
|
|
|
getLabelTextDimensions, |
10
|
|
|
handleDrag, |
11
|
|
|
} from './helpers/GraphHelpers'; |
12
|
|
|
|
13
|
|
|
export const draw = (network: Network, container: HTMLDivElement) => { |
14
|
|
|
const { nodes, links } = network; |
15
|
|
|
|
16
|
|
|
const width = container.clientWidth + 500; |
17
|
|
|
const height = container.clientHeight + 500; |
18
|
|
|
|
19
|
|
|
const simulation = createSimulation(nodes, links, width, height); |
20
|
|
|
const svgContainer = createSVGContainer(container, width, height); |
21
|
|
|
|
22
|
|
|
const zoomLayer = createZoom(svgContainer); |
23
|
|
|
|
24
|
|
|
generateMarkers(svgContainer); |
25
|
|
|
|
26
|
|
|
const linkElements = zoomLayer |
27
|
|
|
.append('g') |
28
|
|
|
.attr('id', 'links') |
29
|
|
|
.selectAll<Element, DependencyLink>('line.link') |
30
|
|
|
.data(links) |
31
|
|
|
.enter() |
32
|
|
|
.append<Element>('svg:path') |
33
|
|
|
.attr('class', 'link') |
34
|
|
|
.attr('marker-end', 'url(#provider)') |
35
|
|
|
.style('stroke-width', 1) |
36
|
|
|
.attr('stroke-opacity', 0.12); |
37
|
|
|
|
38
|
|
|
const labelNodes = zoomLayer.append('g').attr('id', 'labels'); |
39
|
|
|
|
40
|
|
|
labelNodes |
41
|
|
|
.selectAll<Element, DependencyNode>('g#labels') |
42
|
|
|
.data(nodes) |
43
|
|
|
.enter() |
44
|
|
|
.append<SVGGElement>('g') |
45
|
|
|
.call(handleDrag(simulation)) |
46
|
|
|
.append('text') |
47
|
|
|
.attr('fill', '#5E6063') |
48
|
|
|
.attr('cursor', 'default') |
49
|
|
|
.text(d => d.name); |
50
|
|
|
|
51
|
|
|
labelNodes |
52
|
|
|
.selectAll('g') |
53
|
|
|
.data(nodes) |
54
|
|
|
.append<SVGPathElement>('svg:path') |
55
|
|
|
.attr('class', 'label') |
56
|
|
|
.attr('fill', '#dcdee0') |
57
|
|
|
.attr('d', generateLabelPath); |
58
|
|
|
|
59
|
|
|
simulation.on('tick', () => { |
60
|
|
|
linkElements.each(generateLinkPath); |
61
|
|
|
|
62
|
|
|
labelNodes |
63
|
|
|
.selectAll('text') |
64
|
|
|
.data(nodes) |
65
|
|
|
.attr('x', (node: DependencyNode) => (node.x ? node.x : null)) |
66
|
|
|
.attr('y', (node: DependencyNode) => (node.y ? node.y : null)); |
67
|
|
|
|
68
|
|
|
labelNodes |
69
|
|
|
.selectAll<Element, DependencyNode>('path') |
70
|
|
|
.attr('transform', (node: DependencyNode) => |
71
|
|
|
node.x && node.y ? 'translate(' + (node.x - 30) + ',' + (node.y - 55) + ')' : null |
72
|
|
|
) |
73
|
|
|
.lower(); |
74
|
|
|
}); |
75
|
|
|
|
76
|
|
|
return svgContainer.node(); |
77
|
|
|
}; |
78
|
|
|
|