Skip to content

Instantly share code, notes, and snippets.

@JohnCoogan
Created December 5, 2012 04:01
Show Gist options
  • Save JohnCoogan/4212091 to your computer and use it in GitHub Desktop.
Save JohnCoogan/4212091 to your computer and use it in GitHub Desktop.
Visualizing My Twitter Graph
{
"directed": false,
"graph": [],
"links": [
{
"source": 0,
"target": 6
},
{
"source": 0,
"target": 13
},
{
"source": 0,
"target": 24
},
{
"source": 0,
"target": 14
},
{
"source": 0,
"target": 15
},
{
"source": 0,
"target": 9
},
{
"source": 0,
"target": 23
},
{
"source": 0,
"target": 10
},
{
"source": 0,
"target": 16
},
{
"source": 0,
"target": 21
},
{
"source": 0,
"target": 7
},
{
"source": 0,
"target": 17
},
{
"source": 1,
"target": 8
},
{
"source": 1,
"target": 4
},
{
"source": 2,
"target": 14
},
{
"source": 2,
"target": 6
},
{
"source": 2,
"target": 23
},
{
"source": 2,
"target": 22
},
{
"source": 2,
"target": 19
},
{
"source": 2,
"target": 18
},
{
"source": 2,
"target": 11
},
{
"source": 2,
"target": 10
},
{
"source": 2,
"target": 3
},
{
"source": 2,
"target": 17
},
{
"source": 2,
"target": 21
},
{
"source": 3,
"target": 5
},
{
"source": 3,
"target": 9
},
{
"source": 4,
"target": 24
},
{
"source": 4,
"target": 20
},
{
"source": 4,
"target": 9
},
{
"source": 4,
"target": 8
},
{
"source": 4,
"target": 17
},
{
"source": 5,
"target": 13
},
{
"source": 5,
"target": 24
},
{
"source": 5,
"target": 14
},
{
"source": 5,
"target": 15
},
{
"source": 5,
"target": 21
},
{
"source": 5,
"target": 9
},
{
"source": 5,
"target": 23
},
{
"source": 5,
"target": 10
},
{
"source": 5,
"target": 6
},
{
"source": 5,
"target": 7
},
{
"source": 6,
"target": 19
},
{
"source": 6,
"target": 13
},
{
"source": 6,
"target": 7
},
{
"source": 6,
"target": 11
},
{
"source": 6,
"target": 24
},
{
"source": 6,
"target": 14
},
{
"source": 6,
"target": 22
},
{
"source": 6,
"target": 15
},
{
"source": 6,
"target": 8
},
{
"source": 6,
"target": 9
},
{
"source": 6,
"target": 23
},
{
"source": 6,
"target": 18
},
{
"source": 6,
"target": 10
},
{
"source": 6,
"target": 16
},
{
"source": 6,
"target": 21
},
{
"source": 6,
"target": 12
},
{
"source": 6,
"target": 17
},
{
"source": 7,
"target": 13
},
{
"source": 7,
"target": 24
},
{
"source": 7,
"target": 14
},
{
"source": 7,
"target": 15
},
{
"source": 7,
"target": 25
},
{
"source": 7,
"target": 9
},
{
"source": 7,
"target": 23
},
{
"source": 7,
"target": 18
},
{
"source": 7,
"target": 10
},
{
"source": 7,
"target": 21
},
{
"source": 7,
"target": 17
},
{
"source": 9,
"target": 13
},
{
"source": 9,
"target": 18
},
{
"source": 9,
"target": 24
},
{
"source": 9,
"target": 14
},
{
"source": 9,
"target": 15
},
{
"source": 9,
"target": 23
},
{
"source": 9,
"target": 10
},
{
"source": 9,
"target": 16
},
{
"source": 9,
"target": 25
},
{
"source": 9,
"target": 21
},
{
"source": 9,
"target": 17
},
{
"source": 10,
"target": 24
},
{
"source": 10,
"target": 12
},
{
"source": 10,
"target": 14
},
{
"source": 10,
"target": 13
},
{
"source": 10,
"target": 15
},
{
"source": 10,
"target": 18
},
{
"source": 10,
"target": 16
},
{
"source": 10,
"target": 23
},
{
"source": 10,
"target": 17
},
{
"source": 10,
"target": 25
},
{
"source": 10,
"target": 21
},
{
"source": 12,
"target": 15
},
{
"source": 12,
"target": 14
},
{
"source": 12,
"target": 23
},
{
"source": 12,
"target": 25
},
{
"source": 12,
"target": 21
},
{
"source": 13,
"target": 24
},
{
"source": 13,
"target": 15
},
{
"source": 13,
"target": 21
},
{
"source": 13,
"target": 23
},
{
"source": 13,
"target": 14
},
{
"source": 13,
"target": 18
},
{
"source": 13,
"target": 16
},
{
"source": 13,
"target": 17
},
{
"source": 14,
"target": 15
},
{
"source": 14,
"target": 21
},
{
"source": 14,
"target": 24
},
{
"source": 14,
"target": 23
},
{
"source": 14,
"target": 18
},
{
"source": 15,
"target": 24
},
{
"source": 15,
"target": 23
},
{
"source": 15,
"target": 18
},
{
"source": 15,
"target": 21
},
{
"source": 16,
"target": 24
},
{
"source": 16,
"target": 18
},
{
"source": 16,
"target": 21
},
{
"source": 17,
"target": 24
},
{
"source": 17,
"target": 18
},
{
"source": 17,
"target": 21
},
{
"source": 17,
"target": 23
},
{
"source": 18,
"target": 24
},
{
"source": 18,
"target": 23
},
{
"source": 18,
"target": 25
},
{
"source": 19,
"target": 22
},
{
"source": 21,
"target": 24
},
{
"source": 21,
"target": 23
},
{
"source": 21,
"target": 25
},
{
"source": 23,
"target": 24
},
{
"source": 24,
"target": 25
}
],
"multigraph": false,
"nodes": [
{
"degree": 496,
"degree_cent": 0.006775771153793612,
"eigen_cent": 0.243840711008099,
"followers_count": 251,
"following": true,
"friends_count": 489,
"id": "311428321",
"indegree": 7,
"name": "Brian Martinez",
"outdegree": 489,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2701060960/c6229cd327c2f1558a7c21094e0e7b0a_normal.png",
"screen_name": "BC_Martinez"
},
{
"degree": 2102,
"degree_cent": 0.02871506242998825,
"eigen_cent": 0.07190881386987996,
"followers_count": 2615,
"following": true,
"friends_count": 2100,
"id": "103917660",
"indegree": 2,
"name": "David Jacobs",
"outdegree": 2100,
"partition": 2,
"profile_image_url": "http://a0.twimg.com/profile_images/624905068/avatar_fullsize_normal.jpeg",
"screen_name": "MetaThis"
},
{
"degree": 225,
"degree_cent": 0.0030736865112975056,
"eigen_cent": 0.19114884408778857,
"followers_count": 247,
"following": true,
"friends_count": 198,
"id": "243869548",
"indegree": 27,
"name": "David Renteln",
"outdegree": 198,
"partition": 9,
"profile_image_url": "http://a0.twimg.com/profile_images/1931870271/twitter_default_3_normal.jpg",
"screen_name": "Dteln"
},
{
"degree": 565,
"degree_cent": 0.007718368350591514,
"eigen_cent": 0.06106063048434986,
"followers_count": 824,
"following": true,
"friends_count": 561,
"id": "48008960",
"indegree": 4,
"name": "Evan M. Rose",
"outdegree": 561,
"partition": 17,
"profile_image_url": "http://a0.twimg.com/profile_images/1974026484/emr_linkedin_normal.jpg",
"screen_name": "evanmrose"
},
{
"degree": 3461,
"degree_cent": 0.047280128958225184,
"eigen_cent": 0.1068051662842218,
"followers_count": 9053,
"following": true,
"friends_count": 3434,
"id": "16061930",
"indegree": 27,
"name": "Jeff Hammerbacher",
"outdegree": 3434,
"partition": 13,
"profile_image_url": "http://a0.twimg.com/profile_images/2888888777/d9dd0d9a3d7236cb27b90e07bf15d281_normal.jpeg",
"screen_name": "hackingdata"
},
{
"degree": 1628,
"degree_cent": 0.02223982951285484,
"eigen_cent": 0.194851298393719,
"followers_count": 2259,
"following": true,
"friends_count": 1617,
"id": "310050530",
"indegree": 11,
"name": "Jack West",
"outdegree": 1617,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1379691054/JackProfile_normal.JPG",
"screen_name": "JackCWest"
},
{
"degree": 442,
"degree_cent": 0.006038086391082211,
"eigen_cent": 0.34289860979141984,
"followers_count": 367,
"following": true,
"friends_count": 422,
"id": "182927076",
"indegree": 20,
"name": "Drop Some Knowledge",
"outdegree": 422,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2757083762/b7b3ee9956e4e00dcf5137905876b34c_normal.png",
"screen_name": "PlayDSK"
},
{
"degree": 619,
"degree_cent": 0.008456053113302915,
"eigen_cent": 0.2788273614544869,
"followers_count": 635,
"following": true,
"friends_count": 606,
"id": "344781168",
"indegree": 13,
"name": "betaclassroom",
"outdegree": 606,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1505792330/TImage_normal.png",
"screen_name": "betaclassroom"
},
{
"degree": 797,
"degree_cent": 0.01088768066446272,
"eigen_cent": 0.0642734758828458,
"followers_count": 6912,
"following": true,
"friends_count": 777,
"id": "15540222",
"indegree": 20,
"name": "Guillermo Rauch",
"outdegree": 777,
"partition": 3,
"profile_image_url": "http://a0.twimg.com/profile_images/1867093513/photo_normal.png",
"screen_name": "rauchg"
},
{
"degree": 595,
"degree_cent": 0.008128193218764514,
"eigen_cent": 0.17232885449494298,
"followers_count": 5423,
"following": true,
"friends_count": 577,
"id": "274793711",
"indegree": 18,
"name": "EdSurge",
"outdegree": 577,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1639864764/Live_-_v4-notext_normal.png",
"screen_name": "EdSurge"
},
{
"degree": 316,
"degree_cent": 0.004316821944755607,
"eigen_cent": 0.3099137538495145,
"followers_count": 192,
"following": true,
"friends_count": 306,
"id": "720931356",
"indegree": 10,
"name": "SmarterCookie",
"outdegree": 306,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2581769378/wxhbirmnsx2rnm009525_normal.jpeg",
"screen_name": "smartercookie"
},
{
"degree": 2005,
"degree_cent": 0.027389962022895547,
"eigen_cent": 0.06383191642120138,
"followers_count": 925,
"following": true,
"friends_count": 2001,
"id": "69618874",
"indegree": 4,
"name": "Clare Sayas",
"outdegree": 2001,
"partition": 16,
"profile_image_url": "http://a0.twimg.com/profile_images/2917667269/94997b4130187aab4b53ae373ff77468_normal.jpeg",
"screen_name": "claresayas"
},
{
"degree": 59,
"degree_cent": 0.0008059889074069015,
"eigen_cent": 0.11069252634947015,
"followers_count": 47,
"following": true,
"friends_count": 53,
"id": "573273555",
"indegree": 6,
"name": "Tess Brustein",
"outdegree": 53,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2197505142/kristin_and_me_normal.jpg",
"screen_name": "tbrustein"
},
{
"degree": 581,
"degree_cent": 0.007936941613617115,
"eigen_cent": 0.1411386124031156,
"followers_count": 786,
"following": true,
"friends_count": 567,
"id": "18739136",
"indegree": 14,
"name": "Jessie Arora",
"outdegree": 567,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1879603558/photo__14__normal.jpg",
"screen_name": "Jessie_Arora"
},
{
"degree": 792,
"degree_cent": 0.01081937651976722,
"eigen_cent": 0.25407143725002423,
"followers_count": 1577,
"following": true,
"friends_count": 780,
"id": "14609431",
"indegree": 12,
"name": "Robert Pronovost",
"outdegree": 780,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2808327100/c186617396f5a9c0ea990f2098a76e20_normal.png",
"screen_name": "pronovost"
},
{
"degree": 69,
"degree_cent": 0.0009425971967979016,
"eigen_cent": 0.15377448495430635,
"followers_count": 1431,
"following": true,
"friends_count": 56,
"id": "267753999",
"indegree": 13,
"name": "Imagine K12",
"outdegree": 56,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2695170892/e1f00aa91536c116e330189b3e872a92_normal.jpeg",
"screen_name": "imaginek12"
},
{
"degree": 236,
"degree_cent": 0.003223955629627606,
"eigen_cent": 0.07082109871675088,
"followers_count": 412,
"following": true,
"friends_count": 231,
"id": "39029972",
"indegree": 5,
"name": "Jeff Scheur",
"outdegree": 231,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1814517078/P1010011_2_normal.JPG",
"screen_name": "jscheur"
},
{
"degree": 1682,
"degree_cent": 0.02297751427556624,
"eigen_cent": 0.1872126505180465,
"followers_count": 1701,
"following": true,
"friends_count": 1669,
"id": "14155782",
"indegree": 13,
"name": "Michael Staton",
"outdegree": 1669,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1834673971/Staton_Twitter_Pic_normal.jpg",
"screen_name": "mpstaton"
},
{
"degree": 1070,
"degree_cent": 0.014617086964837026,
"eigen_cent": 0.21792485467808734,
"followers_count": 807,
"following": true,
"friends_count": 1060,
"id": "17831644",
"indegree": 10,
"name": "Daniel Jhin Yoo",
"outdegree": 1060,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1552742813/techcrunch_about_me_square_normal.png",
"screen_name": "danieljyoo"
},
{
"degree": 832,
"degree_cent": 0.01136580967733122,
"eigen_cent": 0.0633385771732664,
"followers_count": 296,
"following": true,
"friends_count": 825,
"id": "15987934",
"indegree": 7,
"name": "Brigitte Bradford",
"outdegree": 825,
"partition": 21,
"profile_image_url": "http://a0.twimg.com/profile_images/2737307107/03ffbc940235021aa83f697b3eeec489_normal.jpeg",
"screen_name": "brig42"
},
{
"degree": 1056,
"degree_cent": 0.014425835359689625,
"eigen_cent": 0.061510680166126125,
"followers_count": 9768,
"following": true,
"friends_count": 1042,
"id": "14344469",
"indegree": 14,
"name": "Peter Skomoroch",
"outdegree": 1042,
"partition": 13,
"profile_image_url": "http://a0.twimg.com/profile_images/2862590929/a9fe716b562b57480a6052c5aba15b1c_normal.jpeg",
"screen_name": "peteskomoroch"
},
{
"degree": 354,
"degree_cent": 0.004835933444441409,
"eigen_cent": 0.2181072802446081,
"followers_count": 384,
"following": true,
"friends_count": 341,
"id": "18576413",
"indegree": 13,
"name": "Amy Lin",
"outdegree": 341,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1871590274/twitterpic_normal.png",
"screen_name": "heyamylin"
},
{
"degree": 219,
"degree_cent": 0.0029917215376629052,
"eigen_cent": 0.07666831053821732,
"followers_count": 125,
"following": true,
"friends_count": 209,
"id": "364495209",
"indegree": 10,
"name": "Jacob Makler",
"outdegree": 209,
"partition": 18,
"profile_image_url": "http://a0.twimg.com/profile_images/1657573700/15000_1267119842707_1371120100_30605281_3806364_n_normal.jpg",
"screen_name": "JPmakler"
},
{
"degree": 281,
"degree_cent": 0.003838692931887107,
"eigen_cent": 0.29728621261644617,
"followers_count": 104,
"following": true,
"friends_count": 271,
"id": "24399559",
"indegree": 10,
"name": "Kasey Brown",
"outdegree": 271,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2350558628/fccgxw1xeywigsrmgxin_normal.jpeg",
"screen_name": "digitwhiz"
},
{
"degree": 591,
"degree_cent": 0.008073549903008114,
"eigen_cent": 0.2501744854809419,
"followers_count": 309,
"following": true,
"friends_count": 580,
"id": "23357834",
"indegree": 11,
"name": "Anthony Wu",
"outdegree": 580,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/2183843281/fb_profile_normal.jpg",
"screen_name": "anthonywu"
},
{
"degree": 148,
"degree_cent": 0.0020218026829868035,
"eigen_cent": 0.11215757100267687,
"followers_count": 67,
"following": true,
"friends_count": 144,
"id": "505239133",
"indegree": 4,
"name": "Gary Tsai",
"outdegree": 144,
"partition": 1,
"profile_image_url": "http://a0.twimg.com/profile_images/1856614632/IMG_0010_6_normal.JPG",
"screen_name": "GMTsai"
}
],
"user": [{
"followers_count": 427,
"following": false,
"friends_count": 180,
"name": "John Coogan",
"profile_image_url": "http://a0.twimg.com/profile_images/2054496309/image_normal.jpg",
"screen_name": "johncoogan"
}]
}
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v2.min.js?2.9.3"></script>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 0;
position: absolute;
width: 960px;
height: 500px;
font-size: 14px;
}
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
}
.nodetext {
font-size: 24px;
}
.title {
font-size: 34px;
}
.sizeby {
font-size: 18px;
}
.sizenote {
font-size: 15px;
}
.rankingtext {
font-size: 16px;
}
.rankingtitle {
font-size: 28px;
}
.rankingnum {
font-size: 16px;
}
.clickfortwitter {
font-size: 18px;
}
form {
position: absolute;
left: 10px;
top: 353px;
font-size: 20px;
}
.highlight {
stroke-width: 3px !important;
stroke: #000 !important;
}
</style>
<body>
<form>
<label><input type="radio" name="mode" value="eigen" checked="checked"> Eigenvector</label>
<label><input type="radio" name="mode" value="degree"> Degree</label>
</form>
<script>
var w = 960,
h = 500,
l = 265,
svg,
force,
link,
node,
clip,
graph,
graphData,
max,
nodes,
metric = "eigen_cent",
eigen_scale = 0.7,
degree_scale = 5,
scale = eigen_scale;
var color = d3.scale.category20();
function showNodeDetails() {
return function(d, i) {
svg.selectAll(".nodetext").remove();
labels = [];
labels.push("" + d['name'], "@" + d['screen_name'], "Following: " + d['friends_count'], "Followers: " + d['followers_count'], "Eigenvector: " + d['eigen_cent'].toFixed(4), "Degree: " + d['degree_cent'].toFixed(4))
setDetailLabels(labels);
graph.selectAll(".circle")
.transition()
.duration(100)
.attr("fill-opacity", 0.5);
graph.selectAll("image")
.transition()
.duration(100)
.attr("style", "opacity: .5;");
d3.select("." + d.screen_name).selectAll("image")
.transition()
.duration(100)
.attr("style", "opacity: 1;");
d3.select("." + d.screen_name).selectAll("circle")
.transition()
.duration(100)
.attr("class", "circle highlight")
.attr("fill-opacity", 1);
d3.select(".id" + d.id)
.attr("fill", "#F00");
}
}
function setDetailLabels(labels) {
svg.selectAll(".nodetext").remove();
svg.selectAll("text.nodetext").data(labels).enter().append("svg:text")
.attr("class", "nodetext")
.text(function() { return this.__data__; })
.attr("x", 10)
.attr("y", function(d, i){ return (this.getBBox().height * 1.2) * (i+3.2)});
}
function resetDetailLabels() {
svg.selectAll(".nodetext").remove();
labels = ["Hover on a circle", "to see details", "Following: ", "Followers: ", "Eigenvector: ", "Degree: "];
setDetailLabels(labels);
}
function removeNodeDetails() {
return function(d, i) {
resetDetailLabels();
graph.selectAll(".circle")
.transition()
.attr("fill-opacity", 1);
graph.selectAll("image")
.transition()
.attr("style", "opacity: 1;");
d3.select("." + d.screen_name).selectAll("circle")
.attr("class", "circle");
d3.select(".id" + d.id)
.attr("fill", "#000");
}
}
function followLink() {
return function(d) {
window.open("http://twitter.com/"+d['screen_name'])
}
}
function sizeBy(metric, scale) {
for (var i = 0; i < nodes.length; i++) {
nodes[i]['radius'] = Math.sqrt(nodes[i][metric] * scale) * 110;
};
force.start();
graph.selectAll(".clipping")
.transition()
.duration(2000)
.attr("x", function(d) { return Math.sqrt(d[metric] * scale) * -75; })
.attr("y", function(d) { return Math.sqrt(d[metric] * scale) * -75; })
.attr("rx", function(d) { return Math.sqrt(d[metric] * scale) * 20; })
.attr("ry", function(d) { return Math.sqrt(d[metric] * scale) * 20; })
.attr("width", function(d) { return Math.sqrt(d[metric] * scale) * 150; })
.attr("height", function(d) { return Math.sqrt(d[metric] * scale) * 150; })
graph.selectAll(".circle")
.transition()
.duration(2000)
.attr("x", function(d) { return Math.sqrt(d[metric] * scale) * -90; })
.attr("y", function(d) { return Math.sqrt(d[metric] * scale) * -90; })
.attr("width", function(d) { return Math.sqrt(d[metric] * scale) * 180; })
.attr("height", function(d) { return Math.sqrt(d[metric] * scale) * 180; })
.attr("rx", function(d) { return Math.sqrt(d[metric] * scale) * 20; })
.attr("ry", function(d) { return Math.sqrt(d[metric] * scale) * 20; })
graph.selectAll("image")
.transition()
.duration(2000)
.attr("x", function(d) { return Math.sqrt(d[metric] * scale) * -75; })
.attr("y", function(d) { return Math.sqrt(d[metric] * scale) * -75; })
.attr("width", function(d) { return Math.sqrt(d[metric] * scale) * 150; })
.attr("height", function(d) { return Math.sqrt(d[metric] * scale) * 150; });
transitionRanking(metric);
}
d3.selectAll("input").on("change", function change() {
if (this.value === "eigen") sizeBy("eigen_cent", eigen_scale);
else sizeBy("degree_cent", degree_scale);
});
svg = d3.select("body").append("svg")
.attr("width", w + l - 25)
.attr("height", h)
.style("border", "3px solid #000");
graph = svg.append("g")
.attr("transform", "translate(" + l + ",10)");
function drawGraph() {
d3.json("graph.json", function(json) {
nodes = json.nodes;
graphData = json;
json.user[0]["degree_cent"] = nodes.sort(function(a,b) { return b["degree_cent"] - a["degree_cent"] } )[0]["degree_cent"] * 1.2;
json.user[0]["eigen_cent"] = nodes.sort(function(a,b) { return b["eigen_cent"] - a["eigen_cent"] } )[0]["eigen_cent"] * 1.2;
json.user[0]["partition"] = 0;
nodes.unshift(json.user[0]);
for (var i = 0; i < nodes.length; i++) {
nodes[i]['radius'] = Math.sqrt(nodes[i][metric] * scale) * 110;
};
force = d3.layout.force()
.gravity(0.05)
.charge(0)
.nodes(nodes)
.friction(0.1)
.size([w-l, h]);
force.start();
node = graph.selectAll(".node")
.data(nodes)
.enter().append("svg:g")
.attr("r", function(d) { return Math.sqrt(d[metric] * scale) * 90; })
.attr("class", function(d) { return "node " + d['screen_name']; })
.on("mouseover", showNodeDetails())
.on("mouseout", removeNodeDetails())
.on("click", followLink())
.call(force.drag);
clip = node.append("defs").append("svg:clipPath")
.attr("id", function(d) { return "clip-" + d['screen_name']; })
.append("svg:rect")
.attr("id", "clip-rect")
.attr("class", "clipping");
node.append("svg:rect")
.style("fill", function(d) { return color(d.partition); })
.style("stroke", "#000")
.style("stroke-width", 1)
.attr("class","circle");
node.append("image")
.attr("xlink:href", function(d) { return d.profile_image_url; })
.attr("clip-path", function(d) { return "url(#clip-" + d['screen_name'] + ")"; });
svg.append("svg:rect")
.attr("class", "rankingBG")
.attr("x", w + 20)
.attr("y", -2)
.attr("width", l)
.attr("height", h + 4)
.style("fill", "#ddd")
.style("stroke", "#000")
.style("stroke-width", 3);
svg.append("svg:text")
.attr("class", "rankingtitle")
.text("Ranking")
.attr("x", w + 88)
.attr("y", 33);
svg.selectAll(".rankingnum")
.data(d3.range(1,31))
.enter().append("svg:text")
.attr("class", "rankingnum")
.text(function(d) { return d + ":"; })
.attr("x", w + 50)
.attr("text-anchor","end")
.attr("y", function(d, i) { return i * 25 + 63; });
drawRanking(graphData);
force.on("tick", function(e) {
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length;
while (++i < n) {
q.visit(collide(nodes[i]));
}
svg.selectAll(".node")
.attr("transform", function(d) { return "translate("+ d.x + "," + d.y + ")";});
});
sizeBy(metric, scale);
});
}
function collide(node) {
var r = (node.radius * 1.2) + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = (node.radius * 1.2) + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
};
}
function redrawGraph() {
d3.selectAll("input")[0][0].checked = true;
d3.selectAll("input")[0][1].checked = false;
svg.selectAll(".rankingtext").remove();
svg.selectAll(".rankingnum").remove();
node.remove();
drawGraph();
}
function compareVals(a, b) {
return a < b ? 1 : a == b ? 0 : -1;
}
function drawRanking(data) {
svg.selectAll(".rankingtext")
.data(data.nodes)
.enter().append("svg:text")
.sort(function (a, b) { return compareVals(a[metric], b[metric]); })
.attr("class", function(d) { return "rankingtext id" + d['id'];} )
.text(function(d, i) { return d['name']; })
.attr("x", w + 63)
.attr("y", function(d, i) { return i * 25 + 63; })
.on("mouseover", showNodeDetails())
.on("mouseout", removeNodeDetails())
.on("click", followLink());
}
function transitionRanking(metric) {
svg.selectAll(".rankingtext")
.sort(function (a, b) { return compareVals(a[metric], b[metric]); })
.transition()
.duration(2000)
.attr("y", function(d, i) { return i * 25 + 63; });
}
function drawLegend() {
svg.append("svg:rect")
.attr("x", -20)
.attr("y", -20)
.attr("width", l)
.attr("height", 320)
.attr("ry", 20)
.style("fill", "#ddd")
.style("stroke", "#000")
.style("stroke-width", 3);
svg.append("svg:text")
.attr("class", "title")
.text("Twitter Graph")
.attr("x", 22)
.attr("y", 40);
svg.append("svg:text")
.attr("class", "title")
.text("Visualization")
.attr("x", 33)
.attr("y", 75);
var o = 25;
svg.append("svg:rect")
.attr("x", -20)
.attr("y", 335 - o)
.attr("width", l)
.attr("height", 180)
.attr("ry", 20)
.style("fill", "#ddd")
.style("stroke", "#000")
.style("stroke-width", 3);
svg.append("svg:text")
.attr("class", "sizeby")
.text("Show size by centrality:")
.attr("x", 10)
.attr("y", 360 - o);
svg.append("svg:text")
.attr("class", "sizenote")
.text("Eigenvector Centrality measures")
.attr("x", 10)
.attr("y", 430 - o);
svg.append("svg:text")
.attr("class", "sizenote")
.text("most similar connections.")
.attr("x", 10)
.attr("y", 450 - o);
svg.append("svg:text")
.attr("class", "sizenote")
.text("Degree Centrality measures")
.attr("x", 10)
.attr("y", 480 - o);
svg.append("svg:text")
.attr("class", "sizenote")
.text("most popular connections.")
.attr("x", 10)
.attr("y", 500 - o);
svg.append("svg:rect")
.attr("x", -20)
.attr("y", 550)
.attr("width", l)
.attr("height", 180)
.attr("ry", 20)
.style("fill", "#ddd")
.style("stroke", "#000")
.style("stroke-width", 3)
.on("click", function(){
redrawGraph();
});
svg.append("svg:text")
.attr("class", "title")
.text("Click to Reset")
.attr("x", 17)
.attr("y", 615)
.on("click", function(){
redrawGraph();
});
svg.append("svg:text")
.attr("class", "clickfortwitter")
.text("Click to see full Twitter profile")
.attr("x", 500)
.attr("y", h - 10);
}
drawGraph();
drawLegend();
resetDetailLabels();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment