1
|
|
|
import { DependencyLink, DependencyNode } from '../../components/types'; |
2
|
|
|
import { forceCenter, forceCollide, forceLink, forceSimulation, forceY, Simulation } from 'd3-force'; |
3
|
|
|
import { drag } from 'd3-drag'; |
4
|
|
|
import { selectHighLightedNodes } from '../../utils/helpers/Selectors'; |
5
|
|
|
import { event } from 'd3-selection'; |
6
|
|
|
import { hideTooltip, showTooltip } from '../tooltip/tooltip'; |
7
|
|
|
|
8
|
|
|
export function createSimulation(nodes: DependencyNode[], links: DependencyLink[], width: number, height: number) { |
9
|
|
|
return forceSimulation(nodes) |
10
|
|
|
.force( |
11
|
|
|
'dependency', |
12
|
|
|
forceLink<DependencyNode, DependencyLink>(links) |
13
|
|
|
.distance(180) |
14
|
|
|
.id((node: DependencyNode) => node.name) |
15
|
|
|
) |
16
|
|
|
.force('center', forceCenter(width / 2, height / 2)) |
17
|
|
|
.force('y', forceY(0.5)) |
18
|
|
|
.force('collide', forceCollide(140)) |
19
|
|
|
.force('nodeCollide', forceCollide(140)); |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
export function addNodesDrag(simulation: Simulation<DependencyNode, DependencyLink>) { |
23
|
|
|
let isDragStarted = false; |
24
|
|
|
return drag<SVGGElement, DependencyNode>() |
25
|
|
|
.on('start', (node: DependencyNode) => { |
26
|
|
|
if (!selectHighLightedNodes().data().length) { |
27
|
|
|
dragStarted(node, simulation); |
28
|
|
|
isDragStarted = true; |
29
|
|
|
hideTooltip(); |
30
|
|
|
} |
31
|
|
|
}) |
32
|
|
|
.on('drag', (node: DependencyNode) => { |
33
|
|
|
if (isDragStarted) { |
34
|
|
|
dragged(node); |
35
|
|
|
} |
36
|
|
|
}) |
37
|
|
|
.on('end', (node: DependencyNode) => { |
38
|
|
|
dragEnded(node, simulation); |
39
|
|
|
isDragStarted = false; |
40
|
|
|
showTooltip(); |
41
|
|
|
}); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
function dragStarted(node: DependencyNode, simulation: Simulation<DependencyNode, DependencyLink>) { |
45
|
|
|
if (!event.active) { |
46
|
|
|
simulation.alphaTarget(0.3).restart(); |
47
|
|
|
} |
48
|
|
|
node.fx = node.x; |
49
|
|
|
node.fy = node.y; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
function dragged(node: DependencyNode) { |
53
|
|
|
node.fx = event.x; |
54
|
|
|
node.fy = event.y; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
function dragEnded(node: DependencyNode, simulation: Simulation<DependencyNode, DependencyLink>) { |
58
|
|
|
if (!event.active) { |
59
|
|
|
simulation.alphaTarget(0); |
60
|
|
|
} |
61
|
|
|
node.fx = null; |
62
|
|
|
node.fy = null; |
63
|
|
|
} |
64
|
|
|
|