Skip to content

Instantly share code, notes, and snippets.

@jashcny
Last active October 14, 2016 15:55
Show Gist options
  • Save jashcny/9d9f6423aff9cdf7ef54 to your computer and use it in GitHub Desktop.
Save jashcny/9d9f6423aff9cdf7ef54 to your computer and use it in GitHub Desktop.
Week 8: My Update Plot.
Region State GunDeaths Ownership DeathRate
West Alaska 144 61.7 19.8
South Alabama 860 48.9 17.6
West Arizona 941 32.3 14.1
South Arkansas 501 58 16.8
West California 3026 20.1 7.7
West Colorado 619 34.3 11.5
Northeast Connecticut 161 16.6 4.4
South Delaware 100 5.3 10.3
South Florida 2442 32.5 11.9
South Georgia 1184 31.6 12.6
West Hawaii 38 45.1 2.6
West Idaho 227 57 14.1
Midwest Illinois 1117 26.2 8.6
Midwest Indiana 857 33.8 13
Midwest Iowa 253 33.8 8
Midwest Kansas 331 32.3 11.4
South Kentucky 622 42.4 13.7
South Louisiana 886 44.5 19.3
Northeast Maine 158 22.6 10.9
South Maryland 578 20.7 9.7
Northeast Massachusetts 213 22.6 3.1
Midwest Michigan 1190 28.8 12
Midwest Minnesota 427 36.7 7.6
South Mississippi 525 42.8 17.8
Midwest Missouri 880 27.1 14.4
West Montana 172 52.3 16.7
Midwest Nebraska 168 19.8 9
West Nevada 395 37.5 13.8
South New Hampshire 93 14.4 6.4
Northeast New Jersey 506 11.3 5.7
West New Mexico 326 49.9 15.5
Northeast New York 863 10 4.2
South North Carolina 1223 28.7 12.1
Midwest North Dakota 86 47.9 11.8
Midwest Ohio 1289 19.6 11
South Oklahoma 632 31.2 16.5
West Oregon 463 26.6 11
Northeast Pennsylvania 1451 27.1 11.2
Northeast Rhode Island 56 5.8 5.2
South South Carolina 745 44.4 15.2
Midwest South Dakota 80 35 10
South Tennessee 1030 39.4 15.4
South Texas 2778 35.7 10.6
West Utah 339 31.9 12.6
Northeast Vermont 65 28.8 9.2
South Virginia 833 29.3 10.2
West Washington 632 27.7 8.7
South West Virginia 280 54 14.3
Midwest Wisconsin 570 34.7 9.7
West Wyoming 102 53.8 16.7
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gun Death Rates VS. Gun Ownership By State</title>
<style>
@import url(https://fonts.googleapis.com/css?family=Raleway:400);
@import url(https://fonts.googleapis.com/css?family=Raleway:400italic|Poiret+One|Ubuntu|Oxygen);
@import url(https://fonts.googleapis.com/css?family=Raleway:400italic|Poiret+One|Ubuntu);
body {
background-color: white;
font-family: Helvetica, Arial, sans-serif;
}
h1 {
font-family: 'Oxygen', sans-serif;
font-size: 28px;
margin-left: 340px;
color: rgb(233, 42, 58);
}
p {
font-family: 'Roboto', sans-serif;
font-size: 16px;
}
svg {
padding-left: 355px;
padding-bottom: 10px;
padding-top: 20px;
}
.bar rect {
fill: rgba(233, 42, 58,0.6);
}
.bar rect:hover {
fill: rgb(233, 42, 58);
}
.value {
fill: black;
font-size: 12px;
font-family: 'Ubuntu', sans-serif;
}
.axis {
shape-rendering: crispEdges;
font-size: 13px;
font-family: 'Ubuntu', sans-serif;
}
.axis path {
fill: none;
stroke: none;
}
.x.axis path {
fill: none;
stroke: white;
}
.x.axis line {
stroke: rgb(189,189,189);
stroke-opacity: .8;
}
.y.axis path {
stroke: black;
}
#source {
margin-left: 240px;
margin-top: 50px;
}
#p1 {
margin-left: 240px;
margin-top: 50px;
}
#menu {
margin-left: 350px;
margin-bottom: 10px;
margin-top: 40px;
}
.label {
font-size: 13px;
font-family: 'Ubuntu', sans-serif;
}
#pp,#tt {
margin-left: 280px;
}
.tooltip {
position: absolute;
z-index: 10;
opacity: 1;
}
.tooltip p {
width: initial;
font-family: "Open Sans", sans-serif;
line-height: 1.4;
color: black;
font-size: 13px;
background-color: rgba(255,255,255,0.8);
border: rgba(230,230,230,1) 1px solid;
padding: 5px 7px 5px 7px;
}
#menu select {
background: rgba(233, 42, 58,0.4);
width: 220px;
padding: 5px;
font-size: 14px;
line-height: 1;
border: 0;
border-radius: 0;
height: 34px;
}
</style>
</head>
<body>
<h1>Gun Death Rates VS. Gun Ownership By State</h1>
<p id="p1">Notes:</p>
<div id="pp">
<p>(1) Gun deaths are the annual average rate per 100,000 residents from 2004 through 2010, provided by the CDC.</p>
<p>(2) Ownership rates are from a randomized survey conducted in 2013 by Harvard University. </p>
</div>
<p id="source">Sources:</p>
<p id="tt"> U.S. Centers for Disease Control and Prevention; “Gun ownership and social gun culture,” Injury Prevention, Kalesan et al; The Oregonian.</p>
<div id="menu">
<select>
<option value="GunDeaths" >Gun Deaths</option>
<option value="Ownership" >Ownership</option>
<option value="DeathRate" >Death Rate</option>
//TODO: fill in the others here. What do you use for the values?
</select>
</div>
<div id="chart">
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script>
var fullwidth = 700,
fullheight = 550;
var margin = {top: 40, right: 40, bottom: 10, left: 100},
width = fullwidth - margin.right - margin.left;
height = fullheight - margin.top - margin.bottom;
var states,
prevRate;
var xScale = d3.scale.linear()
.range([0, width]);
var yScale = d3.scale.ordinal()
.rangeRoundBands([0, height], .3);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("top")
.ticks(8)
.outerTickSize([2]);
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip");
var svg = d3.select("#chart").append("svg")
.attr("width", fullwidth)
.attr("height", fullheight)
.style("margin-left", -margin.left + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis");
svg.append("g")
.attr("class", "y axis")
.append("line")
.attr("class", "domain")
.attr("y2", height);
var menu = d3.select("#menu select")
.on("change", redraw);
d3.csv("guncrime.csv", function(data) {
states = data;
// remember d3.keys gets us the column names from these objects, using first row:
var rates = d3.keys(states[0]).filter(function(key) {
return key != "State" && key != "Region"; // this will return columns NOT MATCHING those
});
console.log(rates);
// build menu from the data; could have been done by hand.
menu.selectAll("option")
.data(rates)
.enter().append("option")
.text(function(d) { return d; });
menu.property("value", "GunDeaths");
d3.select("menu").on("change", redraw);
// redraw in this case draws the UI - it uses a variable to determine data column.
redraw();
}); // end load csv
function redraw() {
// get the age for the data access off the menu:
var currentRate = menu.property("value");
console.log(currentRate);
// sort by it and then take the top 10 using slice!
var top20 = states.sort(function(a, b) {
return b[currentRate] - a[currentRate];
})
.slice(0, 20);
yScale.domain(top20.map(function(d) { return d.State; })); // the y scale is ordinal, all the state names
var bar = svg.selectAll(".bar")
.data(top20, function(d) { return d.State; }); // key function!
var barCreate = bar.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(0," + (yScale(d.State) + height) + ")"; })
.style("fill-opacity", 0);
console.log("rate", prevRate); // this is undefined the first time thru.
barCreate.append("rect")
//.attr("width", age && function(d) { return x(d[age]); })
.attr("width", function(d) {
if (prevRate) {
return xScale(d[prevRate]);
}
})
.attr("height", yScale.rangeBand());
barCreate.append("text")
.attr("class", "label")
.attr("x", -3)
.attr("y", yScale.rangeBand()/2 )
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) { return d.State; });
barCreate.append("text")
.attr("class", "value")
//.attr("x", age && function(d) { return x(d[age]) - 3; })
.attr("x", function(d) {
if (prevRate) {
return xScale(d[prevRate]) - 3;
}
})
.attr("y", yScale.rangeBand() / 2)
.attr("dx","3.5em")
.attr("dy", ".35em")
.attr("text-anchor", "end");
preRate = currentRate;
// they are sorted, so take the top value for the max on the domain here:
xScale.domain([0, top20[0][currentRate]]);
// sets the d.yLocation for the bar that's used in the exit transition.
var barUpdate = bar.transition()
.duration(1000)
.attr("transform", function(d) {
// set the value of the current y location for the exit move when it goes.
d.yLocation = yScale(d.State);
return "translate(0," + yScale(d.State) + ")"; })
.style("fill-opacity", 1);
barUpdate.select("rect")
.attr("width", function(d) { return xScale(d[currentRate]); });
barUpdate.select(".value")
.attr("x", function(d) { return xScale(d[currentRate]) - 3; })
.text(function(d) { return d[currentRate] });
var barExit = bar.exit().transition()
.duration(1000)
.attr("transform", function(d) { return "translate(0," + (d.yLocation + height) + ")"; })
.style("fill-opacity", 0)
.remove();
barExit.select("rect")
.attr("width", function(d) { return xScale(d[currentRate]); });
barExit.select(".value")
.attr("x", function(d) { return xScale(d[currentRate]) - 3; })
.text(function(d) { return d[currentRate] });
// transition the axis, so easy if you fixed the domain!
svg.transition().select(".x.axis")
.duration(1000)
.call(xAxis);
var bars = d3.selectAll("g.bar");
bars.on("mousemove", mousemove)
.on("mouseout", mouseout);
if (currentRate == "GunDeaths") {
bars.on("mouseover", mouseoverPP);
}
if (currentRate == "Ownership") {
bars.on("mouseover", mouseoverUR);
}
if (currentRate == "DeathRate") {
bars.on("mouseover", mouseoverMF);
}
} // end of redraw
function mousemove(d) {
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
function mouseout(d) {
d3.select(this)
.transition()
tooltip.style("display", "none");
}
function selectMenu(menu) {
var thisMenu = d3.select(menu);
d3.selectAll("menu").classed("selected", false);
thisMenu.classed("selected", true);
}
function OwnershipChange() {
bars
.on("mouseover", mouseoverUR)
.on("mousemove", mousemove)
.on("mouseout", mouseout);
}
function DeathRateChange() {
bars
.on("mouseover", mouseoverMF)
.on("mousemove", mousemove)
.on("mouseout", mouseout);
}
function GunDeathsChange() {
bars
.on("mouseover", mouseoverPP) // same as the initial case!
.on("mousemove", mousemove)
.on("mouseout", mouseout);
selectMenu(this);
}
function mouseoverPP(d) {
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Region: "+ d.Region+"</br>"+ "State: " +d.State + "</br>" +"Gun Deaths: " +d.GunDeaths+"</p>");
}
function mouseoverUR(d) {
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Region: "+ d.Region+"</br>"+ "State: " +d.State + "</br>"+"Ownership: "+ d.Ownership +"%"+ "</p>");
}
function mouseoverMF(d) {
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Region: "+ d.Region+"</br>"+ "State: " +d.State + "</br>"+"Death Rate: "+ d.DeathRate +"%"+ "</p>");
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment