|
<html> |
|
<head> |
|
<title>Labeled Nodes</title> |
|
<meta charset="utf-8" /> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> |
|
</head> |
|
<style> |
|
svg { |
|
height: 500px; |
|
width: 500px; |
|
border: 1px solid gray; |
|
} |
|
</style> |
|
<body> |
|
|
|
<div id="viz"> |
|
<svg> |
|
</svg> |
|
</div> |
|
</body> |
|
<footer> |
|
<script> |
|
|
|
d3.csv("firm.csv",function(error,data) {createNetwork(data)}); |
|
|
|
function createNetwork(edgelist) { |
|
var nodeHash = {}; |
|
var nodes = []; |
|
var edges = []; |
|
|
|
edgelist.forEach(function (edge) { |
|
if (!nodeHash[edge.source]) { |
|
nodeHash[edge.source] = {id: edge.source, label: edge.source}; |
|
nodes.push(nodeHash[edge.source]); |
|
} |
|
if (!nodeHash[edge.target]) { |
|
nodeHash[edge.target] = {id: edge.target, label: edge.target}; |
|
nodes.push(nodeHash[edge.target]); |
|
} |
|
if (edge.weight >= 5) { |
|
edges.push({source: nodeHash[edge.source], target: nodeHash[edge.target], weight: edge.weight}); |
|
} |
|
}); |
|
createForceNetwork(nodes, edges); |
|
} |
|
|
|
function createForceNetwork(nodes, edges) { |
|
|
|
//create a network from an edgelist |
|
|
|
var force = d3.layout.force().nodes(nodes).links(edges) |
|
.size([500,500]) |
|
.charge(-300) |
|
.on("tick", updateNetwork); |
|
|
|
d3.select("svg").selectAll("line") |
|
.data(edges) |
|
.enter() |
|
.append("line") |
|
.style("stroke-width", "1px") |
|
.style("stroke", "#996666"); |
|
|
|
var nodeEnter = d3.select("svg").selectAll("g.node") |
|
.data(nodes) |
|
.enter() |
|
.append("g") |
|
.attr("class", "node") |
|
.on("click", nodeClick) |
|
.on("dblclick", nodeDoubleClick) |
|
.on("mouseover", nodeOver) |
|
.on("mouseout", nodeOut) |
|
.call(force.drag()); |
|
|
|
nodeEnter.append("circle") |
|
.attr("r", 10) |
|
.style("fill", "#CC9999") |
|
.style("stroke", "black") |
|
.style("stroke-width", "1px") |
|
|
|
nodeEnter.append("text") |
|
.style("text-anchor", "middle") |
|
.attr("y", 3) |
|
.style("stroke-width", "2px") |
|
.style("stroke-opacity", 0.75) |
|
.style("stroke", "white") |
|
.style("font-size", "10px") |
|
.text(function (d) {return d.id}) |
|
.style("pointer-events", "none") |
|
|
|
nodeEnter.append("text") |
|
.style("text-anchor", "middle") |
|
.attr("y", 3) |
|
.style("font-size", "10px") |
|
.text(function (d) {return d.id}) |
|
.style("pointer-events", "none") |
|
|
|
force.start(); |
|
|
|
function nodeClick(d) { |
|
d.fixed = true; |
|
} |
|
|
|
function nodeDoubleClick(d) { |
|
d.fixed = false; |
|
force.start(); |
|
} |
|
|
|
function nodeOver() { |
|
force.stop(); |
|
} |
|
|
|
function nodeOut() { |
|
force.start(); |
|
} |
|
|
|
function updateNetwork() { |
|
d3.select("svg").selectAll("line") |
|
.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}); |
|
|
|
d3.select("svg").selectAll("g.node") |
|
.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"}); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
</script> |
|
</footer> |
|
|
|
</html> |