block by emeeks 9441864

Adjacency Matrix from Node/Edge List

Full Screen

An adjacency matrix is a useful way of visualizing networks using an n-by-n grid that shows connection between nodes as a filled grid square. This adjacency matrix is directed, with the source on the y-axis and target on the x-axis. It loads the data from a node list and edge list and represents edge weight using opacity. It also highlights rows and columns on mouseover.

index.html

<html xmlns="//www.w3.org/1999/xhtml">
<head>
  <title>D3 in Action Adjacency Matrix</title>
  <meta charset="utf-8" />
</head>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//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;
}

</style>
<body onload="adjacency()">

<div id="vizcontainer">
<svg style="width:500px;height:500px;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 = [];
      //create all possible edges
      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);
        }
      }
      
      d3.select("svg")
      .append("g")
      .attr("transform", "translate(50,50)")
      .attr("id", "adjacencyG")
      .selectAll("rect")
      .data(matrix)
      .enter()
      .append("rect")
      .attr("width", 25)
      .attr("height", 25)
      .attr("x", function (d) {return d.x * 25})
      .attr("y", function (d) {return d.y * 25})
      .style("stroke", "black")
      .style("stroke-width", "1px")
      .style("fill", "red")
      .style("fill-opacity", function (d) {return d.weight * .2})
      .on("mouseover", gridOver)
      
      var scaleSize = nodes.length * 25;
      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>

edgelist.csv

source,target,weight
sam,tully,3
sam,pat,8
sam,kim,2
sam,pris,1
roy,pris,5
roy,sam,1
tully,sam,1
tully,pris,5
tully,kim,3
tully,pat,1
tully,mo,3
kim,pat,2
kim,mo,1
mo,tully,7
mo,pat,1
mo,sam,4
mo,pris,1
pat,sam,3
pat,tully,1
pat,kim,2
pat,mo,5

nodelist.csv

id,followers,following
sam,17,500
roy,83,80
pris,904,15
tully,7,5
kim,11,50
mo,80,85
pat,150,300