block by dhoboy b536ee036c8c5ef50a8e

Seismic Ratings and Collapse Probabilities of California Hospitals

Full Screen

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

index.html

<!DOCTYPE html>
<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="//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>