Things we learned in class
- data nesting
- functions to draw slopes for each variety
- line transitions using dash array
- mouseover transitions for text
Data Visualization with D3.js at Metis Class 4
yield | variety | year | site | |
---|---|---|---|---|
39.93333 | Manchuria | 1931 | Crookston | |
38.13333 | Glabron | 1931 | Crookston | |
40.46667 | Svansota | 1931 | Crookston | |
41.33333 | Velvet | 1931 | Crookston | |
46.93333 | Trebi | 1931 | Crookston | |
45.66667 | No. 457 | 1931 | Crookston | |
48.56666 | No. 462 | 1931 | Crookston | |
41.6 | Peatland | 1931 | Crookston | |
44.1 | No. 475 | 1931 | Crookston | |
49.86667 | Wisconsin No. 38 | 1931 | Crookston | |
32.96667 | Manchuria | 1932 | Crookston | |
26.16667 | Glabron | 1932 | Crookston | |
20.63333 | Svansota | 1932 | Crookston | |
32.06666 | Velvet | 1932 | Crookston | |
41.83333 | Trebi | 1932 | Crookston | |
34.33333 | No. 457 | 1932 | Crookston | |
30.53333 | No. 462 | 1932 | Crookston | |
25.23333 | Peatland | 1932 | Crookston | |
32.13333 | No. 475 | 1932 | Crookston | |
35.9 | Wisconsin No. 38 | 1932 | Crookston | |
28.96667 | Manchuria | 1931 | Duluth | |
29.66667 | Glabron | 1931 | Duluth | |
25.7 | Svansota | 1931 | Duluth | |
26.3 | Velvet | 1931 | Duluth | |
33.93333 | Trebi | 1931 | Duluth | |
33.6 | No. 457 | 1931 | Duluth | |
28.1 | No. 462 | 1931 | Duluth | |
32 | Peatland | 1931 | Duluth | |
33.06666 | No. 475 | 1931 | Duluth | |
31.6 | Wisconsin No. 38 | 1931 | Duluth | |
22.56667 | Manchuria | 1932 | Duluth | |
25.86667 | Glabron | 1932 | Duluth | |
22.23333 | Svansota | 1932 | Duluth | |
22.46667 | Velvet | 1932 | Duluth | |
30.6 | Trebi | 1932 | Duluth | |
22.7 | No. 457 | 1932 | Duluth | |
22.5 | No. 462 | 1932 | Duluth | |
31.36667 | Peatland | 1932 | Duluth | |
27.36667 | No. 475 | 1932 | Duluth | |
29.33333 | Wisconsin No. 38 | 1932 | Duluth | |
32.96667 | Manchuria | 1931 | Grand Rapids | |
29.13333 | Glabron | 1931 | Grand Rapids | |
29.66667 | Svansota | 1931 | Grand Rapids | |
23.03333 | Velvet | 1931 | Grand Rapids | |
29.76667 | Trebi | 1931 | Grand Rapids | |
32.16667 | No. 457 | 1931 | Grand Rapids | |
24.93334 | No. 462 | 1931 | Grand Rapids | |
34.7 | Peatland | 1931 | Grand Rapids | |
19.7 | No. 475 | 1931 | Grand Rapids | |
34.46667 | Wisconsin No. 38 | 1931 | Grand Rapids | |
22.13333 | Manchuria | 1932 | Grand Rapids | |
14.43333 | Glabron | 1932 | Grand Rapids | |
16.63333 | Svansota | 1932 | Grand Rapids | |
32.23333 | Velvet | 1932 | Grand Rapids | |
20.63333 | Trebi | 1932 | Grand Rapids | |
19.46667 | No. 457 | 1932 | Grand Rapids | |
19.9 | No. 462 | 1932 | Grand Rapids | |
26.76667 | Peatland | 1932 | Grand Rapids | |
15.23333 | No. 475 | 1932 | Grand Rapids | |
20.66667 | Wisconsin No. 38 | 1932 | Grand Rapids | |
27.43334 | Manchuria | 1931 | Morris | |
28.76667 | Glabron | 1931 | Morris | |
25.76667 | Svansota | 1931 | Morris | |
26.13333 | Velvet | 1931 | Morris | |
43.76667 | Trebi | 1931 | Morris | |
28.7 | No. 457 | 1931 | Morris | |
30.36667 | No. 462 | 1931 | Morris | |
29.86667 | Peatland | 1931 | Morris | |
22.6 | No. 475 | 1931 | Morris | |
29.46667 | Wisconsin No. 38 | 1931 | Morris | |
34.36666 | Manchuria | 1932 | Morris | |
35.13333 | Glabron | 1932 | Morris | |
35.03333 | Svansota | 1932 | Morris | |
38.83333 | Velvet | 1932 | Morris | |
46.63333 | Trebi | 1932 | Morris | |
43.53334 | No. 457 | 1932 | Morris | |
47 | No. 462 | 1932 | Morris | |
43.2 | Peatland | 1932 | Morris | |
44.23333 | No. 475 | 1932 | Morris | |
47.16667 | Wisconsin No. 38 | 1932 | Morris | |
27 | Manchuria | 1931 | University Farm | |
43.06666 | Glabron | 1931 | University Farm | |
35.13333 | Svansota | 1931 | University Farm | |
39.9 | Velvet | 1931 | University Farm | |
36.56666 | Trebi | 1931 | University Farm | |
43.26667 | No. 457 | 1931 | University Farm | |
36.6 | No. 462 | 1931 | University Farm | |
32.76667 | Peatland | 1931 | University Farm | |
24.66667 | No. 475 | 1931 | University Farm | |
39.3 | Wisconsin No. 38 | 1931 | University Farm | |
26.9 | Manchuria | 1932 | University Farm | |
36.8 | Glabron | 1932 | University Farm | |
27.43334 | Svansota | 1932 | University Farm | |
26.8 | Velvet | 1932 | University Farm | |
29.06667 | Trebi | 1932 | University Farm | |
26.43334 | No. 457 | 1932 | University Farm | |
25.56667 | No. 462 | 1932 | University Farm | |
28.06667 | Peatland | 1932 | University Farm | |
30 | No. 475 | 1932 | University Farm | |
38 | Wisconsin No. 38 | 1932 | University Farm | |
48.86667 | Manchuria | 1931 | Waseca | |
55.2 | Glabron | 1931 | Waseca | |
47.33333 | Svansota | 1931 | Waseca | |
50.23333 | Velvet | 1931 | Waseca | |
63.8333 | Trebi | 1931 | Waseca | |
58.1 | No. 457 | 1931 | Waseca | |
65.7667 | No. 462 | 1931 | Waseca | |
48.56666 | Peatland | 1931 | Waseca | |
46.76667 | No. 475 | 1931 | Waseca | |
58.8 | Wisconsin No. 38 | 1931 | Waseca | |
33.46667 | Manchuria | 1932 | Waseca | |
37.73333 | Glabron | 1932 | Waseca | |
38.5 | Svansota | 1932 | Waseca | |
37.4 | Velvet | 1932 | Waseca | |
49.2333 | Trebi | 1932 | Waseca | |
42.2 | No. 457 | 1932 | Waseca | |
44.7 | No. 462 | 1932 | Waseca | |
36.03333 | Peatland | 1932 | Waseca | |
41.26667 | No. 475 | 1932 | Waseca | |
58.16667 | Wisconsin No. 38 | 1932 | Waseca |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> | |
<style type="text/css"> | |
body { | |
font: 400 13px/1.2 sans-serif; | |
} | |
.axis path { | |
fill: none; | |
stroke: #000; | |
} | |
.varietyLines:hover { | |
stroke-width: 10; | |
} | |
.content { | |
/* flex box */ | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: -webkit-flex; | |
display: flex; | |
-webkit-flex-flow: row wrap; | |
-moz-flex-flow: row wrap; | |
-ms-flex-flow: row wrap; | |
-o-flex-flow: row wrap; | |
flex-flow: row wrap; | |
flex-flow: row wrap; | |
-webkit-box-pack: center; | |
-webkit-justify-content: center; | |
-ms-flex-pack: center; | |
justify-content: center; | |
} | |
</style> | |
<body> | |
<main class="content"></main> | |
</body> | |
<script> | |
var margin = {top: 20, right: 100, bottom: 40, left: 50}; | |
var width = 300 - margin.left - margin.right, | |
height = 250 - margin.top - margin.bottom; | |
var xScale = d3.scale.ordinal() | |
.domain(['1931','1932']) | |
.rangePoints([0, width]); | |
var yScale = d3.scale.linear() | |
.range([height,0]) | |
var colorScale = d3.scale.category10(); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
d3.csv("barley.csv", function(error, data) { | |
if (error) return console.warn(error); | |
data.forEach(function(d) { | |
d.yield = +d.yield; | |
}) | |
var places = d3.set(data.map(function(d) {return d.site})).values(); | |
places.forEach(function(d) { | |
drawSlopeGraph(d); | |
}) | |
d3.select("body").append("input") | |
.attr("type", "range") | |
.attr("min", 1) | |
.attr("max", 20) | |
.attr("step", 1) | |
.on("change", function(d) { | |
var myValue = this.value | |
d3.selectAll('circle') | |
.transition() | |
.attr("r", myValue) | |
}) | |
function drawSlopeGraph(sitePlace) { | |
var wrapper = d3.select(".content").append("div") | |
.attr("class", "chartWrapper"); | |
wrapper.append("h2") | |
.text(sitePlace); | |
var svg = wrapper.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 + ")"); | |
yScale.domain(d3.extent(data, function(d) {return d.yield})); | |
svg.append("g") | |
.attr("class","y axis") | |
.call(yAxis) | |
svg.append("g") | |
.attr("class","x axis") | |
.attr("transform","translate(0," + height + ")") | |
.call(xAxis) | |
var crookstonData = data.filter(function(d) {return d.site == sitePlace; }) | |
nestedData = d3.nest() | |
.key(function(d) { return d.variety; }) | |
.entries(crookstonData); | |
var circleGroup1932 = svg.selectAll(".circleGroup1932") | |
.data(nestedData) | |
.enter().append("g") | |
.attr("class", "circleGroup1932") | |
.attr("transform", function(d) {return "translate(" + xScale(d.values[1].year) + "," + yScale(d.values[1].yield) + ")"}) | |
circleGroup1932.append("circle") | |
.attr("r", 3) | |
.style("fill", function(d) {return colorScale(d.key); }) | |
circleGroup1932.append("text") | |
.attr("dx", 20) | |
.attr("class", function(d) {return d.key.replace(".", "").replace(" ", ""); }) | |
.text(function(d) {return d.key}) | |
.style("fill", "rgba(0,0,0,0)") | |
.on("mouseenter", function() { | |
d3.select(this) | |
.style("fill", function(d) {return colorScale(d.key); }) | |
}) | |
.on("mouseleave", function() { | |
d3.select(this) | |
.style("fill", "rgba(0,0,0,0)") | |
}) | |
var circleGroup1931 = svg.selectAll(".circleGroup1931") | |
.data(nestedData) | |
.enter().append("g") | |
.attr("class", "circleGroup1931") | |
.attr("transform", function(d) {return "translate(" + xScale(d.values[0].year) + "," + yScale(d.values[0].yield) + ")"}) | |
circleGroup1931.append("circle") | |
.attr("r", 3) | |
.style("fill", function(d) {return colorScale(d.key); }) | |
var varietyLines = svg.selectAll(".varietyLines") | |
.data(nestedData) | |
.enter().append("line") | |
.attr("class", "varietyLines") | |
.attr("stroke-dasharray", width + " " + width) | |
.attr("stroke-dashoffset", width) | |
.attr("x1", function(d) { return xScale(d.values[0].year); }) | |
.attr("x2", function(d) { return xScale(d.values[1].year); }) | |
.attr("y1", function(d) { return yScale(d.values[0].yield); }) | |
.attr("y2", function(d) { return yScale(d.values[1].yield); }) | |
.style("stroke", function(d) {return colorScale(d.key); }) | |
d3.selectAll(".varietyLines") | |
.transition() | |
.duration(2000) | |
.ease("linear") | |
.attr("stroke-dashoffset", 0); | |
} | |
}); | |
</script> |