Exploring other views of: http://flowingdata.com/2016/02/09/why-people-visit-the-emergency-room/. Code copied from Nathan Yau’s work, and adapted.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="stl.css">
<link href='//fonts.googleapis.com/css?family=Raleway:400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="projectTitle">Seasonality of products involved in ER visits, sorted by most to least seasonal</div>
<div class="projectDesc">For each product type and month, the chart shows the percent of accidents involving that product that took place in that month. For example, in 2014, just over 70% of all ER visits related to Fireworks occured in July. The products are sorted from most to least seasonal, ending with "stair/steps" accidents which are essentially equally likely in any month.</div>
<div class="projectDesc">The dashed line at 8.3% shows an "average" month. The y-scale emphasizes values between 0 and 20%, to better reveal the differences in seasonality between 0 occurances and 2x an average month.</div>
<div class="productDesc">Inspired by and adapted from Nathan Yau's <a href="//flowingdata.com/2016/02/09/why-people-visit-the-emergency-room/">Why People Visit the Emergency Room</a>.</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="stl.js"></script>
</body>
body {
font: 14px 'Inconsolata', Monaco, "Lucida Console", Consolas, "Courier New";
}
.projectTitle {
margin-left: 40px;
}
.projectDesc{
margin-left: 40px;
font-size: 12px;
max-width: 800px;
margin-top: 14px;
}
.hidden {
display: none;
}
.product path {
fill: none;
stroke: blue;
stroke-linejoin: round;
stroke-linecap: round;
stroke-width: 0.8px;
}
.axis path {
stroke: grey;
stroke-width: .4px;
}
.title {
font-size: 12px;
}
.tick line {
stroke: grey;
stroke-width: .4px;
}
.tick text {
fill: grey;
stroke: none;
font-size: 8px;
}
"use strict";
var selected = false;
var months,
monthFormat = d3.time.format("%m");
var chartWidth = 200;
var chartHeight = 100;
var chartHeightMargin = 30;
var chartWidthMargin = 30;
var margin = {
top: 25,
right: 0,
bottom: 50,
left: 40
},
width = 1500 - margin.left - margin.right;
var numWide = Math.floor(width / (chartWidth + chartWidthMargin))
var height = margin.top + margin.bottom + (chartHeight + chartHeightMargin) * 250 / numWide;
var max_radius = 14;
var countFormat = d3.format(",.1%");
var x = d3.time.scale()
.range([0, chartWidth]);
//var y = d3.scale.linear().domain([-1, 7]).range([100, 0])
//var y = d3.scale.linear().domain([-1, 1, 5, 8]).range([100, 60, 35, 0])
var y = d3.scale.linear().domain([0, 1 / 6, .8]).range([chartHeight, chartHeight / 2, 0])
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom')
.tickSize('4')
.tickFormat(d3.time.format("%b"));
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
.tickSize('4')
.tickValues([1 / 12, 1 / 6, .3, .5, .7])
.tickFormat(d3.format(".1%"));
var yCat = d3.scale.linear().domain([0, 250 / numWide]).range([0, height - (chartHeight)])
var xCat = d3.scale.linear().domain([0, 4]).range([0, (chartWidth + chartWidthMargin) * 4])
var line = d3.svg.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.valueSeasonal);
});
var svg = d3.select("body").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 + ")");
d3.tsv("products-monthly-2014-top250.tsv", type, function(error, products) {
console.log(products)
products.sort(function(a, b) {
return b.std - a.std
})
x.domain(d3.extent(months));
// Container for a product line and circles.
var product_container = svg.selectAll('.product')
.data(products)
.enter().append("g")
.attr("class", "product")
.attr("transform", function(d, i) {
return "translate(" + xCat(i % numWide) + "," + yCat(Math.floor(i / numWide)) + ")"
})
.attr("id", function(d) {
return "p" + d.code;
});
//
// Lines.
//
product_container.append('g')
.attr("transform", "translate(0," + y(0) + ")")
.attr("class", function(d) {
return "xAxis axis hidden id-" + d.code
})
.append('g').call(xAxis);
product_container.append('g')
//.attr("transform", "translate(0," + (chartHeight - 25) + ")")
.attr("class", function(d) {
return "hidden axis id-" + d.code
})
.append('g').call(yAxis);
product_container.append("path")
.attr("d", function(d) {
return line(d.values);
})
.attr("class", function(d) {
return d.code;
});
product_container.append("line")
.attr({
'x2': chartWidth,
'y1': y(1 / 12),
'y2': y(1 / 12),
'stroke-dasharray': '5,5',
'stroke': 'grey',
'stroke-width': '.5px'
})
product_container.append("line")
.attr({
'x2': chartWidth,
'y1': y(0),
'y2': y(0),
'stroke': 'grey',
'stroke-width': '.5px'
})
//
// Text
//
product_container.append('text')
.text(function(d) {
return d.name
})
.attr({
'x': 2,
'y': y(.73),
'class': function(d) {
return 'title hidden id-' + d.code
}
})
product_container.append("rect")
.attr({
'height': chartHeight,
'width': chartWidth,
'opacity': 0
})
.on('mouseover', function(d) {
d3.selectAll('.id-' + d.code).classed("hidden", false)
})
.on('mouseout', function(d) {
d3.selectAll('.id-' + d.code).classed("hidden", true)
});;
}); // @end d3.tsv()
function type(d, i) {
var calculateStd = function(data, mean) {
conslole.log('here')
var sumSquaredDiff = 0;
return
}
months = d3.range(1, 13).map(function(d) {
return monthFormat.parse(String(d));
}).filter(Number);
var product = {
code: d.Code,
name: d.Title,
values: null,
annualTotal: 0,
seasonalArray: []
};
for (var i = 1; i <= 12; i++) {
product.annualTotal = product.annualTotal + +d['m' + i]
}
product.mean = product.annualTotal / 12
product.values = months.map(function(m) {
var value = Number(d['m' + Number(monthFormat(m))])
var seasonal = value / product.annualTotal
//var seasonal = (value / (product.annualTotal / 12)) - 1
product.seasonalArray.push(seasonal)
return {
product: product,
date: m,
value: value,
valueSeasonal: seasonal
}
});
product.std = d3.deviation(product.seasonalArray)
return product;
}