This block provides a rough re-creation of the Florida Gun Deaths visualization. Keeping in mind the inspiration and issues discussed, try to redesign this visualization. Focus first on editing the style (colors, thickness of lines, etc.) before changing the encoding.
The original visualization appeared in the article This Chart Shows An Alarming Rise In Florida Gun Deaths After 'Stand Your Ground' Was Enacted article by Pamela Engel on Business Insider on February 18, 2014.
The chart was created by Christine Chen. She responded to the discussion, and linked to her inspiration for the graphic. This inspiration appeared in the infographic Iraq's bloody toll by Simon Scarr on South China Morning Post on December 17, 2011.
There was a lot of discussion, especially on Twitter and various blogs, when this visualization came out. Here are some of those posts:
You can access the original (and updated) data for this visualization from the Florida Statistical Analysis Center. Specifically, you can download the "Murder: Firearm Type and Rate for Florida" dataset in PDF or Excel format the UCR Offense Data page.
To generate the data.csv
file, the original 1971_fwd_murder_firearms.xlsx
file was transformed using the following Trifacta Wrangler recipe:
splitrows col: column1 on: '\n' quote: '\"'
delete row: IN(SOURCEROWNUMBER(), [1,2])
split col: column1 on: ',' limit: 11 quote: '\"'
replace col: * with: '' on: '\"' global: true
header
delete row: SOURCEROWNUMBER() == 4
drop col: Total_Murders, Murder_Rate_per_100_000, Total_Handgun, Total_Other_Firearm, Total_Percent_by_Firearms, Percent_by_Handguns, Percent_by_Other_Firearms, Total_by_Firearm_change, Population_Change
rename col: Total_by_Firearm to: 'Total'
delete row: IN(SOURCEROWNUMBER(), [50, 57, 51, 52, 53, 54, 55, 56])
keep row: (DATE(1989, 1, 1) <= Year) && (Year < DATE(2017, 1, 1))
derive value: Total / (Population / 100000) as: 'Rate'
forked from sjengle's block: Florida Gun Deaths
xxxxxxxxxx
<meta charset="utf-8">
<link href='https://fonts.googleapis.com/css?family=Fira+Sans:300,400,500,700' rel='stylesheet' type='text/css'>
<link href='style.css' rel='stylesheet' type='text/css'>
<script src="//d3js.org/d3.v4.min.js"></script>
<body>
<!--
If there is an order you prefer for your elements,
consider pre-defining the g elements in your
preferred order.
//-->
<svg>
<!-- axis lines should be in back -->
<g id="x"></g> <!-- x axis -->
<g id="y"></g> <!-- y axis -->
<!-- header (title) and footer (source) -->
<g id="header"></g>
<g id="footer"></g>
<!-- actual visualization on top -->
<g id="plot">
<g id="bars"></g> <!-- heavy black axis lines -->
<g id="points_label"></g>
<g id="note"></g> <!-- area annotation -->
</g>
<g id="legend"></g>
</svg>
<script>
var size = {width: 750, height: 800};
var pad = {top: 120, right: 45, bottom: 75, left: 60};
var offset = 8;
var width = size.width - pad.left - pad.right;
var height = size.height - pad.top - pad.bottom + offset;
var x = d3.scaleBand()
.range([0, width])
.paddingInner(0.01);
var y = d3.scaleLinear()
.range([0, height]);
var xaxis = d3.axisTop(x)
.tickValues([1990, 1995, 2000, 2005, 2010, 2015])
// .ticks(6)
.tickFormat(function(d) { return d; })
// hide end tick
.tickSizeOuter(0);
var yaxis = d3.axisLeft(y)
.ticks(10)
.tickPadding(5)
.tickSizeOuter(0)
.tickSizeInner(-width); // drawing the grid line
function translate(x, y) {
return "translate(" + x + "," + y + ")";
}
function convert(row) {
row.Year = +row.Year;
row.Population = +row.Population;
row.Total = +row.Total;
row.Rate = +row.Rate;
return row;
}
var svg = d3.select("body").select("svg");
var plot = svg.select("g#plot");
var header = svg.select("g#header");
var footer = svg.select("g#footer");
svg.attr("width", size.width);
svg.attr("height", size.height);
plot.attr("transform", translate(pad.left, pad.top));
/*
* add various text annotation to svg
*/
header.append("text")
.attr("class", "title")
.attr("x", 0)
.attr("y", 0)
.attr("dx", "5px")
.attr("dy", "36pt")
.text("Gun deaths in Florida");
header.append("text")
.attr("class", "subtitle")
.attr("x", 0)
.attr("y", 0)
.attr("dx", "5px")
.attr("dy", "58pt")
.text("Number of murders committed using firearms");
footer.append("text")
.attr("x", 0)
.attr("y", size.height + offset)
.attr("dx", "5px")
.attr("dy", "-23pt")
.text("Source: Florida Department of Law Enforcement");
footer.append("text")
.attr("x", 0)
.attr("y", size.height )
.attr("dx", "5px")
.attr("dy", "-6pt")
.text("Inspiration: https://tinyurl.com/led8ggk");
d3.csv("data.csv", convert, function(error, data) {
if (error) throw error;
// x.domain(d3.extent(data, function(e) {return e.Year;}));
x.domain(data.map(function(d){return d.Year}))
y.domain([0, 900]).nice();
var min_max = d3.extent(data, function (d){return d.Total});
var min = min_max[0],
max = min_max[1];
var minYear, maxYear;
// getting min and max year of number of deaths
data.map(function(d){
if(d.Total == min){minYear = d.Year;}
else if(d.Total == max) {maxYear = d.Year;}
})
var bars = plot.select("#bars")
.selectAll("rect")
.data(data);
bars.enter().append("rect")
.attr("class", "bar")
.attr("width", x.bandwidth())
.attr("x", function(d) {
return x(d.Year);
})
.attr("y", 0)
.attr("height", function(d) {
return y(d.Total);
});
/*
* draw x- and y-axis
* should be behind other elements
*/
svg.select("g#y")
.attr("transform", translate(pad.left-2, pad.top))
.call(yaxis);
// slighltly adjust the header and footer
svg.select("g#header")
.attr("transform", translate(pad.left, 0))
svg.select("g#footer")
.attr("transform", translate(pad.left, 0))
svg.select("g#x")
.attr("transform", translate(pad.left, pad.top-2))
.call(xaxis)
.selectAll(".tick text")
.style("text-anchor", "middle")
// .attr("x", data.map(function(d){return x(d.Year)}))
.attr("x", 0)
.attr("y", 0)
.attr("dy", "-0.6em");
plot.select("g#points_label")
.selectAll("text")
.data(data)
.enter()
.filter(function (d) {return d.Total == min || d.Total == max})
.append("text")
.attr("x", function(d){return x(d.Year);})
.attr("y", function(d){return y(d.Total);})
.attr("dy", "-0.5em")
.attr("dx", "0.05em")
.style("font", "0.8em sans-serif")
.style("fill", "white")
.text(function(d){
return d.Total;
});
/*
* plot annotation on top of area
*/
var note = plot.select("g#note");
note.selectAll("text")
// text with manual line breaks
.data(["2005", "Florida enacted", "its 'Stand Your", "Ground' law"].reverse())
.enter()
.append("text")
.attr("id", function(d, i) { return "note-" + i; })
.attr("x", x(2000))
.attr("y", y(850))
.attr("dx", x(2004) - x(2005))
.attr("dy", function(d, i) { return (-i * 2) + "ex"; })
.text(function(d) { return d; });
note.append("line")
.attr("x1", x(2005)+10)
.attr("x2", x(2002))
.attr("y1", y(530) + 5)
.attr("y2", y(720));
svg.select("g#legend")
.attr("transform", translate(0, size.height/2))
.append("text")
.attr("dx", "-5em")
.attr("transform", "rotate(90)")
.text("Number of Gun Deaths");
});
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js