Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Export example from NodeXL
"nodes": [
{"id":0, "name": "Twitter Powered Subtitles for Conference Audio/Videos on Youtube", "url":"", "nodeSize":2.12},
{"id":1, "name": "Twitter Powered Youtube Subtitles, Reprise: Anytime Commenting", "url":"", "nodeSize":1.7},
{"id":2, "name": "Twitter Powered Subtitles for BBC iPlayer Content c/o the MASHe Blog", "url":"", "nodeSize":1.91},
{"id":3, "name": "Scheduling Content Round the Edges – Supporting OU/BBC Co-Productions", "url":"", "nodeSize":1.55},
{"id":4, "name": "Maintaining a Google Calendar from a Google Spreadsheet, Reprise", "url":"", "nodeSize":1.54},
{"id":5, "name": "Reversible, Reverse History and Side-by-Side Storytelling", "url":"", "nodeSize":1.76},
{"id":6, "name": "Multi-Dimensional and Multiple-Perspective Storytelling", "url":"", "nodeSize":1.6},
{"id":7, "name": "Searching the Backchannel – Martin Bean, OU VC, Twitter Captioned at JISC10", "url":"", "nodeSize":2.1},
{"id":8, "name": "BBC iPlayer Gets a New Beta Release, plus Some Thoughts on My Changing TV Habits", "url":"", "nodeSize":2.49},
{"id":9, "name": "uTitle: Anytime Twitter Captioning of Youtube Videos", "url":"", "nodeSize":1.7},
{"id":10, "name": "Backchannel Side Effects – Personal Meeting Notes", "url":"", "nodeSize":1.54},
{"id":11, "name": "Crowd Sourcing a Promotion Case…", "url":"", "nodeSize":1.84},
{"id":12, "name": "Visual UI Editor For Google Apps Script", "url":"", "nodeSize":2.64},
{"id":13, "name": "Twitter + voting/polling + Yahoo Pipes = TwEVS (The Making Of)", "url":"", "nodeSize":1.94},
{"id":14, "name": "Twitter powered subtitles for BBC iPlayer", "url":"", "nodeSize":1.55},
{"id":15, "name": "Searching the backchannel with Twitter subtitles", "url":"", "nodeSize":1.53},
{"id":16, "name": "Convergence @youtube meets @twitter: In timeline commenting of YouTube videos using Twitter [uTitle]", "url":"", "nodeSize":1.54},
{"id":17, "name": "97%* of desktop web browsers can now enjoy iTitle Twitter Subtitling – Vimeo edition", "url":"", "nodeSize":1.73},
{"id":18, "name": "Give it a REST: iTitle/uTitle linking (oh and you can comment on Vimeo vids in uTitle)", "url":"", "nodeSize":1.73},
{"id":19, "name": "Material to support Tony Hirst’s (@psychemedia’s) promotion", "url":"", "nodeSize":2.46},
{"id":20, "name": "iTitle: Full circle with Twitter subtitle playback in YouTube (ALT-C 2010 Keynotes)", "url":"", "nodeSize":1.53},
{"id":21, "name": "Making ripples in a big pond: Optimising videos with an iTitle Twitter track", "url":"", "nodeSize":1.77},
{"id":22, "name": "App, App and Away: Workshop Handout #open4ed #GAS", "url":"", "nodeSize":1.57},
{"id":23, "name": "Automating your inbox with Google Apps Script", "url":"", "nodeSize":1.57},
{"id":24, "name": "My draft application for the ALT Learning Technologist of the Year Award 2011", "url":"", "nodeSize":1.87},
{"id":25, "name": "[Work in Progress] Creating a framework for custom form interfaces using Google Apps Script", "url":"", "nodeSize":1.57},
{"id":26, "name": "Creating Google Charts From CSV Data Inside a Yahoo Pipe", "url":"", "nodeSize":1.59},
{"id":27, "name": "Easier Twitter Powered Subtitles for Youtube Movies", "url":"", "nodeSize":1.83},
{"id":28, "name": "Who’s Tweeting Our Hashtag?", "url":"", "nodeSize":1.87},
{"id":29, "name": "Evidence, Even If Flawed, For Blog Metrics", "url":"", "nodeSize":1.58},
{"id":30, "name": "Captioned Videos of IWMW 2010 Talks", "url":"", "nodeSize":2.55},
{"id":31, "name": "Twitter Captioned Videos Gets Even Better", "url":"", "nodeSize":2},
{"id":32, "name": "Escaping the Constraints of Space and Time", "url":"", "nodeSize":1.76},
{"id":33, "name": "Are the Benefits of Multiple Event Hashtags Now Accepted?", "url":"", "nodeSize":1.5},
{"id":34, "name": "An Early Example of a TTML Application", "url":"", "nodeSize":1.89},
{"id":35, "name": "Asynchronous Twitter Discussions Of Video Streams", "url":"", "nodeSize":1.5},
{"id":36, "name": "Blog Widget For Creating EPub and PDF Files", "url":"", "nodeSize":1.58},
{"id":37, "name": "Twitter Posts Are Not Private: What are the Implications?", "url":"", "nodeSize":1.5},
{"id":38, "name": "When Technology (Eventually) Enhances Accessibility", "url":"", "nodeSize":1.5},
{"id":39, "name": "A Few Days Left to Download a Structured Archive of Tweets", "url":"", "nodeSize":1.5},
{"id":40, "name": "The Virtual Revolution: Twitter subtitles for BBC iPlayer", "url":"", "nodeSize":1.58},
{"id":41, "name": "Twitter powered subtitles for BBC iPlayer", "url":"", "nodeSize":2.52},
{"id":42, "name": "Gordon Brown’s Building Britain’s Digital Future announcement with twitter subtitles", "url":"", "nodeSize":1.95},
{"id":43, "name": "JISC10 Conference Keynotes with Twitter Subtitles", "url":"", "nodeSize":2.14},
{"id":44, "name": "Google I/O 2010 – Keynote Day 2 Android Demo with Twitter Subtitles", "url":"", "nodeSize":1.54},
{"id":45, "name": "Convergence @youtube meets @twitter: In timeline commenting of YouTube videos using Twitter [uTitle]", "url":"", "nodeSize":2.19},
{"id":46, "name": "iTitle", "url":"", "nodeSize":4}
"links": [
{"source": 1, "target": 45},
{"source": 2, "target": 41},
{"source": 2, "target": 40},
{"source": 3, "target": 41},
{"source": 5, "target": 46},
{"source": 6, "target": 42},
{"source": 7, "target": 43},
{"source": 7, "target": 46},
{"source": 8, "target": 41},
{"source": 8, "target": 43},
{"source": 8, "target": 44},
{"source": 9, "target": 45},
{"source": 10, "target": 43},
{"source": 12, "target": 25},
{"source": 12, "target": 24},
{"source": 13, "target": 28},
{"source": 13, "target": 26},
{"source": 14, "target": 27},
{"source": 15, "target": 7},
{"source": 16, "target": 8},
{"source": 17, "target": 30},
{"source": 17, "target": 31},
{"source": 18, "target": 30},
{"source": 18, "target": 31},
{"source": 19, "target": 11},
{"source": 19, "target": 28},
{"source": 19, "target": 4},
{"source": 19, "target": 0},
{"source": 20, "target": 0},
{"source": 21, "target": 0},
{"source": 21, "target": 30},
{"source": 22, "target": 12},
{"source": 23, "target": 12},
{"source": 24, "target": 11},
{"source": 30, "target": 46},
{"source": 30, "target": 27},
{"source": 31, "target": 46},
{"source": 32, "target": 5},
{"source": 32, "target": 46},
{"source": 33, "target": 46},
{"source": 34, "target": 41},
{"source": 34, "target": 42},
{"source": 35, "target": 46},
{"source": 37, "target": 46},
{"source": 38, "target": 46},
{"source": 39, "target": 46}
<!DOCTYPE html>
<title>Force-Directed Layout</title>
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
<style type="text/css"> {
fill: none;
stroke: #666;
stroke-width: 1.5px;
marker#licensing {
fill: green;
} {
stroke: green;
} {
stroke-dasharray: 0,2 1;
circle {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
text {
font: 10px sans-serif;
pointer-events: none;
text.shadow {
stroke: #fff;
stroke-width: 3px;
stroke-opacity: .8;
<script type="text/javascript">
var w = 962,
h = 502;
d3.json("force.json", function(json) {
var force = d3.layout.force()
.size([w, h])
.on("tick", tick)
var svg ="body").append("svg:svg")
.attr("width", w)
.attr("height", h);
// Per-type markers, as they don't inherit styles.
.attr("id", function(d) { return "suit"; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", function(d) { return d.nodeSize*3+8 || 5; })
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("svg:g").selectAll("path")
.attr("class", function(d) { return "link suit"; })
.attr("marker-end", function(d) { return "url(#suit"")"; });
var circle = svg.append("svg:g").selectAll("circle.node")
.attr("r", function(d) { return d.nodeSize*3 || 5; })
.on("click", function(d) {;})
var text = svg.append("svg:g").selectAll("g")
// A copy of the text with a thick white stroke for legibility.
.attr("x", 8)
.attr("y", ".31em")
.attr("class", "shadow")
.text(function(d) { return; });
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return; });
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", function(d) {
var dx = - d.source.x,
dy = - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + + "," +;
circle.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
text.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment