index.html
<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
body {
font-family: arial;
font-size: 12px;
}
.axis line {
fill: none;
stroke: #000;
stroke-width: 1px;
}
.axis text {
font-family: arial, sans-serif;
font-size: 12px;
pointer-events: none;
fill: #777;
}
.domain {
fill: none;
}
.y.axis text {
text-anchor: end !important;
font-size:12px;
}
.hull {
stroke-width: 12px;
stroke-linejoin: round;
}
</style>
<body>
<div class="g-all-charts-container">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script>
var margin = {top: 30, right: 30, bottom: 30, left: 50},
width = 800 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([0,70])
.range([0,width]);
var yScale = d3.scale.linear()
.domain([-25,25])
.range([height,0]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var colorScale = d3.scale.category10();
d3.tsv("barley.tsv", ready);
function ready(err, data) {
if (err) console.warn(err, "error loading data");
data.forEach(function(d) {
d['1931'] = +d['1931'];
d['yoy'] = +d['yoy'];
});
var container = d3.select(".g-all-charts-container")
.append("div")
.attr("class", "g-container");
var svg = container.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 + ")");
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var nestedData = d3.nest()
.key(function(d) { return d.site })
.entries(data);
nestedData.forEach(function(d) {
d.vertices = d3.geom.hull(
d.values.map(function(d) {
return [xScale(d['1931']), yScale(d['yoy'])];
})
);
});
svg.selectAll(".hull")
.data(nestedData)
.enter().append("path")
.attr("class", "hull")
.attr("d", function(d) { return "M" + d.vertices.join("L") + "Z"; })
.style("fill", function(d) { return colorScale(d.key); })
.style("stroke", function(d) { return colorScale(d.key); })
.style("fill-opacity", 0)
.style("stroke-opacity", 0);
svg.selectAll(".variety-nodes")
.data(data)
.enter().append("circle")
.attr("class", "variety-nodes")
.attr("r", 0)
.attr("cx", function(d) { return xScale(d['1931'])})
.attr("cy", function(d) { return yScale(d['yoy'])})
d3.selectAll(".variety-nodes")
.transition()
.duration(1000)
.delay(function(d) { return 2000 + (d.yoy*200); })
.attr("r", 3)
.style("fill", function(d) { return d.yoy > 0 ? 'black' : 'red' })
.style("stroke", "#fff")
.style("stroke-width", 1)
svg.selectAll(".hull")
.transition()
.delay(7000)
.style("fill-opacity", 1)
.style("stroke-opacity", 1);
var legend = svg.selectAll(".legend")
.data(colorScale.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", colorScale);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
svg.append("line")
.attr("x1", 0)
.attr("y1", yScale(0))
.attr("x2", width)
.attr("y2", yScale(0))
.style("stroke", "#000")
.style("stroke-width", 1);
var defs = svg.append("defs");
defs.append("marker")
.attr("id", "triangle-start")
.attr("viewBox", "0 0 10 10")
.attr("refX", 10)
.attr("refY", 5)
.attr("markerWidth", -6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
defs.append("marker")
.attr("id", "triangle-end")
.attr("viewBox", "0 0 10 10")
.attr("refX", 10)
.attr("refY", 5)
.attr("markerWidth", -6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z")
.style("fill","red");
svg.append("line")
.attr("x1", 80)
.attr("y1", yScale(-5))
.attr("x2", 80)
.attr("y2", yScale(0))
.style("stroke", "red")
.style("stroke-width", 1)
.style("stroke-dasharray", 2)
.attr("marker-start", "url(#triangle-end)");
svg.append("text")
.attr("x",80)
.attr("y", yScale(-5))
.attr("dy", 8)
.style("fill","red")
.style("text-anchor","middle")
.style("font","8px sans-serif")
.text("Down year over year")
svg.append("line")
.attr("x1", 60)
.attr("y1", yScale(5))
.attr("x2", 60)
.attr("y2", yScale(0))
.style("stroke", "#000")
.style("stroke-width", 1)
.style("stroke-dasharray", 2)
.attr("marker-start", "url(#triangle-start)");
svg.append("text")
.attr("x", 60)
.attr("y", yScale(5))
.attr("dy", -2)
.style("text-anchor","middle")
.style("font","8px sans-serif")
.text("Up year over year")
}
</script>
</body>