-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathforce.js
131 lines (114 loc) · 3.89 KB
/
force.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Define the dimensions of the Force jsonData
var width = 1500,
height = 800;
// Background color for the png images
var nodeColor = "white";
// Constant for growth on nodes hover
var growthConstant = 1.4;
// Create a SVG container to hold the vizualization
// Specify the dimensions for this container
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// Create a force layout object and define its properties
// 'charge' is how much the nodes push each other off
// 'linkDistance' is the length of the links between the nodes
var force = d3.layout.force()
.charge(-1500)
.linkDistance(180)
.size([width, height]);
// The static data comes from a json file
d3.json("links.json", function(error, jsonData) {
if (error) throw error;
// Turn on the force layout
force
.nodes(jsonData.nodes)
.links(jsonData.links)
.start();
// Draw the SVG lines between the nodes
var link = svg.selectAll(".link")
// Data bind
.data(jsonData.links)
// Enter : for new data
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.diameter); });
// Draw the SVG circles
var node = svg.selectAll(".node")
// Data bind
.data(jsonData.nodes)
// Enter : for new data
.enter()
.append("g").attr("class", "node")
// Apply force.drag to each element
.call(force.drag);
// Append circle to each node
node.append("circle")
.attr("r", function(d) { return (d.diameter/2) })
.style("fill", function(d) { return nodeColor; });
// Append title to each node
node.append("title")
.text(function(d) { return d.name; });
// Append anchor to the nodes so user can click on hyperlink
var anchor = node.append("svg:a")
.attr("xlink:href", function(d) { return d.url; })
.attr("target", "_blank");
// Append image anchor on the nodes
anchor.append("svg:image")
.attr("xlink:href", function(d) { return d.photo; })
.attr("x", function(d) { return -(d.diameter/2); })
.attr("y", function(d) { return -(d.diameter/2); })
.attr("height", function(d) { return d.diameter })
.attr("width", function(d) { return d.diameter });
force.on("tick", function() {
// Update position of the nodes
node.attr("transform", function(d) {
var radius = d.diameter/2;
// Put constraints on the position - within bounds - nodes can't go outside of the box
var xPos = Math.max(radius, Math.min(width - radius, d.x));
var yPos = Math.max(radius, Math.min(height - radius, d.y));
return "translate(" + [xPos, yPos] + ")";
});
// Update the positions of the links
link.attr("x1", function (d) { return d.source.x; })
.attr("y1", function (d) { return d.source.y; })
.attr("x2", function (d) { return d.target.x; })
.attr("y2", function (d) { return d.target.y; });
});
// Mouseover and Mouseout events
node
.on("mouseover", function(d) {
// Enlarge nodes on hover
d3.select(this).selectAll("image")
.transition()
.duration(700)
// modify size and position
.attr({
x : function(d) {
if(!d.centerNode){return -(d.diameter * (growthConstant/2)); }
else{ return -(d.diameter/2); }
},
y : function(d) {
if(!d.centerNode){return -(d.diameter * (growthConstant/2)); }
else{ return -(d.diameter/2); }
},
height:function(d) {
if(!d.centerNode){return (d.diameter * growthConstant); }
else{ return d.diameter; }
},
width : function(d) {
if(!d.centerNode){return (d.diameter * growthConstant); }
else{ return d.diameter; }
}
})
})
// Return to default size and position
.on("mouseout", function() {
d3.select( this).selectAll("image")
.transition()
.attr("x", function(d) { return -(d.diameter/2); })
.attr("y", function(d) { return -(d.diameter/2); })
.attr("height", function(d) { return d.diameter; })
.attr("width", function(d) { return d.diameter; });
})
});