Skip to content

Instantly share code, notes, and snippets.

@deckerlr
Last active March 29, 2016 17:30
Show Gist options
  • Save deckerlr/362c366316499fa91e9b to your computer and use it in GitHub Desktop.
Save deckerlr/362c366316499fa91e9b to your computer and use it in GitHub Desktop.
VI9

The following scatterplot utilizing d3 is based heavily on code generated by Mike Bostock, Michelle Weigle, and William Q Liu.

When dealing with my current scatterplot, I had plotted rushing yards vs passing yards. Each quarterback was a dot on the scatterplot and the conference to which they belong is color coded. The idea of animated transitions to me is great for change in time statistics. Unfortunately, our data is static. The number of rushing or passing yards is not changing. While animated transitions can be used to switch between different types of graphs or information displayed, I personally do not feel that this is nothing more than art. It does not seem to help the user evaluate the data. Granted the new chart or data may help, but the animated transition was just an artistic path between two views.

The selection and highlight has a much greater ability to help the user further evaluate the scatterplot data. Trying to put myself as the user, I asked what kind of analysis would I like to perform. Trends always come to mind. So I thought that it would be nice to be able to select a quarterback and have his conference highlighted so a trend can be analyzed. You can also click on the legend to accomlish the same highlighting. The highlighting was done for a set delay and then it returns. This was a trde-off between functionality and d3 coding ability.

Player Conf Passing Rushing
Marcus Mariota Pac-12 3773 669
Blake Sims SEC 3250 321
Jake Waters Big 12 3163 471
Connor Cook Big Ten 2900 69
J.T. Barrett Big Ten 2834 938
Bryce Petty Big 12 3305 137
Bo Wallace SEC 3108 218
Dak Prescott SEC 2987 939
Gary Nova Big Ten 2667 -35
Brad Kayaa ACC 2962 -124
Cody Kessler Pac-12 3505 -149
Nick Marshall SEC 2315 780
Jameis Winston ACC 3559 82
Patrick Mahomes Big 12 1547 98
Kenny Hill SEC 2649 156
Brett Hundley Pac-12 3019 548
Trevone Boykin Big 12 3714 659
Chad Voytik ACC 2011 426
Dylan Thompson SEC 3280 -53
Tommy Armstrong Jr Big Ten 2314 664
Trevor Knight Big 12 2197 340
Jared Goff Pac-12 3964 -44
Clint Trickett Big 12 3285 -106
Kevin Hogan Pac-12 2603 245
Mike Bercovici Pac-12 1445 16
Hutson Mason SEC 2019 14
Lucas Falk Pac-12 1883 -70
Taylor Kelly Pac-12 1874 232
Will Gardner ACC 1669 -106
Mitch Leidner Big Ten 1540 461
Connor Halliday Pac-12 3873 -131
Davis Webb Big 12 2539 15
Daxx Garman Big 12 2041 -16
Wes Lunt Big Ten 1729 -80
Marquise Williams ACC 2870 737
Cyler Miles Pac-12 2129 280
Tyler Murphy ACC 1526 1079
Jake Rudock Big Ten 2404 154
Anu Solomon Pac-12 3458 259
Sean Mannion Pac-12 3164 -306
Travis Wilson Pac-12 2012 218
Mike Cummings Big 12 1715 23
Patrick Towles SEC 2718 303
Anthony Jennings SEC 1460 284
Jacoby Brissett ACC 2344 498
Brandon Allen SEC 2125 -13
Devin Gardner Big Ten 1892 258
Tyrone Swoopes Big 12 2352 294
Maty Mauk SEC 2551 335
Sefo Liufau Pac-12 3194 126
C.J. Brown Big Ten 2083 569
Greyson Lambert ACC 1632 -6
Justin Worley SEC 1579 -105
Michael Brewer ACC 2598 -22
Christian Hackenberg Big Ten 2606 -94
Sam Richardson Big 12 2669 421
Anthony Boone ACC 2507 346
Cole Stoudt ACC 1573 101
Trevor Siemian Big Ten 2214 -123
John Wolford ACC 1965 -151
Jeff Driskel SEC 1092 173
Austin Appleby Big Ten 1449 198
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
.tooltip {
position: absolute;
width: 200px;
height: 28px;
pointer-events: none;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.domain(["SEC", "ACC", "Big 12", "Pac-12", "Big Ten"])
.range(["#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
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("data.tsv", function(error, data) {
if (error) throw error;
data.forEach(function(d) {
d.Passing = +d.Passing;
d.Rushing = +d.Rushing;
});
x.domain(d3.extent(data, function(d) { return d.Rushing; })).nice();
y.domain(d3.extent(data, function(d) { return d.Passing; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Rushing Yards (yds)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Passing Yards (yds)")
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.Rushing); })
.attr("cy", function(d) { return y(d.Passing); })
.style("fill", function(d) { return color(d.Conf); })
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(d["Player"])
.style("left", (x(d.Rushing) + 5) + "px")
.style("top", (y(d.Passing) - 15) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
})
.on("click", function(d) {
// Update circles
var current = d.Conf;
console.log(current);
svg.selectAll("circle")
.data(data) // Update with new data
.transition() // Transition from old to new
.duration(1000) // Length of animation
.each("start", function() { // Start animation
d3.select(this) // 'this' means the current element
.attr("r", function(d) {
if (d.Conf == current) {return "15"}
else { return "3.5" } // Change size
})
})
.each("end", function() { // End animation
d3.select(this) // 'this' means the current element
.transition()
.duration(500)
.attr("r", 3.5); // Change radius
});
});
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
.on("click", function(d) {
// Update circles
var current = d;
console.log(current);
svg.selectAll("circle")
.data(data) // Update with new data
.transition() // Transition from old to new
.duration(1000) // Length of animation
.each("start", function() { // Start animation
d3.select(this) // 'this' means the current element
.attr("r", function(d) {
if (d.Conf == current) {return "15"}
else { return "3.5" } // Change size
})
})
.each("end", function() { // End animation
d3.select(this) // 'this' means the current element
.transition()
.duration(500)
.attr("r", 3.5); // Change radius
});
});
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment