Punch Card table of the Seismic Ratings and Collapse Probabilities of California Hospitals.
Column Explanations (paraphrased from here):
NPC Rating - Nonstructural Performance Category
A small punch (low rating) means that safe and orderly evacuation following a strong
earthquake cannot be assumed. A big punch (high rating) means that the facility can continue
to operate for 72 hours without any power, water, or sewer after a strong ground motion.
SPC Rating - Structural Performance Category
A small punch (low rating) means that the hospital poses a significant risk of collapse
following a strong earthquake. A big punch (high rating) means that the hospital will be
reasonably capable of providing services to the public following a strong earthquake.
Ratings not verified by the Office of Statewide Health, Planning, and Development (OSHPD) are included.
Multi-Hazard Loss Estimation Technology
-2007 Hazus Score (%):
A small punch (low percentage) means the hospital has a low probability of collapsing when
ground motions of a given design acceleration occur at the building site.
A big punch (high percentage) means that the probability is high.
-2010 Hazus Score (%): Additional building parameters are used to determine the collapse probability. A small punch is a low probability and a big punch is a high probability. Buildings located directly on faults are assigned probability of -50%. (I did not include these buildings in my calculations).
Data for each building in each Hospital were included in the csv. Hospital building averages are used in this table.
Punch Card table design inspired by Syntagmatic
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue";
}
table {
border-spacing: 10px 5px;
}
tbody tr {
font-size: 10px;
}
thead th {
font-size: 12px;
font-weight: bold;
cursor: pointer;
}
thead th:first-child {
cursor: default;
}
tbody .tdata {
text-align: center;
margin: auto auto auto 20px;
}
tbody tr td:first-child .tdata {
text-align: left;
}
.label {
padding-left: 20px;
}
.hint {
font-size: 12px;
color: #999;
text-align: center;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
d3.csv("Seismic_Ratings_and_Collapse_Probabilities_of_California_Hospitals.csv", function(data) {
var hospitals = {};
data.forEach(function(d) {
var name = d["Facility Name"];
if (!hospitals[name]) { // initialize a new hospital
hospitals[name] = {};
hospitals[name]["spc"] = {};
hospitals[name]["spc"].value = 0;
hospitals[name]["spc"].count = 0;
hospitals[name]["npc"] = {};
hospitals[name]["npc"].value = 0;
hospitals[name]["npc"].count = 0;
hospitals[name]["2007_hazus"] = {};
hospitals[name]["2007_hazus"].value = 0;
hospitals[name]["2007_hazus"].count = 0;
hospitals[name]["2010_hazus"] = {};
hospitals[name]["2010_hazus"].value = 0;
hospitals[name]["2010_hazus"].count = 0;
}
// spc totaling
if ((d["SPC Rating"] != "") && (+d["SPC Rating"] >= 0)) {
hospitals[name]["spc"].value += +d["SPC Rating"];
hospitals[name]["spc"].count += 1;
}
if (/s$/.test(d["SPC Rating"])) {
var val = /^[0-9]/.exec(d["SPC Rating"]);
val = +val;
hospitals[name]["spc"].value += val;
hospitals[name]["spc"].count += 1;
}
// npc totaling
if ((d["NPC Rating"] != "") && (+d["NPC Rating"] >= 0)) {
hospitals[name]["npc"].value += +d["NPC Rating"];
hospitals[name]["npc"].count += 1;
}
if (/s$/.test(d["NPC Rating"])) {
var val = /^[0-9]/.exec(d["NPC Rating"]);
val = +val;
hospitals[name]["npc"].value += val;
hospitals[name]["npc"].count += 1;
}
// 2007 Hazus totaling
if ((d["2007 Hazus Score (%)"] != "") && (+d["2007 Hazus Score (%)"] >= 0)) {
hospitals[name]["2007_hazus"].value += +d["2007 Hazus Score (%)"];
hospitals[name]["2007_hazus"].count += 1;
}
// 2010 Hazus totaling
if ((d["2010 Hazus Score (%)"] != "") && (+d["2010 Hazus Score (%)"] > 0)){
hospitals[name]["2010_hazus"].value += +d["2010 Hazus Score (%)"];
hospitals[name]["2010_hazus"].count += 1;
}
});
var dimensions = ["Hospital", "SPC Rating (1 - 5)", "NPC Rating (1 - 5)", "2007 Hazus Score (%)", "2010 Hazus Score (%)"]
// put a hint at the top
d3.select("body")
.append("div")
.attr("class", "hint")
.append("text")
.text("Click a column header to sort")
// draw the table
var table = d3.select("body").append("table"),
thead = table.append("thead"),
tbody = table.append("tbody");
// draw the column headers
thead.append("tr").selectAll("th")
.data(dimensions)
.enter()
.append("th")
.text(function(d) { return d; })
hospital_data = d3.entries(hospitals);
// draw each row in the table
var tr = tbody.selectAll("tr")
.data(hospital_data)
.enter()
.append("tr");
// punch scales
var spc_npc_scale = d3.scale.sqrt()
.domain([1, 5])
.range([1, 15])
var hazus_2007_scale = d3.scale.sqrt()
.domain([0, d3.max(hospital_data, function(d) {
return (d["value"]["2007_hazus"]["count"] > 0 ? d["value"]["2007_hazus"]["value"] / d["value"]["2007_hazus"]["count"] : -1000)
})])
.range([0, 16])
var hazus_2010_scale = d3.scale.sqrt()
.domain([0, d3.max(hospital_data, function(d) {
return (d["value"]["2010_hazus"]["count"] > 0 ? d["value"]["2010_hazus"]["value"] / d["value"]["2010_hazus"]["count"] : -1000)
})])
.range([0, 16])
// color scales
var spc_npc_color = d3.scale.quantize()
.domain([1,5])
.range(["#d73027","#fdae61","#66bd63"]) // red, yellow, green
var hazus_2007_color = d3.scale.quantize()
.domain([0, d3.max(hospital_data, function(d) {
return (d["value"]["2007_hazus"]["count"] > 0 ? d["value"]["2007_hazus"]["value"] / d["value"]["2007_hazus"]["count"] : -1000)
})])
.range(["#66bd63","#fdae61","#d73027"]) // green, yellow, red
var hazus_2010_color = d3.scale.quantize()
.domain([0, d3.max(hospital_data, function(d) {
return (d["value"]["2010_hazus"]["count"] > 0 ? d["value"]["2010_hazus"]["value"] / d["value"]["2010_hazus"]["count"] : -1000)
})])
.range(["#66bd63","#fdae61","#d73027"]) // green, yellow, red
// draw td's in each tr
tr.selectAll("td")
.data(function(d) {
var r = d3.values(d.value).map(function(e) {
if (e.count > 0) {
return e.value / e.count;
}
if (e.count == 0) {
return "no data";
}
})
r.unshift(d.key)
return r;
})
.enter()
.append("td")
.append("div")
.attr("class", "tdata")
.style("border-radius", function(d, i) {
if (d != "no data") {
if ((i == 1) || (i == 2)) {
return Math.ceil(spc_npc_scale(d)/2) + "px";
}
if (i == 3) {
return Math.ceil(hazus_2007_scale(d)) + "px";
}
if (i == 4) {
return Math.ceil(hazus_2010_scale(d)) + "px";
}
}
})
.style("height", function(d, i) {
if (d != "no data") {
if ((i == 1) || (i == 2)) {
return Math.ceil(spc_npc_scale(d)) + "px";
}
if (i == 3) {
return Math.ceil(hazus_2007_scale(d)) + "px";
}
if (i == 4) {
return Math.ceil(hazus_2010_scale(d)) + "px";
}
}
})
.style("width", function(d, i) {
if (d != "no data") {
if ((i == 1) || (i == 2)) {
return Math.ceil(spc_npc_scale(d)) + "px";
}
if (i == 3) {
return Math.ceil(hazus_2007_scale(d)) + "px";
}
if (i == 4) {
return Math.ceil(hazus_2010_scale(d)) + "px";
}
}
})
.style("background", function(d, i) {
if (d != "no data") {
if ((i == 1) || (i == 2)) {
return spc_npc_color(d);
}
if (i == 3) {
return hazus_2007_color(d);
}
if (i == 4) {
return hazus_2010_color(d);
}
}
})
.append("span")
.attr("class", "label")
.style("margin-left", function(d, i) {
if (d == "no data") {
return "-50px";
}
})
.text(function(d, i) {
if ((i == 0) || (d == "no data")) {
return d;
}
if ((d != "no data") && (i > 0)) {
return d3.round(d,2);
}
})
// sort columns in table on click
var sort_counter = 0;
thead.selectAll("tr th")
.on("click", function(k) {
sort_counter += 1;
tr.sort(function(a, b) {
if (k == "Hospital") { // don't sort this column
return 0;
}
if (k == "SPC Rating (1 - 5)") {
if (sort_counter % 2 == 0) {
return (a.value.spc.count > 0 ? a.value.spc.value / a.value.spc.count : 1000) -
(b.value.spc.count > 0 ? b.value.spc.value / b.value.spc.count : 1000);
}
if (sort_counter % 2 != 0) {
return (b.value.spc.count > 0 ? b.value.spc.value / b.value.spc.count : -1000) -
(a.value.spc.count > 0 ? a.value.spc.value / a.value.spc.count : -1000);
}
}
if (k == "NPC Rating (1 - 5)") {
if (sort_counter % 2 == 0) {
return (a.value.npc.count > 0 ? a.value.npc.value / a.value.npc.count : 1000) -
(b.value.npc.count > 0 ? b.value.npc.value / b.value.npc.count : 1000);
}
if (sort_counter % 2 != 0) {
return (b.value.npc.count > 0 ? b.value.npc.value / b.value.npc.count : -1000) -
(a.value.npc.count > 0 ? a.value.npc.value / a.value.npc.count : -1000);
}
}
if (k == "2007 Hazus Score (%)") {
if (sort_counter % 2 == 0) {
return (a["value"]["2007_hazus"]["count"] > 0 ? a["value"]["2007_hazus"]["value"] / a["value"]["2007_hazus"]["count"] : 1000) -
(b["value"]["2007_hazus"]["count"] > 0 ? b["value"]["2007_hazus"]["value"] / b["value"]["2007_hazus"]["count"] : 1000);
}
if (sort_counter % 2 != 0) {
return (b["value"]["2007_hazus"]["count"] > 0 ? b["value"]["2007_hazus"]["value"] / b["value"]["2007_hazus"]["count"] : -1000) -
(a["value"]["2007_hazus"]["count"] > 0 ? a["value"]["2007_hazus"]["value"] / a["value"]["2007_hazus"]["count"] : -1000);
}
}
if (k == "2010 Hazus Score (%)") {
if (sort_counter % 2 == 0) {
return (a["value"]["2010_hazus"]["count"] > 0 ? a["value"]["2010_hazus"]["value"] / a["value"]["2010_hazus"]["count"] : 1000) -
(b["value"]["2010_hazus"]["count"] > 0 ? b["value"]["2010_hazus"]["value"] / b["value"]["2010_hazus"]["count"] : 1000);
}
if (sort_counter % 2 != 0) {
return (b["value"]["2010_hazus"]["count"] > 0 ? b["value"]["2010_hazus"]["value"] / b["value"]["2010_hazus"]["count"] : -1000) -
(a["value"]["2010_hazus"]["count"] > 0 ? a["value"]["2010_hazus"]["value"] / a["value"]["2010_hazus"]["count"] : -1000);
}
}
})
})
});
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js