Create a gist now

Instantly share code, notes, and snippets.

@nategood /README.md
Last active Aug 29, 2015

Florida has better things to do than baseball

Florida has better things to do than baseball

Measuring fan loyalty with MLB attendance and wins

Visualization comparing MLB attendance vs. wins over the past decade. The viz loosely shows the obvious: win more ball games and more people will show up; however upon diving in there are a few interesting anomalies...

  • Cubs fans love misery Regardless of wins, everyone still shows up to see if the goat's curse will ever be lifted in Chicago.
  • The Twins have it backwards They were playing great ball prior to 2010, but having, at best, mediocre attendance. In 2010, attendance jumped significantly. Unfortunately for them, it was also their last winning season. Despite the poor performance, attendance has remained high, presumably due to the new ballbark that opened in 2010. Maybe they should have stuck with the old digs?
  • The Bay loves their Giants, the A's... not so much San Fran appears second from the top in terms of the team loyalty ratio. Their neighbor Oakland on the other hand appears second from the bottom – even with a better ten year win average.
  • Florida has better things to do than baseball Despite playing really solid baseball from '08 to '13, Tampa Bay has the worst overall attendance in baseball for the last decade. They're the only team with an attendance average less than their wins average, a.k.a. their average is in the "fan dead zone". The recent relocation of the Marlins seems to have significantly boosted attendance, but prior to that, the fish had equivalently horrid attendance.

Using the visualization

Hover over individual ball to see season details. Hover over team to see all seasons for team (without details). Hover over "Show Only Averages" to plot teams' ten year averages.

  • X Axis: Attendance (as % of max capacity)
  • Y Axis: Win Percentage

The scores next to the team name are a very simple, unscientific score of "fan loyalty". It is simply a ratio of mean attendance percentage to mean win percentage. It rewards teams that still have strong attendance, regardless of their wins. It especially rewards those that show up when the season is looking bleak*.

The "fan dead zone" encompasses seasons where a team's winning percentage was better than their attendance percentage.

Notes about the data:

  • All info pulled from ESPN
  • Some teams during some seasons reported > 100% attendance
  • The capacity of ballparks can vary quite a bit. For example the Yankees have a 50k+ capacity stadium, whereas Boston has under 40k. You can argue those teams with larger parks are unfairly penalized by this viz.

Team Changes:

  • < 2005 Washington Nationals were the Montreal Expos
  • < 2012 Miami Marlins were the Florida Marlins

* And maybe to a fault. A plain old ratio is not ideal as it probably punishes teams with great records a bit too heavily. May replace this plain old ratio based score with more "fair" metric.

Hacked together by @nategood.

