taking the data from here: http://www.nytimes.com/interactive/2015/12/10/us/gun-sales-terrorism-obama-restrictions.html?_r=0
which Curran posted here (thanks!): https://github.com/curran/data/blob/gh-pages/nyt/gun_sales/all-data.csv
looking at the same data, but all the years on one graph instead. Very much a WIP.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="gunsales.css">
<link href='//fonts.googleapis.com/css?family=Raleway:400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div>Monthly Gun Sales from 2000 to 2015, data from <a href="//www.nytimes.com/interactive/2015/12/10/us/gun-sales-terrorism-obama-restrictions.html?_r=0">NYT</a></div>
<div>Click on the chart to overlay the years</div>
<div class="vis"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="gunsales.js"></script>
</body>
.lines {
fill: none;
stroke-width: 1.5px;
}
.lines:hover {
stroke: #f00;
}
.axis path {
stroke-width: 1px;
stroke: #808080;
fill: none;
}
.axis line {
fill: none;
stroke: #808080;
shape-rendering: crispEdges;
}
"use strict";
// STANDARD VARIABLES
var margin = {
top: 50,
right: 100,
bottom: 30,
left: 100
},
numberOfYears = 16,
thisYear = 2015,
singleChartWidth = 50,
width = singleChartWidth * numberOfYears,
height = 500 - margin.top - margin.bottom;
var yearToNum = function(data) {
return numberOfYears - 1 - thisYear + +data.key
}
// STANDARD SVG SETUP
var svg = d3.select('.vis')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var scaleGunSales = d3.scale.linear().domain([0, 2500000]).range([height, 0])
// 12 is number of months
var xAxisMonth = d3.scale.linear().domain([1, 12]).range([0, singleChartWidth])
var xAxisMonthWide = d3.scale.linear().domain([1, 12]).range([0, width])
var xAxisYear = d3.scale.linear().domain([0, 16]).range([0, width])
var xAxis = d3.svg.axis()
.scale(xAxisYear)
.orient("bottom")
.ticks(16)
.tickFormat(function(d) {
return d3.time.format("%Y")(new Date(2000 + d, 7, 1))
});
var yAxis = d3.svg.axis()
.scale(scaleGunSales)
.orient("left");
var calculateLine = function(xScale) {
return d3.svg.line()
.x(function(d) {
return xScale(+d.month)
})
.y(function(d) {
return scaleGunSales(+d.guns_total)
})
.interpolate("linear")
}
var strokeColor = d3.scale.linear()
.domain([2000, 2015])
.range(["#ffdbdb", "#680c0c"])
.interpolate(d3.interpolateHcl);
d3.csv('nytdata.csv', function(error, data) {
if (error) throw error;
var annualData = d3.nest()
.key(function(d) {
return d.year;
})
.entries(data);
svg.selectAll(".lines")
.data(annualData)
.enter()
.append("path")
.attr("d", function(d) {
return calculateLine(xAxisMonth)(d.values)
})
.attr("transform", function(d) {
//return "translate(0,0)"
return "translate(" + (singleChartWidth * yearToNum(d)) + ",0)"
})
.attr("class", "lines")
.attr("stroke", function(d) {
return strokeColor(+d.key)
});
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.select("body").on("click", function() {
svg.select(".x")
.transition()
.duration(400)
.call(xAxis.scale(xAxisMonth).ticks(0))
.transition()
.delay(2400)
.duration(1000)
.call(xAxis.scale(xAxisMonthWide)
.ticks(12)
.tickFormat(function(d) {
return d3.time.format("%B")(new Date(2000, d - 1, 15))
})
)
d3.selectAll(".lines")
.transition()
.delay(function(d) {
return yearToNum(d) * 100 + 400
})
.duration(400)
.attr("transform", function(d) {
return "translate(0,0)"
})
.transition()
.delay(2400)
.duration(1000)
.attr("d", function(d) {
return calculateLine(xAxisMonthWide)(d.values)
})
})
})
.lines
fill: none
stroke-width: 1.5px
&:hover
stroke: red
.axis
path
stroke-width: 1px
stroke: grey
fill: none
line
fill: none
stroke: grey
shape-rendering: crispEdges