/
Force Graph - Year.html
111 lines (104 loc) · 4.78 KB
/
Force Graph - Year.html
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
<!DOCTYPE html>
<meta charset="utf-8">
<!-- modified from https://gist.github.com/timelyportfolio/5049980/ !-->
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
var width = 750,
height = 750;
var color = ["#efc021", "#d65108", "#007aa3"];
var force = d3.layout.force()
.charge(-30)
.linkDistance(15)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().on("zoom", function () {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
}))
.on("dblclick.zoom", null)
.append("g");
var year = window.location.href.slice(-4); //Set var year is the last 4 characters of the URL
if (year == 1973){
var csv = "Force Graph CSV/Force Graph Years - 1973.csv"}
if (year == 1974){
var csv = "Force Graph CSV/Force Graph Years - 1974.csv"}
if (year == 1975){
var csv = "Force Graph CSV/Force Graph Years - 1975.csv"}
d3.csv(csv, function (data) {
//set up graph in same style as original example but empty
graph = { "nodes": [], "links": [] };
//loop through each link record from the csv data
//add to the nodes each source and target; we'll reduce to unique values later
//add to the links each source, target record with the value (if desired, multiple value fields can be added)
data.forEach(function (d) {
graph.nodes.push({ "name": d.sourceID, "group": +d.groupsource, "url": d.sourceID, "nodesize":+d.sourceValue, "label": d.source});
graph.nodes.push({ "name": d.targetID, "group": +d.grouptarget, "url": d.targetID, "nodesize":+d.targetValue, "label": d.target});
graph.links.push({ "source": d.sourceID, "target": d.targetID, "value": +d.value });
});
//use this as temporary holding while we manipulate graph.nodes
//this will contain a map object containing an object for each node
//within each node object there will be a child object for each instance that node appear
//however, using rollup we can eliminate this duplication
var nodesmap = d3.nest()
.key(function (d) { return d.name; })
.rollup(function (d) { return { "name": d[0].label, "group": d[0].group, "url": d[0].url, "nodesize": d[0].nodesize}; })
.map(graph.nodes);
//thanks Mike Bostock https://groups.google.com/d/msg/d3-js/pl297cFtIQk/Eso4q_eBu1IJ
//this handy little function returns only the distinct / unique nodes
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));
//it appears d3 with force layout wants a numeric source and target
//so loop through each link replacing the text with its index from node
graph.links.forEach(function (d, i) {
graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});
//this is not in the least bit pretty
//will get graph.nodes in its final useable form
//loop through each unique node and replace with an object with same numeric key and name/group as properties
//that will come from the nodesmap that we defined earlier
graph.nodes.forEach(function (d,i) { graph.nodes[i]={ "name": nodesmap[d].name, "group": nodesmap[d].group, "url": nodesmap[d].url, "nodesize": nodesmap[d].nodesize }; })
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function (d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", function (d) { return Math.sqrt(d.nodesize * 10); })
.style("fill", function (d) { return color[d.group-1]; })
.on("dblclick", function(d) {window.open("http://heurist.sydney.edu.au/h4/records/view/renderRecordData.php?db=lmatt_MIMC&recID=" + d.url,"_blank");})
.call(force.drag);
node.append("title")
.text(function (d) { return d.name; });
force.on("tick", function () {
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; });
node.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; });
});
});
</script>
</body>
</html>