A state grid inspired by an Allison McCann graphic on state taxes. (See also David Mimno’s implementation.)
forked from mbostock's block: State Grid
forked from geraldarthur's block: State Grid Choropleth
xxxxxxxxxx
<meta charset="utf-8">
<style>
.state rect {
fill: #a6a8ab;
}
.state text {
font: 12px monospace;
font-weight: bold;
text-anchor: middle;
fill: white;
}
.q0-5 rect { fill: #fffafa; }
.q1-5 rect { fill: #ffd2c4; }
.q2-5 rect { fill: #ffa68e; }
.q3-5 rect { fill: #fc7657; }
.q4-5 rect { fill: #ef4123; }
#legend {
padding: 1.5em 0 0 1.5em;
}
.list-inline {
padding-left: 0;
list-style: none;
}
.list-inline > li {
display: inline-block;
}
li.key {
border-top-width: 15px;
border-top-style: solid;
font-size: .75em;
width: 10%;
padding-left: 0;
padding-right: 0;
}
li.q0-5 { color: #fffafa; }
li.q1-5 { color: #ffd2c4; }
li.q2-5 { color: #ffa68e; }
li.q3-5 { color: #fc7657; }
li.q4-5 { color: #ef4123; }
</style>
<body>
<svg width="960" height="500"></svg>
<script id="grid" type="text/plain">
ME
WI VT NH
WA ID MT ND MN IL MI NY MA RI
OR NV WY SD IA IN OH PA NJ CT
CA UT CO NE MO KY WV VA MD DE
AZ NM KS AR TN NC SC
OK LA MS AL GA
HI AK TX FL
</script>
<script src="jenks.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var states = [],
//
// EDIT!
//
dataKey = 'overallGrade',
//
// DON'T EDIT!
//
stateKey = 'stateAbbrev',
rowsArr = [
{
"stateName": "VERMONT",
"stateAbbrev": "VT",
"extremeHeat": 76,
"drought": null,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 60
},
{
"stateName": "WEST VIRGINIA",
"stateAbbrev": "WV",
"extremeHeat": 52,
"drought": null,
"wildfires": null,
"inlandFlooding": 36,
"coastalFlooding": null,
"overallGrade": 52
},
{
"stateName": "NORTH DAKOTA",
"stateAbbrev": "ND",
"extremeHeat": 76,
"drought": null,
"wildfires": null,
"inlandFlooding": 60,
"coastalFlooding": null,
"overallGrade": 60
},
{
"stateName": "HAWAII",
"stateAbbrev": "HI",
"extremeHeat": 12,
"drought": null,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": 28,
"overallGrade": 28
},
{
"stateName": "NEW JERSEY",
"stateAbbrev": "NJ",
"extremeHeat": 52,
"drought": null,
"wildfires": null,
"inlandFlooding": 52,
"coastalFlooding": 28,
"overallGrade": 36
},
{
"stateName": "NEW HAMPSHIRE",
"stateAbbrev": "NH",
"extremeHeat": 60,
"drought": null,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": 28,
"overallGrade": 52
},
{
"stateName": "RHODE ISLAND",
"stateAbbrev": "RI",
"extremeHeat": 76,
"drought": null,
"wildfires": null,
"inlandFlooding": 76,
"coastalFlooding": 60,
"overallGrade": 76
},
{
"stateName": "VIRGINIA",
"stateAbbrev": "VA",
"extremeHeat": 84,
"drought": null,
"wildfires": null,
"inlandFlooding": 76,
"coastalFlooding": 60,
"overallGrade": 76
},
{
"stateName": "DELAWARE",
"stateAbbrev": "DE",
"extremeHeat": 84,
"drought": null,
"wildfires": null,
"inlandFlooding": 84,
"coastalFlooding": 84,
"overallGrade": 84
},
{
"stateName": "ALASKA",
"stateAbbrev": "AK",
"extremeHeat": 100,
"drought": null,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": 76,
"overallGrade": 84
},
{
"stateName": "CONNECTICUT",
"stateAbbrev": "CT",
"extremeHeat": 100,
"drought": null,
"wildfires": null,
"inlandFlooding": 100,
"coastalFlooding": 76,
"overallGrade": 100
},
{
"stateName": "MARYLAND",
"stateAbbrev": "MD",
"extremeHeat": 100,
"drought": null,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": 100,
"overallGrade": 84
},
{
"stateName": "MASSACHUSETTS",
"stateAbbrev": "MA",
"extremeHeat": 100,
"drought": null,
"wildfires": null,
"inlandFlooding": 100,
"coastalFlooding": 100,
"overallGrade": 100
},
{
"stateName": "SOUTH CAROLINA",
"stateAbbrev": "SC",
"extremeHeat": 52,
"drought": null,
"wildfires": 76,
"inlandFlooding": 52,
"coastalFlooding": 28,
"overallGrade": 52
},
{
"stateName": "SOUTH DAKOTA",
"stateAbbrev": "SD",
"extremeHeat": 36,
"drought": 12,
"wildfires": null,
"inlandFlooding": 12,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "ARKANSAS",
"stateAbbrev": "AR",
"extremeHeat": 28,
"drought": 12,
"wildfires": 12,
"inlandFlooding": 12,
"coastalFlooding": null,
"overallGrade": 12
},
{
"stateName": "NEVADA",
"stateAbbrev": "NV",
"extremeHeat": 12,
"drought": 12,
"wildfires": 36,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 12
},
{
"stateName": "MONTANA",
"stateAbbrev": "MT",
"extremeHeat": 12,
"drought": 12,
"wildfires": 52,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "KENTUCKY",
"stateAbbrev": "KY",
"extremeHeat": 36,
"drought": 36,
"wildfires": 36,
"inlandFlooding": 12,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "ARIZONA",
"stateAbbrev": "AZ",
"extremeHeat": 60,
"drought": 36,
"wildfires": 28,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 52
},
{
"stateName": "LOUISIANA",
"stateAbbrev": "LA",
"extremeHeat": 52,
"drought": 36,
"wildfires": 52,
"inlandFlooding": null,
"coastalFlooding": 76,
"overallGrade": 52
},
{
"stateName": "MISSISSIPPI",
"stateAbbrev": "MS",
"extremeHeat": 28,
"drought": 28,
"wildfires": 28,
"inlandFlooding": null,
"coastalFlooding": 12,
"overallGrade": 12
},
{
"stateName": "WYOMING",
"stateAbbrev": "WY",
"extremeHeat": 52,
"drought": 28,
"wildfires": 28,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "TEXAS",
"stateAbbrev": "TX",
"extremeHeat": 12,
"drought": 28,
"wildfires": 28,
"inlandFlooding": null,
"coastalFlooding": 36,
"overallGrade": 12
},
{
"stateName": "ILLINOIS",
"stateAbbrev": "IL",
"extremeHeat": 36,
"drought": 28,
"wildfires": null,
"inlandFlooding": 28,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "OHIO",
"stateAbbrev": "OH",
"extremeHeat": 12,
"drought": 28,
"wildfires": null,
"inlandFlooding": 28,
"coastalFlooding": null,
"overallGrade": 28
},
{
"stateName": "MISSOURI",
"stateAbbrev": "MO",
"extremeHeat": 52,
"drought": 28,
"wildfires": 12,
"inlandFlooding": 12,
"coastalFlooding": null,
"overallGrade": 12
},
{
"stateName": "IOWA",
"stateAbbrev": "IA",
"extremeHeat": 52,
"drought": 60,
"wildfires": null,
"inlandFlooding": 52,
"coastalFlooding": null,
"overallGrade": 60
},
{
"stateName": "TENNESSEE",
"stateAbbrev": "TN",
"extremeHeat": 60,
"drought": 60,
"wildfires": 60,
"inlandFlooding": 28,
"coastalFlooding": null,
"overallGrade": 52
},
{
"stateName": "GEORGIA",
"stateAbbrev": "GA",
"extremeHeat": 52,
"drought": 60,
"wildfires": 76,
"inlandFlooding": 52,
"coastalFlooding": 36,
"overallGrade": 52
},
{
"stateName": "WISCONSIN",
"stateAbbrev": "WI",
"extremeHeat": 76,
"drought": 52,
"wildfires": null,
"inlandFlooding": 60,
"coastalFlooding": null,
"overallGrade": 76
},
{
"stateName": "ALABAMA",
"stateAbbrev": "AL",
"extremeHeat": 36,
"drought": 52,
"wildfires": 12,
"inlandFlooding": null,
"coastalFlooding": 12,
"overallGrade": 28
},
{
"stateName": "KANSAS",
"stateAbbrev": "KS",
"extremeHeat": 60,
"drought": 52,
"wildfires": 52,
"inlandFlooding": 36,
"coastalFlooding": null,
"overallGrade": 36
},
{
"stateName": "INDIANA",
"stateAbbrev": "IN",
"extremeHeat": 52,
"drought": 52,
"wildfires": null,
"inlandFlooding": 52,
"coastalFlooding": null,
"overallGrade": 52
},
{
"stateName": "NEBRASKA",
"stateAbbrev": "NE",
"extremeHeat": 28,
"drought": 52,
"wildfires": null,
"inlandFlooding": 52,
"coastalFlooding": null,
"overallGrade": 36
},
{
"stateName": "IDAHO",
"stateAbbrev": "ID",
"extremeHeat": 28,
"drought": 52,
"wildfires": 60,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 36
},
{
"stateName": "NEW MEXICO",
"stateAbbrev": "NM",
"extremeHeat": 76,
"drought": 52,
"wildfires": 76,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 76
},
{
"stateName": "COLORADO",
"stateAbbrev": "CO",
"extremeHeat": 76,
"drought": 84,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 76
},
{
"stateName": "FLORIDA",
"stateAbbrev": "FL",
"extremeHeat": 28,
"drought": 84,
"wildfires": 84,
"inlandFlooding": 28,
"coastalFlooding": 12,
"overallGrade": 52
},
{
"stateName": "NORTH CAROLINA",
"stateAbbrev": "NC",
"extremeHeat": 84,
"drought": 84,
"wildfires": 100,
"inlandFlooding": 76,
"coastalFlooding": 52,
"overallGrade": 84
},
{
"stateName": "MINNESOTA",
"stateAbbrev": "MN",
"extremeHeat": 76,
"drought": 76,
"wildfires": null,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 76
},
{
"stateName": "OKLAHOMA",
"stateAbbrev": "OK",
"extremeHeat": 60,
"drought": 76,
"wildfires": 52,
"inlandFlooding": 28,
"coastalFlooding": null,
"overallGrade": 60
},
{
"stateName": "UTAH",
"stateAbbrev": "UT",
"extremeHeat": 28,
"drought": 76,
"wildfires": 76,
"inlandFlooding": null,
"coastalFlooding": null,
"overallGrade": 60
},
{
"stateName": "MICHIGAN",
"stateAbbrev": "MI",
"extremeHeat": 76,
"drought": 76,
"wildfires": null,
"inlandFlooding": 76,
"coastalFlooding": null,
"overallGrade": 76
},
{
"stateName": "MAINE",
"stateAbbrev": "ME",
"extremeHeat": 28,
"drought": 76,
"wildfires": null,
"inlandFlooding": 52,
"coastalFlooding": 52,
"overallGrade": 28
},
{
"stateName": "WASHINGTON",
"stateAbbrev": "WA",
"extremeHeat": 28,
"drought": 76,
"wildfires": 100,
"inlandFlooding": 76,
"coastalFlooding": 52,
"overallGrade": 84
},
{
"stateName": "OREGON",
"stateAbbrev": "OR",
"extremeHeat": 12,
"drought": 100,
"wildfires": 84,
"inlandFlooding": 60,
"coastalFlooding": 52,
"overallGrade": 76
},
{
"stateName": "PENNSYLVANIA",
"stateAbbrev": "PA",
"extremeHeat": 84,
"drought": 100,
"wildfires": null,
"inlandFlooding": 84,
"coastalFlooding": 76,
"overallGrade": 100
},
{
"stateName": "NEW YORK",
"stateAbbrev": "NY",
"extremeHeat": 100,
"drought": 100,
"wildfires": null,
"inlandFlooding": 100,
"coastalFlooding": 76,
"overallGrade": 100
},
{
"stateName": "CALIFORNIA",
"stateAbbrev": "CA",
"extremeHeat": 100,
"drought": 100,
"wildfires": 100,
"inlandFlooding": 100,
"coastalFlooding": 100,
"overallGrade": 100
}
];
d3.select("#grid").text().split("\n").forEach(function(line, i) {
var re = /\w+/g, m;
while (m = re.exec(line)) {
console.log(_.findWhere(rowsArr, { 'stateAbbrev': m[0]}))
states.push({
name: m[0],
data: _.result(_.findWhere(rowsArr, { 'stateAbbrev': m[0]}), dataKey),
x: m.index / 3,
y: i
});
}
});
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var gridWidth = d3.max(states, function(d) { return d.x; }) + 1,
gridHeight = d3.max(states, function(d) { return d.y; }) + 1,
cellSize = 40;
var nestedData = d3.nest()
.key(function(d) { return d.stateAbbrev; })
.entries(rowsArr);
var mappedData = function mappedValues(key) {
return rowsArr.map(function(stateObj) {
return stateObj[dataKey]
})
}
var jenks5 = d3.scale.quantile()
.domain(jenks(mappedData(stateKey), 4))
.range(d3.range(5).map(function(i) { return "q" + i + "-5"; }));
var state = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.selectAll(".state")
.data(states)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + (d.x - gridWidth / 2) * cellSize + "," + (d.y - gridHeight / 2) * cellSize + ")"; })
.attr("class", function(d) {
var currData = d.data,
currClassStr = '';
if (currData !== null) {
currClassStr += "state " + jenks5(d.data)
} else {
currClassStr += "state"
}
return currClassStr;
});
state.append("rect")
.attr("x", -cellSize / 2)
.attr("y", -cellSize / 2)
.attr("width", cellSize - 1)
.attr("height", cellSize - 1);
state.append("text")
.attr("dy", ".35em")
.text(function(d) { return d.name; });
var legend = d3.select('body')
.insert('div', ":first-child")
.attr("id", "legend")
.append('ul')
.attr('class', 'list-inline');
var keys = legend.selectAll('li.key')
.data(jenks5.range());
keys.enter().append('li')
.attr('class', function(d) { return'key ' + d; })
.style('border-top-color', String);
</script>
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js
https://d3js.org/d3.v3.min.js