year team attendance win
2004 St. Louis 0.748 0.648
2004 NY Yankees 0.831 0.623
2004 Boston 0.968 0.605
2004 Atlanta 0.587 0.593
2004 LA Dodgers 0.769 0.574
2004 Anaheim 0.925 0.568
2004 Houston 0.931 0.568
2004 Minnesota 0.485 0.565
2004 San Francisco 0.968 0.562
2004 Oakland 0.622 0.562
2004 Chicago Cubs 0.989 0.549
2004 Texas 0.648 0.549
2004 San Diego 0.887 0.537
2004 Philadelphia 0.934 0.531
2004 Miami 0.606 0.512
2004 Chicago Sox 0.611 0.512
2004 Cleveland 0.516 0.497
2004 Baltimore 0.704 0.481
2004 Cincinnati 0.671 0.469
2004 Pittsburgh 0.55 0.447
2004 Detroit 0.597 0.444
2004 NY Mets 0.505 0.438
2004 Tampa Bay 0.366 0.435
2004 Colorado 0.587 0.42
2004 Milwaukee 0.601 0.416
2004 Toronto 0.464 0.416
2004 Washington 0.239 0.414
2004 Seattle 0.76 0.389
2004 Kansas City 0.516 0.358
2004 Arizona 0.634 0.315
2005 St. Louis 0.868 0.617
2005 Chicago Sox 0.712 0.611
2005 Anaheim 0.933 0.586
2005 NY Yankees 0.879 0.586
2005 Boston 0.972 0.586
2005 Cleveland 0.573 0.574
2005 Atlanta 0.629 0.556
2005 Houston 0.846 0.549
2005 Philadelphia 0.766 0.543
2005 Oakland 0.596 0.543
2005 NY Mets 0.616 0.512
2005 Miami 0.63 0.512
2005 Minnesota 0.516 0.512
2005 San Diego 0.834 0.506
2005 Milwaukee 0.644 0.5
2005 Washington 0.745 0.5
2005 Toronto 0.492 0.494
2005 Texas 0.643 0.488
2005 Chicago Cubs 0.98 0.488
2005 Arizona 0.518 0.475
2005 San Francisco 0.946 0.463
2005 Baltimore 0.672 0.457
2005 Cincinnati 0.57 0.451
2005 LA Dodgers 0.794 0.438
2005 Detroit 0.631 0.438
2005 Seattle 0.704 0.426
2005 Colorado 0.474 0.414
2005 Pittsburgh 0.6 0.414
2005 Tampa Bay 0.325 0.414
2005 Kansas City 0.425 0.346
2006 NY Mets 0.755 0.599
2006 NY Yankees 0.912 0.599
2006 Minnesota 0.58 0.593
2006 Detroit 0.799 0.586
2006 Oakland 0.559 0.574
2006 Chicago Sox 0.899 0.556
2006 Anaheim 0.934 0.549
2006 San Diego 0.773 0.543
2006 LA Dodgers 0.829 0.543
2006 Toronto 0.563 0.537
2006 Boston 1 0.531
2006 Philadelphia 0.786 0.525
2006 St. Louis 0.909 0.516
2006 Houston 0.911 0.506
2006 Cincinnati 0.627 0.494
2006 Texas 0.6 0.494
2006 Atlanta 0.636 0.488
2006 Miami 0.396 0.481
2006 Seattle 0.641 0.481
2006 Cleveland 0.568 0.481
2006 San Francisco 0.93 0.472
2006 Colorado 0.515 0.469
2006 Arizona 0.527 0.469
2006 Milwaukee 0.68 0.463
2006 Washington 0.587 0.438
2006 Baltimore 0.552 0.432
2006 Pittsburgh 0.607 0.414
2006 Chicago Cubs 0.949 0.407
2006 Kansas City 0.421 0.383
2006 Tampa Bay 0.387 0.377
2007 Boston 1.014 0.593
2007 Cleveland 0.656 0.593
2007 Anaheim 0.922 0.58
2007 NY Yankees 0.917 0.58
2007 Arizona 0.585 0.556
2007 Colorado 0.574 0.552
2007 Philadelphia 0.882 0.549
2007 San Diego 0.81 0.546
2007 Detroit 0.938 0.543
2007 Seattle 0.691 0.543
2007 NY Mets 0.829 0.543
2007 Chicago Cubs 0.977 0.525
2007 Atlanta 0.677 0.519
2007 Toronto 0.577 0.512
2007 Milwaukee 0.835 0.512
2007 LA Dodgers 0.85 0.506
2007 Minnesota 0.582 0.488
2007 St. Louis 0.936 0.481
2007 Oakland 0.543 0.469
2007 Texas 0.607 0.463
2007 Washington 0.535 0.451
2007 Houston 0.911 0.451
2007 Chicago Sox 0.816 0.444
2007 Cincinnati 0.604 0.444
2007 San Francisco 0.958 0.438
2007 Miami 0.466 0.438
2007 Baltimore 0.562 0.426
2007 Kansas City 0.489 0.426
2007 Pittsburgh 0.577 0.42
2007 Tampa Bay 0.406 0.407
2008 Anaheim 0.914 0.617
2008 Chicago Cubs 0.991 0.602
2008 Tampa Bay 0.528 0.599
2008 Boston 1.04 0.586
2008 Philadelphia 0.971 0.568
2008 Milwaukee 0.893 0.556
2008 NY Yankees 0.923 0.549
2008 NY Mets 0.891 0.549
2008 Chicago Sox 0.76 0.546
2008 Minnesota 0.584 0.54
2008 Houston 0.848 0.534
2008 Toronto 0.586 0.531
2008 St. Louis 0.904 0.531
2008 Miami 0.459 0.522
2008 LA Dodgers 0.822 0.519
2008 Arizona 0.632 0.506
2008 Cleveland 0.625 0.5
2008 Texas 0.495 0.488
2008 Oakland 0.483 0.466
2008 Kansas City 0.49 0.463
2008 Colorado 0.657 0.457
2008 Cincinnati 0.604 0.457
2008 Detroit 0.986 0.457
2008 San Francisco 0.851 0.444
2008 Atlanta 0.624 0.444
2008 Baltimore 0.519 0.422
2008 Pittsburgh 0.524 0.414
2008 San Diego 0.705 0.389
2008 Seattle 0.602 0.377
2008 Washington 0.692 0.366
2009 NY Yankees 0.867 0.636
2009 Anaheim 0.888 0.599
2009 LA Dodgers 0.829 0.586
2009 Boston 1.015 0.586
2009 Philadelphia 1.022 0.574
2009 Colorado 0.652 0.568
2009 St. Louis 0.881 0.562
2009 San Francisco 0.85 0.543
2009 Texas 0.563 0.537
2009 Miami 0.517 0.537
2009 Minnesota 0.605 0.534
2009 Atlanta 0.585 0.531
2009 Detroit 0.79 0.528
2009 Seattle 0.568 0.525
2009 Tampa Bay 0.529 0.519
2009 Chicago Cubs 0.963 0.516
2009 Milwaukee 0.884 0.494
2009 Chicago Sox 0.694 0.488
2009 Cincinnati 0.513 0.481
2009 Toronto 0.459 0.463
2009 Oakland 0.398 0.463
2009 San Diego 0.558 0.463
2009 Houston 0.76 0.457
2009 Arizona 0.536 0.432
2009 NY Mets 0.927 0.432
2009 Cleveland 0.518 0.401
2009 Kansas City 0.589 0.401
2009 Baltimore 0.489 0.395
2009 Pittsburgh 0.508 0.385
2009 Washington 0.542 0.364
2010 Philadelphia 1.035 0.599
2010 Tampa Bay 0.52 0.593
2010 NY Yankees 0.889 0.586
2010 Minnesota 1.007 0.58
2010 San Francisco 0.903 0.568
2010 Cincinnati 0.605 0.562
2010 Atlanta 0.619 0.562
2010 Texas 0.63 0.556
2010 San Diego 0.619 0.556
2010 Boston 1.009 0.549
2010 Chicago Sox 0.667 0.543
2010 St. Louis 0.87 0.531
2010 Toronto 0.399 0.525
2010 Colorado 0.712 0.512
2010 Oakland 0.401 0.5
2010 Detroit 0.757 0.5
2010 Miami 0.542 0.494
2010 LA Dodgers 0.785 0.494
2010 Anaheim 0.891 0.494
2010 NY Mets 0.771 0.488
2010 Milwaukee 0.808 0.475
2010 Houston 0.703 0.469
2010 Chicago Cubs 0.92 0.463
2010 Cleveland 0.402 0.426
2010 Washington 0.539 0.426
2010 Kansas City 0.529 0.414
2010 Baltimore 0.45 0.407
2010 Arizona 0.518 0.401
2010 Seattle 0.539 0.377
2010 Pittsburgh 0.519 0.352
2011 Philadelphia 1.041 0.63
2011 NY Yankees 0.897 0.599
2011 Milwaukee 0.905 0.593
2011 Texas 0.74 0.593
2011 Detroit 0.791 0.586
2011 Arizona 0.534 0.58
2011 Tampa Bay 0.554 0.562
2011 St. Louis 0.869 0.556
2011 Boston 1.017 0.556
2011 Atlanta 0.604 0.549
2011 Anaheim 0.861 0.531
2011 San Francisco 0.998 0.531
2011 LA Dodgers 0.647 0.509
2011 Toronto 0.456 0.5
2011 Washington 0.599 0.497
2011 Cleveland 0.523 0.494
2011 Chicago Sox 0.608 0.488
2011 Cincinnati 0.646 0.488
2011 NY Mets 0.72 0.475
2011 Oakland 0.52 0.457
2011 Colorado 0.711 0.451
2011 Miami 0.488 0.444
2011 Pittsburgh 0.632 0.444
2011 Kansas City 0.562 0.438
2011 Chicago Cubs 0.905 0.438
2011 San Diego 0.62 0.438
2011 Baltimore 0.483 0.426
2011 Seattle 0.489 0.414
2011 Minnesota 0.99 0.389
2011 Houston 0.623 0.346
2012 Washington 0.723 0.605
2012 Cincinnati 0.685 0.599
2012 NY Yankees 0.87 0.586
2012 Oakland 0.606 0.58
2012 San Francisco 0.995 0.58
2012 Atlanta 0.601 0.58
2012 Texas 0.869 0.574
2012 Baltimore 0.586 0.574
2012 Tampa Bay 0.565 0.556
2012 Anaheim 0.833 0.549
2012 Detroit 0.906 0.543
2012 St. Louis 0.916 0.543
2012 LA Dodgers 0.733 0.531
2012 Chicago Sox 0.598 0.525
2012 Milwaukee 0.834 0.512
2012 Philadelphia 1.008 0.5
2012 Arizona 0.553 0.5
2012 Pittsburgh 0.682 0.488
2012 San Diego 0.614 0.469
2012 Seattle 0.444 0.463
2012 NY Mets 0.671 0.457
2012 Toronto 0.526 0.451
2012 Kansas City 0.574 0.444
2012 Boston 1.014 0.426
2012 Miami 0.732 0.426
2012 Cleveland 0.456 0.42
2012 Minnesota 0.868 0.407
2012 Colorado 0.643 0.395
2012 Chicago Cubs 0.865 0.377
2012 Houston 0.485 0.34
2013 St. Louis 0.946 0.599
2013 Boston 0.944 0.599
2013 Atlanta 0.633 0.593
2013 Oakland 0.637 0.593
2013 Pittsburgh 0.735 0.58
2013 Detroit 0.923 0.574
2013 LA Dodgers 0.825 0.568
2013 Cleveland 0.453 0.568
2013 Tampa Bay 0.547 0.564
2013 Texas 0.788 0.558
2013 Cincinnati 0.739 0.556
2013 Washington 0.789 0.531
2013 Kansas City 0.57 0.531
2013 NY Yankees 0.805 0.525
2013 Baltimore 0.641 0.525
2013 Arizona 0.542 0.5
2013 Anaheim 0.821 0.481
2013 San Francisco 0.992 0.469
2013 San Diego 0.627 0.469
2013 Colorado 0.683 0.457
2013 Milwaukee 0.746 0.457
2013 Toronto 0.636 0.457
2013 NY Mets 0.639 0.457
2013 Philadelphia 0.852 0.451
2013 Seattle 0.454 0.438
2013 Minnesota 0.774 0.407
2013 Chicago Cubs 0.793 0.407
2013 Chicago Sox 0.544 0.389
2013 Miami 0.523 0.383
2013 Houston 0.498 0.315
// https://github.com/arc90/teamcolors
var colors = {
"Arizona": ["#A71930", "#000000", "#DBCEAC", "#FFFFFF"],
"Atlanta": ["#002F5F", "#B71234", "#FFFFFF"],
"Baltimore": ["#ed4c09", "#000000", "#FFFFFF"],
"Boston": ["#C60C30", "#002244", "#FFFFFF"],
"Chicago Cubs": ["#003279", "#CC0033", "#FFFFFF"],
"Chicago Sox": ["#C0C0C0", "#000000", "#FFFFFF"],
"Cincinnati": ["#C6011F", "#FFFFFF", "#000000"],
"Colorado": ["#333366", "#000000", "#C0C0C0", "#FFFFFF"],
"Cleveland": ["#003366", "#d30335", "#FFFFFF"],
"Detroit": ["#001742", "#FFFFFF", "#DE4406"],
"Houston": ["#072854", "#FF7F00", "#FFFFFF"],
"Kansas City": ["#15317E", "#74B4FA", "#FFFFFF"],
"Anaheim": ["#B71234", "#002244", "#FFFFFF"],
"LA Dodgers": ["#083C6B", "#FFFFFF"],
"Miami": ["#F9423A", "#000000", "#8A8D8F", "#0077C8", "#FFD100", "#FFFFFF"],
"Milwaukee": ["#182B49", "#92754C", "#FFFFFF"],
"Minnesota": ["#072754", "#C6011F", "#FFFFFF"],
"NY Mets": ["#002C77", "#FB4F14", "#FFFFFF"],
"NY Yankees": ["#1C2841", "#FFFFFF", "#808080"],
"Oakland": ["#003831", "#FFD800", "#FFFFFF"],
"Philadelphia": ["#BA0C2F", "#FFFFFF", "#003087"],
"Pittsburgh": ["#fdb829", "#000000", "#FFFFFF"],
"San Diego": ["#002147", "#FFFFFF", "#B4A76C"],
"San Francisco": ["#F2552C", "#000000", "#FFFDD0"],
"Seattle": ["#0C2C56", "#005C5C", "C0C0C0", "#FFFFFF"],
"St. Louis": ["#c41e3a", "#0A2252", "#FFFFFF"],
"Tampa Bay": ["#00285D", "#9ECEEE", "#FFFFFF", "#ffd700"],
"Texas": ["#BD1021", "#FFFFFF", "#003279"],
"Toronto": ["#003DA5", "#041E42", "#FFFFFF", "#DA291C"],
"Washington": ["#BA122B", "#11225B", "#FFFFFF" ]
};
<!DOCTYPE html>
<html>
<head>
<title>Determining Baseball Fan Loyalty: MLB Attendance vs. Wins</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="colors.js"></script>
<style type="text/css">
html, body {
font: 12px Helvetica;
margin: 0; padding: 0;
}
circle {
fill: #000;
stroke-width: 0;
fill-opacity: 0.5;
}
circle:hover, circle.highlight {
fill-opacity: 1;
stroke-width: 2;
stroke-opacity: 1;
}
circle.hide {
fill-opacity: 0.1;
}
#tooltip {
background: #111;
color: #fff;
padding: 5px;
text-align: right;
}
#tooltip span {
font: 11px Helvetica;
color: #ddd;
}
text {
font-size: 10px;
text-transform: uppercase;
}
text.team {
text-transform: uppercase;
fill: #ccc;
cursor: pointer;
}
text.teamlowlight {
fill: #666 !important;
}
text.team:hover {
fill: #ccc;
cursor: pointer;
font-weight: bold;
}
rect.avg {
fill: black;
stroke-width: 2;
}
path.range {
fill: none;
stroke: #333;
stroke-width: 3;
stroke-opacity: 0.2;
}
div.toggle {
cursor: pointer;
color: #999;
background: #ddd;
padding: 5px;
position: absolute;
font-size: 10px;
text-transform: uppercase;
}
div.toggle:hover {
background: #666;
color: #fff;
}
path.shame {
fill: #ddd;
stroke: none;
}
path.guidelines {
stroke: #ccc;
stroke-width: 1;
/*fill-opacity*/
}
</style>
</head>
<body>
<svg id="svg"></svg>
<script type="text/javascript">
var ttw = 125;
var tooltip = d3.select("body")
.append("div")
.attr("id", "tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
var slug = function (str) { return str.replace(/[^a-z]/ig, '_'); };
var draw = function(errors, years) {
var h = 500, w = 960;
var gh = 420, gw = 760;
var pad = (h - gh)/2;
var wdiff = w - gw;
var hdiff = h - gh;
var r = 6;
var maxAtt = d3.max(years, function(d) { return d.attendance; });
var maxWins = d3.max(years, function(d) { return d.win; });
var minAtt = d3.min(years, function(d) { return d.attendance; });
var minWins = d3.min(years, function(d) { return d.win; });
var round = function(x) { return Math.round(x * 1000) / 1000; };
// todo normalize attendance and wins for these "scores"
var aggregates = d3.nest()
.key(function(d, i) { return d.team; })
.rollup(function(d, i) {
var result = {
attendance: d3.mean(d, function(d2){ return parseFloat(d2.attendance); }),
attendanceMin: d3.min(d, function(d2){ return parseFloat(d2.attendance); }),
attendanceMax: d3.max(d, function(d2){ return parseFloat(d2.attendance); }),
win: d3.mean(d, function(d2){ return parseFloat(d2.win); }),
winMin: d3.min(d, function(d2){ return parseFloat(d2.win); }),
winMax: d3.max(d, function(d2){ return parseFloat(d2.win); })
};
result.score = round(result.attendance / result.win);
return result;
})
.entries(years);
var teams = aggregates;
teams.sort(function(a, b) { return d3.descending(a.values.score, b.values.score)});
var ascale = d3.scale.linear().domain([minAtt, maxAtt]).range([2 * r, gw - pad - 2 * r]);
var wscale = d3.scale.linear().domain([minWins, maxWins]).range([gh - 2 * r, 2 * r]);
var tscale = d3.scale.linear().domain([0, teams.length]).range([pad, gh + pad]);
var svg = d3.select("#svg")
.attr("width", w)
.attr("height", h)
.style("background", "#eee");
var g = svg.append("g")
.attr("transform", "translate(" + (w - gw) + " " + pad + ")");
var line = d3.svg.line();
// Background
svg.append("rect").attr("fill", "#333").attr("width", w - gw - pad).attr("height", h);
// The shame zone + guidelines
g.append("path").classed("shame", true)
.attr("d", function () {
return line([
[ascale(minAtt) - r, wscale(maxWins) - r],
[ascale(minAtt) - r, wscale(minWins) + r],
[ascale(minWins), wscale(minWins) + r],
[ascale(maxWins), wscale(maxWins) - r],
[ascale(minAtt) - r, wscale(maxWins) - r]
]);
});
g.append("text").style("fill", "#999").text("Fan Dead Zone").attr("x", 50).attr("y", 50);
// 0.500
g.append("path").style("stroke", "#ccc").attr("d", function() { return line([[ascale(minAtt), wscale(0.5)],[ascale(maxAtt), wscale(0.5)]]); })
g.append("text").style("fill", "#999").text("0.500").attr("y", wscale(0.5) - 5).attr("x", ascale(maxAtt)).style("text-anchor","end");
// Axis
g.append("text")
.attr("transform", "translate(0 " + (gh / 2) + ") rotate (-90)")
.style("text-anchor", "middle")
.text("Wins");
g.append("text")
.style("text-anchor", "start").style("fill", "#999")
.attr("transform", "translate(0 " + wscale(minWins) + ") rotate (-90)")
.text(minWins);
g.append("text")
.style("text-anchor", "end").style("fill", "#999")
.attr("transform", "translate(0 " + wscale(maxWins) + ") rotate (-90)")
.text(maxWins);
g.append("text")
.attr("transform", "translate(" + (gw / 2) + " " + (gh+10) + ")")
.style("text-anchor", "middle")
.text("Attendance");
g.append("text")
.style("text-anchor", "start").style("fill", "#999")
.attr("transform", "translate(" + ascale(minAtt) + " " + (gh+10) + ")")
.text(minAtt);
g.append("text")
.style("text-anchor", "end").style("fill", "#999")
.attr("transform", "translate(" + ascale(maxAtt) + " " + (gh+10) + ")")
.text(maxAtt);
// Show Average Toggle
d3.select("body")
.append("div")
.attr("class", "toggle")
.text("Show Only Averages")
.style("left", w - 170 + "px")
.style("top", pad/2 + "px")
.on("mouseover", function(d) {
toggleMode("aggregate");
})
.on("mouseout", function(d) {
toggleMode("yearly");
})
;
// Team Side Bar
svg
.append("text")
.style("fill", "#fff")
.text("Team • Score")
.attr("transform", "translate(" + pad/2 + " " + tscale(0) + ")");
svg.selectAll("text.team")
.data(teams)
.enter()
.append("text")
.attr("class", function(d) { return slug(d.key) + " team"; })
.text(function(d) { return d.key + "" + (d.values.score); })
.attr("transform", function(d, i) { return "translate(" + (pad/2) + " " + tscale(i+1) + ")"; })
.on("mouseover", function(d) {highlight(d.key);})
.on("mouseout", unhighlight)
;
// Team Balls
g.selectAll("g.team")
.data(years)
.enter()
.append("g")
.attr("class", "team")
.attr("transform", function (d) { return "translate(" + ascale(d.attendance) + " " + wscale(d.win) + ")"; })
.on("mouseover", function(d) {
tooltip.style("visibility", "visible");
tooltip.html(d.year + " " + d.team + "<br /><span>Win: " + d.win + "</span><br /><span>Att: " + d.attendance + "</span>");
highlight(d.team);
})
.on("mousemove", function(d) { tooltip.style("top", (event.pageY - 10)+"px").style("left",(event.pageX - 30 - parseInt(tooltip.style("width"), 10)) + "px");})
.on("mouseout", function(d) {
tooltip.style("visibility", "hidden");
unhighlight();
})
.append("circle")
.style("fill", function(d) { return colors[d.team][0]; })
.style("stroke", function(d) { return colors[d.team][1]; })
.attr("class", function(d) { return slug(d.team) + " " + d.year; })
.attr("id", function(d) { return d.team + ":" + d.year; })
.attr("title", function(d) { return d.team + ": " + d.year; })
.attr("r", 0.01)
.transition()
.delay(function(d, i) { return (d.year - 2004) * 300 + 100; })
.duration(300)
.attr("r", r)
;
// Averages
var rw = 12;
var avgs = g.selectAll("g.avg")
.data(aggregates)
.enter()
.append("g")
.attr("class", function(d) { return "avg " + slug(d.key); })
.style("visibility", "hidden")
.attr("transform", function (d) { return "translate(" + (ascale(d.values.attendance) - rw/2) + " " + (wscale(d.values.win) - rw/2) + ")"; })
;
avgs
.append("path")
.attr("class", "range")
.style("stroke", function(d) { return colors[d.key][0]; })
.attr("d", function(d, i) {
return line([
[ascale(d.values.attendanceMin) - ascale(d.values.attendance) + rw/2, rw / 2],
[ascale(d.values.attendanceMax) - ascale(d.values.attendance) + rw/2, rw / 2]
]);
})
;
avgs
.append("rect")
.attr("class", "avg")
.style("fill", function(d) { return colors[d.key][0]; })
.style("stroke", function(d) { return colors[d.key][1]; })
.attr("width", rw)
.attr("height", rw)
;
avgs
.append("text")
.text(function(d) { return d.key; /*+ " " + round(d.values.attendance) + " / " + round(d.values.win);*/ })
.attr("transform", function(d) {
return "translate(" + rw*1.5 + " " + (rw/2-rw/6+5) + ")";
})
.attr("class", "avg")
;
};
var highlight = function(team) {
var team = slug(team);
d3.selectAll("circle").classed("hide", true);
d3.selectAll("circle." + team).classed("highlight", true).classed("hide", false);
d3.selectAll("text.team").classed("teamlowlight", true);
d3.selectAll("text." + team).classed("teamlowlight", false);
d3.selectAll("g." + team).style("visibility", "visible");
};
var unhighlight = function() {
d3.selectAll("text.team").classed("teamlowlight", false)
d3.selectAll("circle").classed("hide", false).classed("highlight", false);
d3.selectAll("g.avg").style("visibility", "hidden");
};
var toggleMode = function(mode) {
if (mode === "yearly") {
d3.selectAll("g.team").style("visibility", "visible");
d3.selectAll("g.avg").style("visibility", "hidden");
} else if (mode === "aggregate") {
d3.selectAll("g.team").style("visibility", "hidden");
d3.selectAll("g.avg").style("visibility", "visible");
}
};
d3.csv("attendance-vs-wins-by-year.csv").get(draw);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment