Skip to content

Instantly share code, notes, and snippets.

@dcasciotti
Last active August 29, 2015 14:17
Show Gist options
  • Save dcasciotti/7da041767f8bcc1e4c25 to your computer and use it in GitHub Desktop.
Save dcasciotti/7da041767f8bcc1e4c25 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sociometric Analysis of Lansing Michigan's Human Welfare Institutions- 1970
</title>
<style>
.background {
fill: #eee;
}
line {
stroke: #fff;
}
text.active {
fill: red;
}
text {
font: 10px sans-serif;
}
</style>
<style type="text/css"></style>
</head>
<p>A SOCIOMETRIC ANALYSIS OF LANSING<BR /> MICHIGAN'S HUMAN WELFARE INSTITUTIONS
<p>Masters Thesis in Urban Planning <br />Michigan State University (1970)<br /> David A. Casciotti
<p>Each colored square represents an interaction between two agencies.
<p>Clusters of agencies on the diagonal axis represent reciprocal interaction of all agencies in the cluster.
<p> Frequency represents a ranking of the number of interactions for a particular agency.
<p>Use the drop-down menu to reorder the matrix.
<p>Built with <a href="http://d3js.org/">d3.js</a>
<aside>
<p>Order: <select id="order">
<option value="name">by Name</option>
<option value="count">by Frequency</option>
<option value="group">by Cluster</option>
</select>
</aside>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 120, right: 100, bottom: 10, left: 120},
width = 600,
height = 600;
var x = d3.scale.ordinal().rangeBands([0, width]),
z = d3.scale.linear().domain([0, 4]).clamp(true),
c = d3.scale.category10().domain(d3.range(10));
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("margin-left", margin.left + "px")
.style("margin-top", margin.top + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("thesis_bak.json", function(thesis) {
console.log(thesis);
var matrix = [],
nodes = thesis.nodes,
n = nodes.length;
// Compute index per node.
nodes.forEach(function(node, i) {
node.index = i;
node.count = 0;
matrix[i] = d3.range(n).map(function(j) { return {x: j, y: i, z: 0}; });
});
// Convert links to matrix; count character occurrences.
thesis .links.forEach(function(link) {
matrix[link.source][link.target].z += link.value;
matrix[link.target][link.source].z += link.value;
matrix[link.source][link.source].z += link.value;
matrix[link.target][link.target].z += link.value;
nodes[link.source].count += link.value;
nodes[link.target].count += link.value;
});
//alert("matrix = "+ )
// Precompute the orders.
var orders = {
name: d3.range(n).sort(function(a, b) { return d3.ascending(nodes[a].name, nodes[b].name); }),
count: d3.range(n).sort(function(a, b) { return nodes[b].count - nodes[a].count; }),
group: d3.range(n).sort(function(a, b) { return nodes[b].group - nodes[a].group; })
};
// The default sort order.
x.domain(orders.name);
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
var row = svg.selectAll(".row")
.data(matrix)
.enter().append("g")
.attr("class", "row")
.attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; })
.each(row);
row.append("line")
.attr("x2", width);
row.append("text")
.attr("x", -6)
.attr("y", x.rangeBand() / 5)
.attr("dy", ".10em")
.attr("text-anchor", "end")
.text(function(d, i) { return nodes[i].name; });
var column = svg.selectAll(".column")
.data(matrix)
.enter().append("g")
.attr("class", "column")
.attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; });
column.append("line")
.attr("x1", -width);
column.append("text")
.attr("x", 6)
.attr("y", x.rangeBand() / 5)
.attr("dy", ".10em")
.attr("text-anchor", "start")
.text(function(d, i) { return nodes[i].name; });
function row(row) {
var cell = d3.select(this).selectAll(".cell")
.data(row.filter(function(d) { return d.z; }))
.enter().append("rect")
.attr("class", "cell")
.attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand())
.attr("height", x.rangeBand())
.style("fill-opacity", function(d) { return z(d.z); })
.style("fill", function(d) { return nodes[d.x].group == nodes[d.y].group ? c(nodes[d.x].group) : null; })
.on("mouseover", mouseover)
.on("mouseout", mouseout);
}
function mouseover(p) {
d3.selectAll(".row text").classed("active", function(d, i) { return i == p.y; });
d3.selectAll(".column text").classed("active", function(d, i) { return i == p.x; });
}
function mouseout() {
d3.selectAll("text").classed("active", false);
}
d3.select("#order").on("change", function() {
clearTimeout(timeout);
order(this.value);
});
function order(value) {
x.domain(orders[value]);
var t = svg.transition().duration(2500);
t.selectAll(".row")
.delay(function(d, i) { return x(i) * 4; })
.attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; })
.selectAll(".cell")
.delay(function(d) { return x(d.x) * 4; })
.attr("x", function(d) { return x(d.x); });
t.selectAll(".column")
.delay(function(d, i) { return x(i) * 4; })
.attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; });
}
var timeout = setTimeout(function() {
order("group");
d3.select("#order").property("selectedIndex", 2).node().focus();
}, 5000);
});
</script>
</body>
</html>
{
"nodes":[
{"name":"West Action","group":1},
{"name":"Am. Red Cross","group":1},
{"name":"East Action","group":1},
{"name":"North Action","group":1},
{"name":"Christo Rey","group":1},
{"name":"Family Services","group":2},
{"name":"Mental Health","group":2},
{"name":"Ing. Mental Health","group":2},
{"name":"Lan. Model Cities","group":2},
{"name":"Mic. St. Emp.","group":3},
{"name":"Family Planning","group":3},
{"name":"Lan. Adult Ed.","group":3},
{"name":"Catholic SS","group":4},
{"name":"Child Treatment Cntr.","group":3},
{"name":"St. Vincent","group":4},
{"name":"Comm.Ser. Council","group":4},
{"name":"Visiting Nurses","group":1},
{"name":"Probate Court","group":1},
{"name":"Community Coun. Info.","group":5},
{"name":"Rehab. Industries","group":5},
{"name":"Vol. of America","group":5},
{"name":"Med. Hosp Soc. Serv.","group":6},
{"name":"Ing. Health Dept.","group":6},
{"name":"MSU Coll. Hman Med.","group":1},
{"name":"Equal Opportunity","group":7},
{"name":"Lan. Urban League","group":7},
{"name":"Lan. Contin. Ed","group":4},
{"name":"Mich. Dept. Ed","group":4},
{"name":"Lan. Rec. Dept","group":4},
{"name":"Lan. Plann. Dept.","group":8},
{"name":"Tri. Co. RPB","group":8},
{"name":"AFL-CIO Comm. Ser.","group":4},
{"name":"Dental Health Comm.","group":4},
{"name":"Easter Seal Soc.","group":1},
{"name":"Big Sisters","group":1},
{"name":"Prob. Ct. Child Ser.","group":1},
{"name":"Lan. Human Relations","group":5},
{"name":"Lansing Parole","group":5},
{"name":"YMCA of Lansing","group":5},
{"name":"Mobile Meals","group":5},
{"name":"Lan. Drop in Cntr.","group":1},
{"name":"School for Blind","group":1},
{"name":"YWCA of Lansing","group":1},
{"name":"Youth for Christ","group":5},
{"name":"Lan. Relocation Off.","group":5},
{"name":"Lan. Sr. Drop in","group":5},
{"name":"MSU Volunteer Prog.","group":5}
],
"links":[
{"source":0,"target":0,"value":5},
{"source":1,"target":0,"value":5},
{"source":1,"target":1,"value":5},
{"source":3,"target":1,"value":5},
{"source":4,"target":1,"value":5},
{"source":7,"target":1,"value":5},
{"source":11,"target":1,"value":2},
{"source":12,"target":1,"value":5},
{"source":13,"target":1,"value":5},
{"source":40,"target":1,"value":5},
{"source":2,"target":2,"value":5},
{"source":3,"target":2,"value":5},
{"source":4,"target":2,"value":2},
{"source":5,"target":2,"value":5},
{"source":22,"target":2,"value":5},
{"source":35,"target":2,"value":5},
{"source":3,"target":3,"value":5},
{"source":4,"target":3,"value":5},
{"source":5,"target":3,"value":2},
{"source":10,"target":3,"value":5},
{"source":4,"target":4,"value":5},
{"source":5,"target":4,"value":5},
{"source":30,"target":4,"value":5},
{"source":5,"target":5,"value":5},
{"source":9,"target":5,"value":2},
{"source":10,"target":5,"value":5},
{"source":13,"target":5,"value":5},
{"source":16,"target":5,"value":5},
{"source":17,"target":5,"value":5},
{"source":24,"target":5,"value":5},
{"source":25,"target":5,"value":2},
{"source":44,"target":5,"value":5},
{"source":6,"target":6,"value":5},
{"source":7,"target":6,"value":5},
{"source":8,"target":6,"value":5},
{"source":9,"target":6,"value":5},
{"source":14,"target":6,"value":2},
{"source":15,"target":6,"value":5},
{"source":17,"target":6,"value":5},
{"source":18,"target":6,"value":5},
{"source":20,"target":6,"value":5},
{"source":25,"target":6,"value":5},
{"source":28,"target":6,"value":2},
{"source":29,"target":6,"value":5},
{"source":7,"target":7,"value":5},
{"source":8,"target":7,"value":5},
{"source":9,"target":7,"value":5},
{"source":10,"target":7,"value":5},
{"source":11,"target":7,"value":2},
{"source":12,"target":7,"value":5},
{"source":13,"target":7,"value":5},
{"source":15,"target":7,"value":5},
{"source":17,"target":7,"value":5},
{"source":18,"target":7,"value":5},
{"source":20,"target":7,"value":2},
{"source":25,"target":7,"value":5},
{"source":26,"target":7,"value":5},
{"source":30,"target":7,"value":5},
{"source":35,"target":7,"value":5},
{"source":39,"target":7,"value":5},
{"source":44,"target":7,"value":2},
{"source":45,"target":7,"value":5},
{"source":46,"target":7,"value":5},
{"source":8,"target":8,"value":5},
{"source":9,"target":8,"value":5},
{"source":15,"target":8,"value":5},
{"source":18,"target":8,"value":2},
{"source":19,"target":8,"value":5},
{"source":25,"target":8,"value":5},
{"source":26,"target":8,"value":5},
{"source":27,"target":8,"value":5},
{"source":31,"target":8,"value":5},
{"source":32,"target":8,"value":2},
{"source":33,"target":8,"value":5},
{"source":37,"target":8,"value":5},
{"source":39,"target":8,"value":5},
{"source":9,"target":9,"value":5},
{"source":14,"target":9,"value":5},
{"source":19,"target":9,"value":2},
{"source":27,"target":9,"value":5},
{"source":28,"target":9,"value":5},
{"source":29,"target":9,"value":5},
{"source":32,"target":9,"value":5},
{"source":33,"target":9,"value":5},
{"source":34,"target":9,"value":2},
{"source":10,"target":10,"value":5},
{"source":21,"target":10,"value":5},
{"source":33,"target":10,"value":5},
{"source":43,"target":10,"value":5},
{"source":44,"target":10,"value":5},
{"source":45,"target":10,"value":2},
{"source":11,"target":11,"value":5},
{"source":23,"target":11,"value":5},
{"source":24,"target":11,"value":5},
{"source":25,"target":11,"value":5},
{"source":26,"target":11,"value":5},
{"source":27,"target":11,"value":2},
{"source":46,"target":7,"value":5},
{"source":12,"target":12,"value":5},
{"source":13,"target":12,"value":5},
{"source":23,"target":12,"value":5},
{"source":24,"target":12,"value":2},
{"source":13,"target":13,"value":5},
{"source":24,"target":13,"value":5},
{"source":34,"target":13,"value":5},
{"source":43,"target":13,"value":5},
{"source":14,"target":14,"value":5},
{"source":16,"target":14,"value":2},
{"source":35,"target":14,"value":5},
{"source":15,"target":15,"value":5},
{"source":28,"target":15,"value":5},
{"source":16,"target":16,"value":5},
{"source":17,"target":16,"value":5},
{"source":36,"target":16,"value":2},
{"source":17,"target":17,"value":5},
{"source":19,"target":17,"value":5},
{"source":22,"target":17,"value":5},
{"source":24,"target":17,"value":5},
{"source":27,"target":17,"value":5},
{"source":34,"target":17,"value":2},
{"source":37,"target":17,"value":5},
{"source":18,"target":18,"value":5},
{"source":23,"target":18,"value":5},
{"source":30,"target":18,"value":5},
{"source":34,"target":18,"value":5},
{"source":45,"target":18,"value":2},
{"source":19,"target":19,"value":5},
{"source":34,"target":19,"value":5},
{"source":43,"target":19,"value":5},
{"source":35,"target":19,"value":5},
{"source":26,"target":11,"value":5},
{"source":43,"target":19,"value":2},
{"source":20,"target":20,"value":5},
{"source":21,"target":20,"value":5},
{"source":22,"target":20,"value":5},
{"source":35,"target":20,"value":5},
{"source":36,"target":20,"value":2},
{"source":21,"target":21,"value":5},
{"source":22,"target":21,"value":5},
{"source":26,"target":21,"value":5},
{"source":30,"target":21,"value":5},
{"source":36,"target":21,"value":2},
{"source":38,"target":21,"value":5},
{"source":22,"target":22,"value":5},
{"source":41,"target":22,"value":5},
{"source":23,"target":23,"value":5},
{"source":24,"target":23,"value":5},
{"source":37,"target":23,"value":2},
{"source":44,"target":23,"value":5},
{"source":24,"target":24,"value":5},
{"source":25,"target":24,"value":5},
{"source":26,"target":24,"value":5},
{"source":35,"target":24,"value":5},
{"source":46,"target":24,"value":2},
{"source":25,"target":25,"value":5},
{"source":26,"target":25,"value":5},
{"source":28,"target":25,"value":5},
{"source":44,"target":25,"value":5},
{"source":26,"target":26,"value":5},
{"source":27,"target":26,"value":2},
{"source":28,"target":26,"value":5},
{"source":40,"target":26,"value":5},
{"source":43,"target":26,"value":5},
{"source":27,"target":27,"value":5},
{"source":28,"target":27,"value":5},
{"source":29,"target":27,"value":2},
{"source":30,"target":27,"value":5},
{"source":31,"target":27,"value":5},
{"source":34,"target":27,"value":5},
{"source":43,"target":27,"value":5},
{"source":45,"target":27,"value":5},
{"source":28,"target":28,"value":2},
{"source":30,"target":28,"value":5},
{"source":29,"target":29,"value":5},
{"source":29,"target":29,"value":5},
{"source":30,"target":30,"value":5},
{"source":31,"target":31,"value":2},
{"source":32,"target":31,"value":5},
{"source":34,"target":31,"value":5},
{"source":37,"target":31,"value":5},
{"source":39,"target":31,"value":5},
{"source":41,"target":31,"value":2},
{"source":43,"target":31,"value":5},
{"source":32,"target":32,"value":5},
{"source":33,"target":32,"value":5},
{"source":34,"target":32,"value":5},
{"source":33,"target":33,"value":5},
{"source":34,"target":34,"value":2},
{"source":42,"target":34,"value":5},
{"source":35,"target":35,"value":5},
{"source":36,"target":36,"value":5},
{"source":37,"target":37,"value":5},
{"source":38,"target":38,"value":5},
{"source":39,"target":39,"value":2},
{"source":40,"target":40,"value":5},
{"source":41,"target":41,"value":5},
{"source":42,"target":42,"value":5},
{"source":43,"target":43,"value":5},
{"source":44,"target":44,"value":2},
{"source":45,"target":45,"value":5},
{"source":46,"target":46,"value":5}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment