index.html
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<title>D3 in Action Adjacency Matrix</title>
<meta charset="utf-8" />
</head>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/queue.v1.min.js" type="text/javascript"></script>
<style>
.tick line {
shape-rendering: crispEdges;
stroke: #000;
}
line.minor {
stroke: #777;
stroke-dasharray: 2,2;
}
path.domain {
fill: none;
stroke: black;
}
g text {
font-size: 12;
}
</style>
<body onload="adjacency()">
<div id="vizcontainer">
<svg style="width:1000px;height:1000px;border:1px lightgray solid;" />
</div>
<footer>
<script>
function adjacency() {
queue()
.defer(d3.csv, "nodelist.csv")
.defer(d3.csv, "edgelist.csv")
.await(function(error, file1, file2) { createAdjacencyMatrix(file1, file2); });
function createAdjacencyMatrix(nodes,edges) {
var edgeHash = {};
for (x in edges) {
var id = edges[x].source + "-" + edges[x].target;
edgeHash[id] = edges[x];
}
matrix = [];
for (a in nodes) {
for (b in nodes) {
var grid = {id: nodes[a].id + "-" + nodes[b].id, x: b, y: a, weight: 0};
if (edgeHash[grid.id]) {
grid.weight = edgeHash[grid.id].weight;
}
matrix.push(grid);
}
}
var weightScale = d3.scale.linear()
.domain(d3.extent(function(d){ return d.weight }))
.range([0,1])
d3.select("svg")
.append("g")
.attr("transform", "translate(220,220)")
.attr("id", "adjacencyG")
.selectAll("rect")
.data(matrix)
.enter()
.append("rect")
.attr("width", 15)
.attr("height", 15)
.attr("x", function (d) {return d.x * 15})
.attr("y", function (d) {return d.y * 15})
.style("stroke", "black")
.style("stroke-width", "1px")
.style("fill", "steelblue")
.style("fill-opacity", function (d) {return d.weight*0.04; })
.on("mouseover", gridOver)
.append("svg:title")
.text(function(d, i) { return d.weight + " co-occurences"; });
var scaleSize = nodes.length * 15;
var nameScale = d3.scale.ordinal().domain(nodes.map(function (el) {return el.id})).rangePoints([0,scaleSize],1);
xAxis = d3.svg.axis()
.scale(nameScale)
.orient("top")
.tickSize(4);
yAxis = d3.svg.axis().scale(nameScale).orient("left").tickSize(4);
d3.select("#adjacencyG").append("g")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("transform", "translate(-10,-10) rotate(90)");
d3.select("#adjacencyG").append("g")
.call(yAxis);
function gridOver(d,i) {
d3.selectAll("rect")
.style("stroke-width", function (p) {return p.x == d.x || p.y == d.y ? "3px" : "1px"})
}
}
}
</script>
</footer>
</body>
</html>
nodelist.csv
id,numericId
ART,0
BIG DATA,1
BUSINESS STRATEGY,2
CLOUD COMPUTING,3
COMPUTER PROGRAMMING,4
DANCING,5
DATA ANALYTICS,6
DATA MINING,7
DATA VISUALIZATION,8
DINING OUT,9
EDUCATION & TECHNOLOGY,10
ENTREPRENEUR NETWORKING,11
ENTREPRENEURSHIP,12
FITNESS,13
HADOOP,14
HIKING,15
HOUSTON,16
INTELLECTUAL DISCUSSION,17
INTERNET STARTUPS,18
JAVASCRIPT,19
LEAN STARTUP,20
LIVE MUSIC,21
MOBILE DEVELOPMENT,22
MOBILE TECHNOLOGY,23
MUSIC,24
NEW TECHNOLOGY,25
OPEN SOURCE,26
OUTDOORS,27
PREDICTIVE ANALYTICS,28
PROFESSIONAL DEVELOPMENT,29
PROFESSIONAL NETWORKING,30
PYTHON,31
SELF-IMPROVEMENT,32
SOCIAL,33
SOFTWARE DEVELOPMENT,34
STARTUP BUSINESSES,35
TECHNOLOGY,36
TECHNOLOGY STARTUPS,37
THEATER,38
TRAVEL,39
WATCHING MOVIES,40
WEB DESIGN,41
WEB DEVELOPMENT,42
WEB TECHNOLOGY,43