New Year's Resolution for 2017: Make a D3 Block a day to teach myself D3. This is Number 14. This example builds a basic scatter-plot using baseball data scraped from the web of wins by Major League Baseball Teams. This example will be extended over the next several days to help fully explore the data. This examples copies and extends Michele Weigle's excellent D3 Scatterplot Example.
xxxxxxxxxx
<meta charset="utf-8">
<head>
<title>D3 Block-a-Day: Day 14, January 14, 2017</title>
</head>
<!-- Example based on Michele Weigle's D3 Scatterplot Example https://bl.ocks.org/weiglemc/6185069 -->
<style>
body {
font: 16pt Helvectical Neue;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: black;
stroke-width: 2px;
fill: #ffe0e0;
}
.tooltip {
background-color: #fff8dc;
padding: 7px;
text-shadow: #f5f5f5 0 1px 0;
font: 13px Helvetica Neue;
border: 2px solid;
border-color: black;
border-radius: 5px;
position: absolute;
box-shadow: rgba(0, 0, 0, 0.3) 0 2px 10px;
}
.xaxis {
font: 14px Helvetica Neue;
}
.yaxis {
font: 14px Helvetica Neue;
}
</style>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 50, left: 70},
width = 960 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
/*
* 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
* axis - sets up axis
*/
// setup x
var xValue = function(d) { return d["YEAR_2015"];}, // data -> value
xScale = d3.scaleLinear().range([0, width]), // value -> display
xMap = function(d) { return xScale(xValue(d));}, // data -> display
xAxis = d3.axisBottom(xScale);
// setup y
var yValue = function(d) { return d["YEAR_2016"];}, // data -> value
yScale = d3.scaleLinear().range([height, 0]), // value -> display
yMap = function(d) { return yScale(yValue(d));}, // data -> display
yAxis = d3.axisLeft(yScale);
// add the graph canvas to the body of the webpage
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 + ")");
// add the tooltip area to the webpage
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// load data
d3.csv("baseball_team_wins.csv", function(error, data) {
// change string (from CSV) into number format
data.forEach(function(d) {
d['YEAR_2015'] = +d['YEAR_2015'];
d['YEAR_2016'] = +d['YEAR_2016'];
});
// don't want dots overlapping axis, so add in buffer to data domain
xScale.domain([40, 120]);
yScale.domain([40, 120]);
// x-axis
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("text")
.attr("transform",
"translate(" + (width*0.1) + " ," +
(height + margin.top + 30) + ")")
.style("text-anchor", "left")
.style("font-family", "Helvetica Neue")
.text("Wins 2015");
// y-axis
svg.append("g")
.attr("class", "yaxis")
.call(yAxis);
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 10 - margin.left)
.attr("x", - 0.75*height)
.attr("dy", ".71em")
.style("text-anchor", "middle")
.style("font-family", "Helvetica Neue")
.text("Wins 2016");
// draw dots
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 10)
.attr("cx", xMap)
.attr("cy", yMap)
.on("mouseover", function(d) {
tooltip.transition()
.duration(150)
.style("opacity", .9);
tooltip.html("<b>" + d["TEAM"] + "</b>" + "<br/> 2015: " + xValue(d)
+ " Wins, 2016: " + yValue(d) + " Wins")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(300)
.style("opacity", 0);
});
});
</script>
</body>
https://d3js.org/d3.v4.min.js