Created
September 21, 2013 21:50
-
-
Save dbeach/6654568 to your computer and use it in GitHub Desktop.
Intro to D3 Force Graphs (BeCamp 2013 – Charlottesville, VA)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"_position": 0, | |
"name": "Big Data", | |
"type": "topic", | |
"connections": [3] | |
}, | |
{ | |
"_position": 1, | |
"name": "Search UI", | |
"type": "topic", | |
"connections": [2] | |
}, | |
{ | |
"_position": 2, | |
"name": "Data Visualization", | |
"type": "topic", | |
"connections": [] | |
}, | |
{ | |
"_position": 3, | |
"name": "Data Science", | |
"type": "topic", | |
"connections": [2] | |
}, | |
{ | |
"_position": 4, | |
"name": "Cassandra", | |
"type": "technology", | |
"connections": [0,3] | |
}, | |
{ | |
"_position": 5, | |
"name": "Solr", | |
"type": "technology", | |
"connections": [0,1] | |
}, | |
{ | |
"_position": 6, | |
"name": "D3", | |
"type": "technology", | |
"connections": [2] | |
}, | |
{ | |
"_position": 7, | |
"name": "Lucene", | |
"type": "technology", | |
"connections": [0,3,5] | |
}, | |
{ | |
"_position": 8, | |
"name": "Hadoop", | |
"type": "technology", | |
"connections": [0] | |
}, | |
{ | |
"_position": 9, | |
"name": "Ember JS", | |
"type": "technology", | |
"connections": [1,2] | |
}, | |
{ | |
"_position": 9, | |
"name": "Angular JS", | |
"type": "technology", | |
"connections": [1,2] | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>D3 Force-Graph Visualization</title> | |
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<style> | |
body { | |
font-family: "Lato", "HelveticaNeue-Light", sans-serif; | |
} | |
h1 { | |
text-align: center; | |
padding: 3em 0 1em; | |
} | |
.force-diagram { | |
background: #fbfbfb; | |
text-align: center; | |
color: white; | |
} | |
.force-diagram .link { | |
stroke: #999999; | |
stroke-width: 1px; | |
stroke-opacity: 0.5; | |
} | |
.force-diagram .node { | |
fill: #dddddd; | |
cursor: move; | |
} | |
.force-diagram circle.technology { | |
fill: red; | |
} | |
.force-diagram circle.topic { | |
fill: #999999; | |
fill-opacity: 0; | |
font-weight: 700; | |
font-size: 20px; | |
} | |
.force-diagram text.topic { | |
fill: black; | |
font-weight: 700; | |
font-size: 20px !important; | |
text-anchor: middle; | |
padding-top: 0.5em; | |
font-size: 12px; | |
pointer-events: none; | |
} | |
.force-diagram text.technology { | |
fill: black; | |
text-anchor: start; | |
padding-top: 0.5em; | |
font-size: 12px; | |
pointer-events: none; | |
} | |
</style> | |
<link href='http://fonts.googleapis.com/css?family=Lato:100,400,900' rel='stylesheet' type='text/css'> | |
</head> | |
<body> | |
<h1>D3 Force Graph</h1> | |
<div id="forceGraph" class="force-diagram"> | |
</div> | |
<script> | |
var forceDiagram = function() { | |
var width = $('#forceGraph').innerWidth(), | |
height = width * .3 > 400 ? width * .3 : 400, | |
r = 40; | |
var force = d3.layout.force() | |
.size([width, height]) | |
.charge(-1500) | |
.linkDistance(r * 1.75); | |
var svg = d3.select("#forceGraph").append("svg:svg") | |
.attr("width", width) | |
.attr("height", height); | |
d3.json("data.json", function(error, dataObject) { | |
console.log('dataObject', error, dataObject); | |
var dataObj = { | |
"nodes": [], | |
"links": [] | |
}; | |
console.log("Data Object", dataObj); | |
for (var i=0; i < dataObject.length; i++) { | |
if (i.hasOwnProperty) { | |
var thisNode = dataObject[i]; | |
// console.log("Node", thisNode); | |
dataObj.nodes.push({"name": thisNode.name, "type": thisNode.type}); | |
var links = thisNode.connections, | |
nLinks = links.length || false; | |
if (nLinks && nLinks > 0) { | |
for (var c=0; c < nLinks; c++) { | |
// console.log("Connections ", thisNode.name, i, c); | |
dataObj.links.push({"source": i, "target": links[c]}) | |
} | |
} | |
} | |
} | |
force | |
.nodes(dataObj.nodes) | |
.links(dataObj.links) | |
.start(); | |
force.on("tick", function() { | |
node.attr("transform", function(d) { | |
return "translate(" + | |
Math.max(r, Math.min(width - r, d.x)) + | |
"," + | |
Math.max(r, Math.min(height - r, d.y)) + | |
")"; | |
}); | |
node.attr("cx", function(d) { return d.x = Math.max(r, Math.min(width - r, d.x)); }) | |
.attr("cy", function(d) { return d.y = Math.max(r, Math.min(height - r, d.y)); }); | |
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; }); | |
}); | |
var link = svg.selectAll(".link") | |
.data(dataObj.links) | |
.enter().append("line") | |
.attr("class", "link"); | |
var ifTopic = function(thisNode, yes, no) { | |
if (thisNode.type === "topic") { | |
return yes | |
} | |
else { | |
return no | |
} | |
}; | |
var node = svg.append("g") | |
.attr("class", "node") | |
.selectAll("circle") | |
.data(dataObj.nodes) | |
.enter() | |
.append("g") | |
.call(force.drag) | |
node.append("circle") | |
.attr("class", function(d) {return d.type}) | |
.attr("r", function(d){return ifTopic(d, r, 10)}); | |
node.append("text") | |
.attr("class", function(d) {return d.type}) | |
.attr("x", function(d){return ifTopic(d, 0, 15)}) | |
.attr("y", 5) | |
.text(function(d) { | |
return d.name; | |
}); | |
}); | |
}; | |
forceDiagram(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment