Built with blockbuilder.org
Last active
August 24, 2019 14:37
-
-
Save mforando/d3c72b1ccde46bc630bb5987ae38e4f2 to your computer and use it in GitHub Desktop.
Fantasy Info
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<meta property="og:title" content="2019 Fantasy Football Information"> | |
<meta property="og:description" content="Keeper Costs, Rules, and Draft Time Info"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { | |
font-family:Helvetica; | |
margin:0; | |
top:0;right:0;bottom:0;left:0; | |
background:rgb(30,30,30); | |
font-size:.85rem; | |
} | |
h1{ | |
padding-bottom:.5rem; | |
border-bottom:1px solid rgba(0,0,0,.7); | |
} | |
p{ | |
} | |
#main{ | |
max-width:1000px; | |
min-height:100vh; | |
margin:1rem auto; | |
padding:1rem; | |
padding-top:1rem; | |
outline:1px solid black; | |
-webkit-box-shadow: 0 0 20px 3px rgba(255,255,255,0.54); | |
-moz-box-shadow: 0 0 20px 3px rgba(255,255,255,0.55); | |
box-shadow: 0 0 20px 3px rgba(255,255,255,0.55); | |
background:rgba(245,245,245); | |
} | |
table | |
{ | |
font-family:Helvetica; | |
font-size:1rem; | |
border-collapse: collapse; | |
width:100%; | |
margin:0 auto; | |
} | |
table th | |
{ | |
border-bottom: 1px solid rgb(0,40,80); | |
border-right: none; | |
border-left: none; | |
padding: 4px; | |
text-align: left; | |
background-color: none; | |
color: black; | |
} | |
table td | |
{ | |
border-bottom: 1px solid #ddd; | |
padding: 4px; | |
padding-top: 4px; | |
padding-bottom: 4px; | |
} | |
table tr:nth-child(even) | |
{ | |
background-color: #f2f2f2; | |
} | |
#trophy1{ | |
color: transparent; | |
text-shadow: 0 0 0 gold; | |
font-size:5rem; | |
width:5rem; | |
text-align:center; | |
display:inline-block; | |
vertical-align: middle; | |
} | |
#trophy2{ | |
color: transparent; | |
text-shadow: 0 0 0 orange; | |
font-size:3rem; | |
height:4rem; | |
width:5rem; | |
text-align:center; | |
display:inline-block; | |
vertical-align: middle; | |
} | |
#trophy3{ | |
color: transparent; | |
text-shadow: 0 0 0 brown; | |
font-size:2rem; | |
height:4rem; | |
width:5rem; | |
text-align:center; | |
vertical-align: middle; | |
display:inline-block; | |
} | |
} | |
.tropycont{ | |
vertical-align: middle; | |
display:block; | |
width:100%; | |
} | |
.trophyLabel{ | |
vertical-align: middle; | |
display:inline-block; | |
} | |
.wrapper { | |
position: relative; | |
} | |
[class|="confetti"] { | |
position: absolute; | |
} | |
.red { | |
background-color: #E94A3F; | |
} | |
.yellow { | |
background-color: #FAA040; | |
} | |
.blue { | |
background-color: #5FC9F5; | |
} | |
#teamselect{ | |
margin-left:15px; | |
} | |
#chart{ | |
width: 800px; | |
margin: 0 auto; | |
} | |
.background { | |
fill: #eee; | |
} | |
line { | |
stroke: #fff; | |
} | |
text.active { | |
fill: red; | |
} | |
.day { | |
fill: black; | |
stroke: black; | |
} | |
.month { | |
fill: none; | |
stroke: #fff; | |
stroke-width: 4px; | |
} | |
.year-title { | |
font-size: 1.5em; | |
} | |
/* color ranges */ | |
.RdYlGn .q0-11{fill:rgb(165,0,38)} | |
.RdYlGn .q1-11{fill:rgb(215,48,39)} | |
.RdYlGn .q2-11{fill:rgb(244,109,67)} | |
.RdYlGn .q3-11{fill:rgb(253,174,97)} | |
.RdYlGn .q4-11{fill:rgb(254,224,139)} | |
.RdYlGn .q5-11{fill:rgb(255,255,191)} | |
.RdYlGn .q6-11{fill:rgb(217,239,139)} | |
.RdYlGn .q7-11{fill:rgb(166,217,106)} | |
.RdYlGn .q8-11{fill:rgb(102,189,99)} | |
.RdYlGn .q9-11{fill:rgb(26,152,80)} | |
.RdYlGn .q10-11{fill:rgb(0,104,55)} | |
.keeper{ | |
border:2px solid rgb(100,0,0); | |
background:rgb(200,0,0); | |
color:white; | |
z-index:9999999; | |
background-color: rgb(200,0,0)!important; | |
} | |
</style> | |
</head> | |
<div id="main"> | |
<h1 style="text-align:center;">2019 Fantasy Football</h1> | |
<h2>2018 League Winners</h2> | |
<div class="wrapper"> | |
<div class="tropycont" id="firstplace"><span id="trophy1">🏆</span><span style="font-size:2rem" class="trophyLabel">1st Place: Ridley Me This</span></div> | |
<div class="tropycont" id="secondplace"><span id="trophy2">🏆</span><span style="font-size:1.5rem" class="trophyLabel">2nd Place: Gurley County</span></div> | |
<div class="tropycont" id="thirdplace"><span id="trophy3">🏆</span><span style="font-size:1rem" class="trophyLabel">3rd Place: Wentzylvania</span></div> | |
<br> | |
</div> | |
<p>Go to League Homepage: <a target="_blank" href="https://football.fantasysports.yahoo.com/f1/25991">https://football.fantasysports.yahoo.com/f1/25991</a></p> | |
<div id="lastyearsstandings"> | |
</div> | |
<div id="keeperrules"> | |
<h3>Keeper Rules:</h3> | |
<ul> | |
<li>Each team must keep 3 players</li> | |
<li>Lose the draft pick for the round you picked the player last year</li> | |
<li>Waiver wire pickups = lose last pick of the draft (No Penalty)</li> | |
<li>Keeper deadline = 1 week prior to live draft (Update - please send ASAP even though its prior to 1 week to the draft)</li> | |
<li>Draft pick trade deadline = 1 hr prior to live draft</li> | |
</ul> | |
</div> | |
<div id="draftdates"> | |
<h3>Draft Date:</h> | |
<div><a target="_blank" href="https://doodle.com/poll/g3w7a6p2dzm256t6">Vote on a Draft Date</a> | |
</div> | |
<br> | |
<div> | |
<span>Select A Team:</span> | |
<select id="teamselect"> | |
</select> | |
</div> | |
<br> | |
<h3>Keeper Cost Calculation</h3> | |
<p>Keeper costs are based on the draft round the player was drafted on in the prior year as well as the current ADP for a PRR, 14-team league on <a target="_blank" href="https://fantasyfootballcalculator.com/adp/ppr/14-team/all">Fantasy Football Calculator</a>. The calculations shown below are based on ADP data from 8-2-2019 and will be adjusted before the draft. Click the link to Fantasy Football Calculator to view the latest ADP data.</p> | |
<div id="keeperSelection"> | |
</div> | |
<br> | |
<p>To select your keepers, <a id="googlesheetsLink" href="https://docs.google.com/spreadsheets/d/1anYR_XncubB6XvXNs7bwjfRH5xwuOm-xgzhsOna86-4/edit#gid=434476128" target="_blank">click this this link</a>. The keeper pool and information on this page will update shortly.</p> | |
<br> | |
<div id="finalRostersContainer"> | |
</div> | |
<br> | |
<h3>ADP vs Current Keepers</h3> | |
<p>Players in bold red shown below have been selected to be kept.</p> | |
<div id="adpkeepers"> | |
</div> | |
</div> | |
<script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script> | |
<body> | |
<script> | |
function tabulate() { | |
//configure the table function for desired columns. | |
table.columns = function(value) { | |
//default in case a specification is not provided. | |
if (!arguments.length) return null; | |
columns = value; | |
//return the charting function with the new specifications. | |
return table; | |
}; | |
table.showHeaders = function(value){ | |
//if not specified, show headers by default | |
if (!arguments.length) return true; | |
showHeaders = value; | |
//return the charting function with the new specifications. | |
return table; | |
} | |
//this is the configurable charting function | |
function table(selection){ | |
var columns = table.columns; | |
if(table.columns == null){ | |
columns = Object.keys(selection.data()[0].values[0]) | |
} | |
var tablecont = selection.append('table') | |
if(table.showHeaders){ | |
var thead = tablecont.append('thead') | |
} | |
var tbody = tablecont.append('tbody'); | |
var data = selection.data(); | |
console.log(data) | |
var headers = selection.select("thead") | |
.append('tr') | |
.selectAll('th') | |
.data(columns) | |
headers.enter() | |
.append('th') | |
.merge(headers) | |
.text(function (column) {return column;}); | |
var rows = tbody.selectAll('tr') | |
.data(function(d){return d.values}) | |
.enter() | |
.append('tr'); | |
var cells = rows.selectAll('td') | |
.data(function (row) { | |
return columns.map(function (column,i) { | |
return {column: column, value: row[column]}; | |
}); | |
}) | |
.enter() | |
.append('td') | |
.text(function (d) { return d.value; }); | |
} | |
//return the configured table function. | |
return table; | |
} | |
var public_spreadsheet_url = 'https://docs.google.com/spreadsheets/d/1anYR_XncubB6XvXNs7bwjfRH5xwuOm-xgzhsOna86-4/edit?usp=sharing'; | |
function renderSpreadsheetData() { | |
Tabletop.init( { key: public_spreadsheet_url, | |
callback: draw, | |
simpleSheet: false } ) | |
} | |
function draw(data, tabletop) { | |
// draw chart | |
//parse results | |
data.DraftOrder.elements.forEach(function(d){ | |
d.Moves = +d.Moves; | |
d.Pick = +d.Pick; | |
d.PtsFor = +d.PtsFor; | |
}) | |
console.log(data.adp.elements) | |
//adp | |
//parse results | |
data.adp.elements.forEach(function(d){ | |
d.Overall = +d.Overall; | |
}) | |
//DraftOrder | |
updateDraftOrder(data.DraftOrder.elements.sort(function(a,b){return d3.ascending(a.Pick,b.Pick)})) | |
//parse results | |
data.PickData.elements.forEach(function(d){ | |
d.DraftPick = +d.DraftPick; | |
d.DraftRound = +d.DraftRound; | |
d.TeamPick = +d.TeamPick; | |
}) | |
var nested = d3.nest().key(function(d){return d.Team}).entries(data.PickData.elements) | |
var teamnames = nested.map(function(d){return d.key}) | |
var options = d3.select("#teamselect").selectAll("option").data(teamnames) | |
options.enter() | |
.append("option") | |
.attr("value",function(d){return d}) | |
.text(function(d){return d}) | |
d3.select("#teamselect").on("change",function(){ | |
var selected = d3.select(this).property("value") | |
updatePickTable(nested.filter(function(d){return d.key == selected})[0]) | |
updateKeepersTable(rosternest.filter(function(d){return d.key == selected})[0]) | |
updateLink(data.DraftOrder.elements.filter(function(d){return d.Team == selected})[0]) | |
}) | |
data.finalrosters.elements.forEach(function(d){ | |
d.DraftRound = +d.DraftRound; | |
d.ADPRound = +d.ADPRound; | |
d.FinalCost = +d.FinalCost; | |
d.Adjustment = +d.Adjustment; | |
d.CurrentADP = +d.CurrentADP; | |
if(d.CurrentADP == 0){ | |
d.CurrentADP = null | |
} | |
d.KeeperCost = +d.KeeperCost; | |
}) | |
var rosternest = d3.nest().key(function(d){return d.Team}).entries(data.finalrosters.elements) | |
updatePickTable(nested[0]) | |
updateKeepersTable(rosternest[0]) | |
updateADP(data.adp.elements) | |
updateLink(data.DraftOrder.elements[0]) | |
} | |
function updateLink(draftorder){ | |
d3.select("#googlesheetsLink") | |
.attr("href","https://docs.google.com/spreadsheets/d/1anYR_XncubB6XvXNs7bwjfRH5xwuOm-xgzhsOna86-4/edit#gid=" + draftorder.GoogleID) | |
} | |
function updateADP(draftorder){ | |
var draftOrderTable = tabulate(); | |
draftOrderTable.columns = ["ADP","Overall","Name","Position","Team"]; | |
draftOrderTable.showHeaders = true; | |
var nest = d3.nest().key(function(d){return "ADP & Keeper Status"}).entries(draftorder)[0] | |
var containers = d3.select("#adpkeepers").selectAll(".containers").data([nest],function(d){return d.key}) | |
containers.enter() | |
.append("div") | |
.attr("class","containers") | |
.merge(containers) | |
.call(draftOrderTable) | |
containers.exit().remove(); | |
d3.select("#adpkeepers").selectAll(".containers").selectAll("tr").classed("keeper",function(d){ | |
if(d.KeeperFlag=="True"){ | |
return true | |
} | |
}) | |
} | |
function updateDraftOrder(draftorder){ | |
var draftOrderTable = tabulate(); | |
draftOrderTable.columns = ["Pick","Rank","Team","WLT","PtsAgainst","PtsFor","Moves"]; | |
draftOrderTable.showHeaders = true; | |
var nest = d3.nest().key(function(d){return "2019 Draft Order"}).entries(draftorder)[0] | |
var containers = d3.select("#lastyearsstandings").selectAll(".containers").data([nest],function(d){return d.key}) | |
containers.enter() | |
.append("div") | |
.attr("class","containers") | |
.merge(containers) | |
.html(function(d){return "<h2>" + d.key + "</h2>"}) | |
.call(draftOrderTable) | |
containers.exit().remove(); | |
} | |
function updatePickTable(teamdata){ | |
teamdata.values = teamdata.values.sort(function(a,b){return d3.ascending(a.FinalCost,b.FinalCost)}) | |
var teamPickTable = tabulate(); | |
teamPickTable.columns = ["DraftRound","DraftPick","Keeper","Notes"]; | |
teamPickTable.showHeaders = true; | |
var containers = d3.select("#finalRostersContainer").selectAll(".containers").data([teamdata],function(d){return d.key}) | |
containers.enter() | |
.append("div") | |
.attr("class","containers") | |
.merge(containers) | |
// .html(function(d){return "<h2>" + d.key + "</h2>"}) | |
.call(teamPickTable) | |
containers.exit().remove(); | |
} | |
function updateKeepersTable(teamdata){ | |
var teamKeeperTable = tabulate(); | |
teamKeeperTable.columns = ["Player","DraftRound","KeeperCost","CurrentADP","ADPRound","Adjustment","FinalCost"]; | |
teamKeeperTable.showHeaders = true; | |
var containers = d3.select("#keeperSelection").selectAll(".containers").data([teamdata],function(d){ | |
console.log(d) | |
return d.key}) | |
containers.enter() | |
.append("div") | |
.attr("class","containers") | |
.merge(containers) | |
// .html(function(d){return "<h2>" + d.key + "</h2>"}) | |
.call(teamKeeperTable) | |
containers.exit().remove(); | |
} | |
renderSpreadsheetData(); | |
for (var i = 0; i < 200; i++) { | |
create(i); | |
} | |
function create(i) { | |
var width = Math.random() * 8; | |
var height = width * 0.4; | |
var colourIdx = Math.ceil(Math.random() * 3); | |
var colour = "red"; | |
switch(colourIdx) { | |
case 1: | |
colour = "yellow"; | |
break; | |
case 2: | |
colour = "blue"; | |
break; | |
default: | |
colour = "red"; | |
} | |
d3.select(".wrapper") | |
.append("div") | |
.attr("class",function(d){return "confetti-" + i + " " + colour}) | |
.style("width",width + "px") | |
.style("height",height + "px") | |
.style("top",Math.random()*100+"%") | |
.style("left",Math.random()*100+"%") | |
.style("opacity",Math.random()+0.5) | |
.style("transform","rotate(" + Math.random()*360 + "deg") | |
drop(i); | |
} | |
function drop(x) { | |
d3.selectAll('.confetti-'+x) | |
.transition() | |
.delay(function(d){ | |
return Math.random()*100}) | |
.duration(function(d){ | |
var startingPoint = +d3.select(this).style("top").replace("%", "") | |
var duration = 3000 * (100-startingPoint)/100 | |
return Math.random()*duration + duration | |
}) | |
.ease(d3.easeCubicIn) | |
.style("top","100%") | |
.style("left",function(){ | |
var startingPoint = +d3.select(this).style("left").replace("%", "") | |
return +(Math.random()-.5)*15 + startingPoint+"%"; | |
}) | |
.on("end",function(){ | |
reset(x) | |
}) | |
} | |
function reset(x) { | |
d3.selectAll('.confetti-'+x) | |
.style("top",Math.random()*40+"%") | |
.style("left",Math.random()*100+"%") | |
drop(x); | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment