Modified from the example 'force-collapsible' of the d3 library by SNU DMLab.
- Keywords extracted from Google blog search during October, 2012.
- Diagram created at 2012-09-11
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Force-Directed Graph</title> | |
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script> | |
<link type="text/css" href="style.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="chart"></div> | |
<script type="text/javascript" src="network.js"></script> | |
</body> | |
</html> |
{ | |
"name": "tv", | |
"children": [ | |
{ | |
"name": "video", | |
"children": [ | |
{ "name": "photo", "size": 117}, | |
{ "name": "flickr", "size": 117}, | |
{ "name": "apple", "size": 97}, | |
{ "name": "converter", "size": 84}, | |
{ "name": "live", "size": 79}, | |
{ "name": "game", "size": 70}, | |
{ "name": "awards", "size": 67}, | |
{ "name": "sharing", "size": 60}, | |
{ "name": "exclusive", "size": 59} | |
] | |
}, | |
{ "name": "apple", | |
"children": [ | |
{ "name": "converter", "size": 217}, | |
{ "name": "dvd", "size": 122}, | |
{ "name": "rebate", "size": 93}, | |
{ "name": "pad", "size": 84}, | |
{ "name": "video", "size": 82}, | |
{ "name": "feed", "size": 61} | |
] | |
}, | |
{ | |
"name": "live", | |
"children": [ | |
{ "name": "free", "size": 163}, | |
{ "name": "india", "size": 113}, | |
{ "name": "streaming", "size": 110}, | |
{ "name": "pakistan", "size": 61} | |
] | |
}, | |
{ | |
"name": "online", | |
"children": [ | |
{ "name": "free", "size": 128}, | |
{ "name": "streaming", "size": 116}, | |
{ "name": "writer", "size": 63}, | |
{ "name": "liverpool", "size": 52} | |
] | |
}, | |
{ | |
"name": "women", | |
"children": [ | |
{ "name": "watch", "size": 67}, | |
{ "name": "sports", "size": 62}, | |
{ "name": "funny", "size": 59} | |
] | |
}, | |
{ | |
"name": "google", | |
"children": [ | |
{ "name": "android", "size": 69}, | |
{ "name": "different", "size": 50} | |
] | |
}, | |
{ | |
"name": "3d", | |
"children": [ | |
{"name": "LG", "size": 61}, | |
{"name": "smart", "size": 50}, | |
{"name": "cinema", "size": 37}, | |
{"name": "new", "size": 28}, | |
{"name": "samsung", "size": 20}, | |
{"name": "toshiba", "size": 19}, | |
{"name": "hd", "size": 17}, | |
{"name": "plasma", "size": 16}, | |
{"name": "glassesfree", "size": 14}, | |
{"name": "technology", "size": 14} | |
] | |
}, | |
{ | |
"name": "smart", | |
"children": [ | |
{"name": "bbc", "size": 168}, | |
{"name": "samsung", "size": 128}, | |
{"name": "blog", "size": 118}, | |
{"name": "affordable", "size": 112}, | |
{"name": "led", "size": 87}, | |
{"name": "money", "size": 114}, | |
{"name": "internet", "size": 64}, | |
{"name": "LG", | |
"children": [ | |
{"name": "infinia", "size": 128}, | |
{"name": "led", "size": 96}, | |
{"name": "hdtv", "size": 87}, | |
{"name": "cinema", "size": 73}, | |
{"name": "technology", "size": 68}, | |
{"name": "cloudcastlg", "size": 63} | |
] | |
}, | |
{ | |
"name": "apps", | |
"children": [ | |
{ "name": "samsung", "size": 300}, | |
{ "name": "bbc", "size": 170}, | |
{ "name": "lg", "size": 142}, | |
{ "name": "upgrader", "size": 104}, | |
{ "name": "3d", "size": 91}, | |
{ "name": "led", "size": 68}, | |
{ "name": "iplayer", "size": 59} | |
] | |
} | |
] | |
} | |
] | |
} |
var width = 960, | |
height = 500, | |
node, | |
link, | |
root; | |
var force = d3.layout.force() | |
.on("tick", tick) | |
//.charge(function(d) { return d._children ? -d.size / 100 : -30; }) | |
.charge(function(d) { return d._children ? -d.size / 100 : -1000; }) | |
//.linkDistance(function(d) { return d.target._children ? 80 : 30; }) | |
.linkDistance(function(d) { return d.target._children ? 80 : 30; }) | |
.size([width, height]); | |
var vis = d3.select("#chart").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
d3.json("lgtv.json", function(json) { | |
root = json; | |
root.fixed = true; | |
root.x = width / 2; | |
root.y = height / 2; | |
update(); | |
}); | |
function update() { | |
var nodes = flatten(root), | |
links = d3.layout.tree().links(nodes); | |
// Restart the force layout. | |
force | |
.nodes(nodes) | |
.links(links) | |
.start(); | |
// Update the links… | |
link = vis.selectAll("line.link") | |
.data(links, function(d) { return d.target.id; }); | |
// Enter any new links. | |
link.enter().insert("line", ".node") | |
.attr("class", "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; }); | |
// Exit any old links. | |
link.exit().remove(); | |
// Update the nodes… | |
node = vis.selectAll("text.node") | |
.data(nodes, function(d) { return d.id; }); | |
node.transition() | |
.attr("r", function(d) { return d.children ? 4.5 : Math.sqrt(d.size) / 10; }); | |
// Enter any new nodes. | |
var minfont = 15; | |
node.enter().append("text") | |
.attr("class", "node") | |
.attr("dx", function(d) { return d.x; }) | |
.attr("dy", function(d) { return d.y; }) | |
.text(function(d) { return d.name; }) | |
.style("fill", color) | |
.style("font-size", | |
function(d) { | |
fs = Math.sqrt(d.size); | |
if(fs<minfont) fs = minfont; | |
return fs; | |
}) | |
.on("click", click) | |
.call(force.drag); | |
// | |
// Exit any old nodes. | |
node.exit().remove(); | |
} | |
function tick() { | |
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("dx", function(d) { return d.x; }) | |
.attr("dy", function(d) { return d.y; }); | |
} | |
// Color leaf nodes orange, and packages white or blue. | |
function color(d) { | |
return d._children ? "#3182bd" : d.children ? "#33F" : "#fd8d3c"; | |
} | |
// Toggle children on click. | |
function click(d) { | |
if (d.children) { | |
d._children = d.children; | |
d.children = null; | |
} else { | |
d.children = d._children; | |
d._children = null; | |
} | |
update(); | |
} | |
// Returns a list of all nodes under the root. | |
function flatten(root) { | |
var nodes = [], i = 0; | |
function recurse(node) { | |
if (node.children) node.size = node.children.reduce(function(p, v) { return p + recurse(v); }, 0); | |
if (!node.id) node.id = ++i; | |
nodes.push(node); | |
return node.size; | |
} | |
root.size = recurse(root); | |
return nodes; | |
} |
circle.node { | |
cursor: pointer; | |
stroke: #337; | |
stroke-width: .5px; | |
} | |
line.link { | |
fill: none; | |
stroke: #AAC; | |
stroke-width: 1.5px; | |
} |