|
<!DOCTYPE html> |
|
<html> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <!-- for color scales --> |
|
|
|
<!-- Example based on http://bl.ocks.org/mbostock/3887118 --> |
|
<!-- Tooltip example from http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html --> |
|
|
|
<style> |
|
body { font-family: calibri; } |
|
.axis { font: 14px calibri; } |
|
.label {font: 16px calibri; } |
|
|
|
.tooltip { |
|
position: absolute; |
|
width: 150px; |
|
height: 60px; |
|
background: #f2f2f2; |
|
pointer-events: none; |
|
} |
|
</style> |
|
|
|
<body> |
|
<h2>Scatterplot</h2> |
|
<div><svg id="chart1" width="700" height="400"></svg></div> |
|
|
|
<script> |
|
// add the graph canvas to the body of the webpage |
|
var svg = d3.select("#chart1"), |
|
margin = {top: 20, right: 20, bottom: 50, left: 70}, |
|
width = +svg.attr("width") - margin.left - margin.right, |
|
height = +svg.attr("height") - margin.top - margin.bottom; |
|
|
|
var g = svg.append("g") |
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
|
//var colorScale = d3.scaleOrdinal(d3.schemeCategory20); |
|
// add the tooltip area to the webpage |
|
var tooltip = d3.select("body").append("div") |
|
.attr("class", "tooltip") |
|
.style("opacity", 0); |
|
|
|
// load data |
|
d3.csv("passing-stats-2014.csv", function (d) { |
|
// change string (from CSV) into number format |
|
d["Passing TD"] = +d["Passing TD"]; |
|
d["Rushing TD"] = +d["Rushing TD"]; |
|
return d; |
|
}, function(error, data) { |
|
|
|
if (error) throw error; |
|
|
|
/* |
|
* value accessor - returns the value to encode for a given data object. |
|
* scale - maps value to a visual display encoding, such as a pixel position. |
|
* map function - maps from data value to display value |
|
*/ |
|
|
|
// setup x |
|
var xValue = function(d) { return d["Rushing TD"];}, // data -> value |
|
xScale = d3.scaleLinear().range([0, width]), // value -> display |
|
xMap = function(d) { return xScale(xValue(d));}; // data -> display |
|
|
|
|
|
// setup y |
|
var yValue = function(d) { return d["Passing TD"];}, // data -> value |
|
yScale = d3.scaleLinear().range([height, 0]), // value -> display |
|
yMap = function(d) { return yScale(yValue(d));}; // data -> display |
|
|
|
// don't want dots overlapping axis, so add in buffer to data domain |
|
xScale.domain([d3.min(data, xValue)-1, d3.max(data, xValue)+1]); |
|
yScale.domain([0, d3.max(data, yValue)+1]); |
|
|
|
// x-axis |
|
g.append("g") |
|
.attr("class", "axis x-axis") |
|
.attr("transform", "translate(0," + height + ")") // move axis to bottom of chart |
|
.call(d3.axisBottom(xScale)); |
|
|
|
// x-axis label |
|
g.append("text") |
|
.attr("class", "label") |
|
.attr("x", width/2) |
|
.attr("y", height+(margin.bottom*0.75)) |
|
.style("text-anchor", "middle") |
|
.text("Rushing TDs"); |
|
|
|
// y-axis |
|
g.append("g") |
|
.attr("class", "axis y-axis") |
|
.call(d3.axisLeft(yScale)); |
|
|
|
// y-axis label |
|
g.append("text") |
|
.attr("class", "label") |
|
.attr("x", 0-(height/2)) |
|
.attr("y", 0-(margin.left*0.55)) |
|
.attr("transform", "rotate(-90)") // rotate text -90 degrees from x, y |
|
.style("text-anchor", "middle") |
|
.text("Passing TDs"); |
|
|
|
// draw dots |
|
g.selectAll(".dot") |
|
.data(data) |
|
|
|
.enter().append("circle") |
|
.attr("class", "dot") |
|
.attr("r", function (d) { |
|
if (d.Rate >= 150) {return d = 1.5} |
|
else if (d.Rate < 150) {return d = 2.5}; |
|
|
|
|
|
}) |
|
.attr("cx", xMap) |
|
.attr("cy", yMap) |
|
.style("fill", function (d) { |
|
|
|
if (d.Conf === 'Pac-12') {return 'red';} |
|
else if (d.Conf === 'MWC') {return 'blue';} |
|
else if (d.Conf === 'MAC') {return 'violet';} |
|
else if (d.Conf === 'Big 12') {return 'grey';} |
|
else if (d.Conf === 'Big Ten') {return 'orange';} |
|
else if (d.Conf === 'SEC') {return 'black';} |
|
else if (d.Conf === 'CUSA') {return 'aqua';} |
|
else if (d.Conf === 'ACC') {return 'yellow';} |
|
else if (d.Conf === 'American') {return 'maroon';} |
|
else if (d.Conf === 'Ind') {return 'green';} |
|
else if (d.Conf === 'Sun Belt') {return 'brown';}; |
|
|
|
})//tried to use colorScale but was unable to generate a common color for all the conferences |
|
|
|
// tooltip |
|
.on("mouseover", function(d) { |
|
tooltip.transition() |
|
.duration(200) // ms delay before appearing |
|
.style("opacity", .8); // tooltip appears on mouseover |
|
tooltip.html(d["Player"] + "<br/> " + d.School + "<br/> " + d.Conf + "<br/>(" + xValue(d) |
|
+ ", " + yValue(d) + ")") |
|
.style("left", (d3.event.pageX + 10) + "px") // specify x location |
|
.style("top", (d3.event.pageY - 28) + "px"); // specify y location |
|
|
|
}) |
|
.on("mouseout", function(d) { |
|
tooltip.transition() |
|
.duration(500) |
|
.style("opacity", 0) // disappear on mouseout |
|
|
|
}); |
|
}); |
|
|
|
</script> |
|
</body> |
|
</html> |