A visualization of a graph that just shows edges, not nodes. This shows the graph structure clearly.
A force directed graph visualization of blocks published on bl.ocks.org. The links in the graph are derived from links from README files of blocks to other blocks. Derived from original work by Micah Stubbs found at github.com/micahstubbs/readme-vis
forked from curran's block: Blocks Graph
xxxxxxxxxx
<html>
<head>
<title>Edge creation</title>
<meta charset="utf-8" />
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="jsLouvain.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="viz">
<svg class="main"> </svg>
</div>
<script>
d3.json("readme-blocks-graph.json", function(error,data) { createNetwork(data) });
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
function createNetwork(graphContainer) {
var nodeHash = {};
var nodes = [];
var edges = [];
var edgelist = graphContainer["graph"]["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({id: nodeHash[edge.source].id + "-" + nodeHash[edge.target].id, source: nodeHash[edge.source], target: nodeHash[edge.target], weight: 1/*edge.weight*/});
}
});
createForceNetwork(nodes, edges);
}
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 colors = d3.scale.category20();
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}; });
console.log("node_data", node_data);
console.log("edge_data", edge_data);
var community = jLouvain().nodes(node_data).edges(edge_data);
var result = community();
console.log("jLouvain result", result);
nodes.forEach(function (node) {
node.module = result[node.id]
//console.log("node.module", node.module)
});
modularityCensus(nodes, edges, result);
var force = d3.layout.force().nodes(nodes).links(edges)
.size([960, 500])
.charge(-50)
.chargeDistance(50)
.linkStrength(3)
.linkDistance(8)
.gravity(0.05)
.on("tick", updateNetwork);
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", "1px")
.style("stroke", "black")
.style("pointer-events", "none");
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});
}
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js