forked from emeeks's block: Networks - Graphs 7
forked from anonymous's block: Networks - Graphs 7
xxxxxxxxxx
<html>
<head>
<title>Edge creation</title>
<meta charset="utf-8" />
<script src="https://d3js.org/d3.v3.min.js" type="text/JavaScript"></script>
<script src="jsLouvain.js" type="text/JavaScript"></script>
</head>
<style>
svg {
height: 800px;
width: 800px;
border: 1px solid gray;
}
</style>
<body>
<div id="viz">
<svg class="main">
</svg>
</div>
</body>
<footer>
<script>
d3.csv("firm.csv",function(error,data) {createNetwork(data)});
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
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 >= 1) {
edges.push({id: nodeHash[edge.source].id + "-" + nodeHash[edge.target].id, source: nodeHash[edge.source], target: nodeHash[edge.target], weight: edge.weight});
}
});
createForceNetwork(nodes, edges);
console.log(nodeHash)
}
function modularityCensus(nodes, edges, moduleHash) {
edges.forEach(function (edge) {
if (edge.source.module !== edge.target.module) {
edge.border = true;
}
else {
edge.border = false;
}
});
nodes.forEach(function (node) {
var theseEdges = edges.filter(function(d) {return d.source === node || d.target === node});
var theseSourceModules = theseEdges.map(function (d) {return d.source.module}).filter(onlyUnique);
var theseTargetModules = theseEdges.map(function (d) {return d.target.module}).filter(onlyUnique);
if (theseSourceModules.length > 1 || theseTargetModules.length > 1) {
node.border = true;
}
else {
node.border = false;
}
});
}
function createForceNetwork(nodes, edges) {
//create a network from an edgelist
var colors = d3.scale.ordinal().domain([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]).range(["#996666", "#66CCCC", "#FFFF99", "#CC9999", "#666633", "#993300", "#999966", "#660000", "#996699", "#cc6633", "#ff9966", "#339999", "#6699cc", "#ffcc66", "#ff6600", "#00ccccc"]);
var node_data = nodes.map(function (d) {return d.id});
var edge_data = edges.map(function (d) {return {source: d.source.id, target: d.target.id, weight: 1}; });
var community = jLouvain().nodes(node_data).edges(edge_data);
var result = community();
nodes.forEach(function (node) {
node.module = result[node.id]
});
modularityCensus(nodes, edges, result);
var force = d3.layout.force().nodes(nodes).links(edges)
.size([800,800])
.charge(-1071)
.chargeDistance(571)
.gravity(0.1)
.on("tick", updateNetwork);
var drag = force.drag()
.on("drag", drag)
.on("dragend", dragend)
.on("dragstart", dragstart);
var edgeEnter = d3.select("svg.main").selectAll("g.edge")
.data(edges, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "edge");
edgeEnter
.append("line")
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"})
.style("stroke", "black")
.style("pointer-events", "none");
var nodeEnter = d3.select("svg.main").selectAll("g.node")
.data(nodes, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "node")
.call(drag);
nodeEnter.append("circle")
.attr("r", 16)
.attr("class", "background")
.style("fill", "lightgreen")
.style("opacity", 0)
.style("pointer-events", "none");
nodeEnter.append("circle")
.attr("r", 12)
.attr("class", "foreground")
.style("fill", function (d) {return colors(d.module)})
.style("stroke", "black")
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"})
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 3)
.style("stroke-width", "1px")
.style("stroke-opacity", 0.75)
.style("stroke", "white")
.style("font-size", "12px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 3)
.style("font-size", "12px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
force.start();
function dragstart() {
nodes.forEach(function (node) {
node.fixed = true;
})
}
function drag(d) {
var nodeDom = this;
var foundOverlap = false
nodes.forEach(function (otherNode) {
var distance = Math.sqrt(Math.pow(otherNode.x - d.x, 2) + Math.pow(otherNode.y - d.y, 2));
if (otherNode != d && distance < 16) {
foundOverlap = true;
}
})
if (foundOverlap == true) {
d3.select(nodeDom).select("circle.background")
.style("opacity", 0.5)
}
else {
d3.select(nodeDom).select("circle.background")
.style("opacity", 0)
}
}
function dragend(d) {
force.stop();
d3.selectAll("circle.background")
.style("opacity", 0);
nodes.forEach(function (otherNode) {
otherNode.fixed = false;
var distance = Math.sqrt(Math.pow(otherNode.x - d.x, 2) + Math.pow(otherNode.y - d.y, 2));
if (otherNode != d && distance < 16) {
var newEdge = {id: d.id + "-" + otherNode.id, source: d, target: otherNode};
if (edges.map(function (d) {return d.id}).indexOf(newEdge.id) == -1) {
edges.push(newEdge);
}
}
});
force.links(edges);
var edgeEnter = d3.select("svg.main").selectAll("g.edge")
.data(edges, function (d) {return d.id})
.enter()
.insert("g", "g.node")
.attr("class", "edge");
edgeEnter
.append("line")
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"})
.style("stroke", "black")
.style("pointer-events", "none");
var community = jLouvain().nodes(node_data).edges(edge_data);
var result = community();
nodes.forEach(function (node) {
node.module = result[node.id]
});
node_data = nodes.map(function (d) {return d.id});
edge_data = edges.map(function (d) {return {source: d.source.id, target: d.target.id, weight: 1}; });
modularityCensus(nodes, edges, result);
d3.selectAll("circle.foreground")
.style("fill", function (d) {return colors(d.module)})
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"});
force.start();
}
function updateNetwork(e) {
d3.select("svg.main").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.main").selectAll("g.node")
.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"});
}
}
</script>
</footer>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js