Added legend, cleaned up selections, cleaned up colors, changed colors and symbols for All-FvsU
This commit is contained in:
parent
d3d6d5c7d9
commit
33f10ee40b
210
src/index.md
210
src/index.md
@ -1,3 +1,7 @@
|
|||||||
|
```js
|
||||||
|
import("https://kit.fontawesome.com/e791529cc8.js");
|
||||||
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const parseTime = d3.timeParse("%b %d, %Y");
|
const parseTime = d3.timeParse("%b %d, %Y");
|
||||||
const formatYear = d3.utcFormat("%Y");
|
const formatYear = d3.utcFormat("%Y");
|
||||||
@ -7,6 +11,7 @@ const coerceGameData = (d, i) => ({
|
|||||||
year: parseInt(d.week.slice(0, 4)),
|
year: parseInt(d.week.slice(0, 4)),
|
||||||
spread: Number(d.spread),
|
spread: Number(d.spread),
|
||||||
fav: d.fav.replace(/\s\(\d\)/, ""),
|
fav: d.fav.replace(/\s\(\d\)/, ""),
|
||||||
|
at: d.at,
|
||||||
und: d.und.replace(/\s\(\d\)/, ""),
|
und: d.und.replace(/\s\(\d\)/, ""),
|
||||||
sF: Number(d.sF),
|
sF: Number(d.sF),
|
||||||
sU: Number(d.sU),
|
sU: Number(d.sU),
|
||||||
@ -20,7 +25,17 @@ const oddsfile = FileAttachment("./data/odds_data.json").json().then((D) => D.ma
|
|||||||
```js
|
```js
|
||||||
const teamNames = FileAttachment("./data/teams.json").json().then((d) => d.sort((a,b)=>a.label.localeCompare(b.label)))
|
const teamNames = FileAttachment("./data/teams.json").json().then((d) => d.sort((a,b)=>a.label.localeCompare(b.label)))
|
||||||
```
|
```
|
||||||
|
```js
|
||||||
|
const defaultBlockFill = "#EEE";
|
||||||
|
const noOUFill = "#555";
|
||||||
|
const winCircleFill = "rgba(255,255,255,0.75)";
|
||||||
|
const coverCircleFill = "rgb(0,0,0,0.75)";
|
||||||
|
const favFill = "#F25781";
|
||||||
|
const undFill = "#0277D1";
|
||||||
|
const neutFill = "#5C7553";
|
||||||
|
const neutFillSecondary = "#8F8A40"
|
||||||
|
const playOffStroke = "rgba(255,255,255,0.5)";
|
||||||
|
```
|
||||||
```js
|
```js
|
||||||
function parseWeek(w)
|
function parseWeek(w)
|
||||||
{
|
{
|
||||||
@ -52,7 +67,7 @@ teamNames.unshift({label:"All",alts:["All"]});
|
|||||||
const teamSelect = Inputs.select(teamNames, {
|
const teamSelect = Inputs.select(teamNames, {
|
||||||
format: (d) => d.label,
|
format: (d) => d.label,
|
||||||
valueof: (d) => d.alts,
|
valueof: (d) => d.alts,
|
||||||
value: teamNames[0].alts,
|
value: teamNames[26].alts,
|
||||||
label: "Team:"
|
label: "Team:"
|
||||||
})
|
})
|
||||||
const teamValue = Generators.input(teamSelect);
|
const teamValue = Generators.input(teamSelect);
|
||||||
@ -65,6 +80,14 @@ const viewSelect = Inputs.radio(
|
|||||||
]),
|
]),
|
||||||
{
|
{
|
||||||
value: 0,
|
value: 0,
|
||||||
|
format:(x)=>{
|
||||||
|
if(x[1]==1)
|
||||||
|
{
|
||||||
|
return html`Predicted Score <i class="fa-regular fa-circle-question"></i>`
|
||||||
|
}else{
|
||||||
|
return "Favorite vs. Underdog"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const viewValue = Generators.input(viewSelect);
|
const viewValue = Generators.input(viewSelect);
|
||||||
@ -220,55 +243,78 @@ function buildDualSquare(d, width, height) {
|
|||||||
const blockHeight = height;
|
const blockHeight = height;
|
||||||
const strokeWidth = 2;
|
const strokeWidth = 2;
|
||||||
|
|
||||||
let blockColor = "#EEE";
|
let blockColor = defaultBlockFill;
|
||||||
let fullStroke = "none";
|
let fullStroke = "none";
|
||||||
let winFill = "none";
|
let winFill = "none";
|
||||||
let beatSpreadFill = "none";
|
let beatSpreadFill = "none";
|
||||||
|
|
||||||
|
let isAll = (teamValue[0=="All"]);
|
||||||
|
|
||||||
if(viewValue==0)
|
if(viewValue==0)
|
||||||
{
|
{
|
||||||
if(d.sF > d.sU)
|
|
||||||
{
|
|
||||||
winFill = "rgba(255,255,255,0.75)"
|
|
||||||
}
|
|
||||||
if(d.sF - d.sU > d.spread)
|
|
||||||
{
|
|
||||||
beatSpreadFill = "rgb(0,0,0,0.75)"
|
|
||||||
}
|
|
||||||
if(Math.abs(d.sF - d.sU) < d.spread && d.sF < d.sU)
|
|
||||||
{
|
|
||||||
beatSpreadFill = "rgb(0,0,0,0.75)"
|
|
||||||
}
|
|
||||||
if(teamValue[0]=="All")
|
if(teamValue[0]=="All")
|
||||||
{
|
{
|
||||||
blockColor = "#545C32";
|
if(d.sF > d.sU && d.sF - d.sU == d.spread)//fav doesn't cover, wins
|
||||||
|
{
|
||||||
|
blockColor = neutFill;
|
||||||
|
}
|
||||||
|
if(d.sF > d.sU && d.sF - d.sU < d.spread)//fav doesn't cover, wins
|
||||||
|
{
|
||||||
|
blockColor = neutFill;
|
||||||
|
winFill = winCircleFill;
|
||||||
|
}
|
||||||
|
if(d.sF - d.sU > d.spread)//favorite covers, wins
|
||||||
|
{
|
||||||
|
blockColor = neutFill;
|
||||||
|
winFill = winCircleFill;
|
||||||
|
beatSpreadFill = coverCircleFill;
|
||||||
|
}
|
||||||
|
if(d.sF <= d.sU)//underdog covers, wins
|
||||||
|
{
|
||||||
|
blockColor = neutFillSecondary;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
|
if(d.sF > d.sU)//underdog covers, loses
|
||||||
|
{
|
||||||
|
winFill = winCircleFill;
|
||||||
|
}
|
||||||
|
if(d.sF - d.sU > d.spread)//favorite covers, wins
|
||||||
|
{
|
||||||
|
beatSpreadFill = coverCircleFill;
|
||||||
|
}
|
||||||
|
if(Math.abs(d.sF - d.sU) < d.spread && d.sF < d.sU)//underdog covers, wins
|
||||||
|
{
|
||||||
|
beatSpreadFill = coverCircleFill;
|
||||||
|
}
|
||||||
if(teamValue.indexOf(d.fav) > -1)
|
if(teamValue.indexOf(d.fav) > -1)
|
||||||
{
|
{
|
||||||
blockColor = "#F25781";
|
blockColor = favFill;
|
||||||
}
|
}
|
||||||
if(teamValue.indexOf(d.und) > -1)
|
if(teamValue.indexOf(d.und) > -1)
|
||||||
{
|
{
|
||||||
blockColor = "#0277D1";
|
blockColor = undFill;
|
||||||
if(d.sU > d.sF)
|
if(d.sU > d.sF)
|
||||||
{
|
{
|
||||||
winFill = "rgba(255,255,255,0.75)"
|
winFill = winCircleFill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(d.week == undefined)
|
|
||||||
{
|
|
||||||
fullStroke = "rgba(255,255,255,0.5)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
if (d.pDiff) {
|
if (d.pDiff) {
|
||||||
blockColor = d3.interpolateOrRd(diffColorScale(d.pDiff));
|
blockColor = d3.interpolateOrRd(diffColorScale(d.pDiff));
|
||||||
} else {
|
} else {
|
||||||
blockColor = "#555";
|
blockColor = noOUFill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(d.week == undefined)
|
||||||
|
{
|
||||||
|
fullStroke = playOffStroke;
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<rect x="0" y="0" height="${height}" width="${
|
<rect x="0" y="0" height="${height}" width="${
|
||||||
width
|
width
|
||||||
@ -304,11 +350,105 @@ function buildToolTip(d)
|
|||||||
return toolTipHTML;
|
return toolTipHTML;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
```js
|
||||||
|
function legend()
|
||||||
|
{
|
||||||
|
const legendNode = d3.create("div");
|
||||||
|
|
||||||
|
const isAll = (teamValue[0]=="All");
|
||||||
|
console.log(isAll);
|
||||||
|
|
||||||
|
if(!viewValue)
|
||||||
|
{
|
||||||
|
legendNode.html(
|
||||||
|
`
|
||||||
|
<table id="legend-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>${isAll ? "push" : ""}</td>
|
||||||
|
<td>win</td>
|
||||||
|
<td>cover</td>
|
||||||
|
<td>playoffs</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Favorite</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFill)}` : `${legendSwatch(favFill)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFill,false,true)}` : `${legendSwatch(favFill,false,true)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFill,true,true)}` : `${legendSwatch(favFill,true, true)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFill,false,false,true)}` : `${legendSwatch(favFill,false,false,true)}`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Underdog</td>
|
||||||
|
<td>${isAll ? `` : `${legendSwatch(undFill)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFillSecondary)}` : `${legendSwatch(undFill,true,true)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFillSecondary)}` : `${legendSwatch(undFill,true, true)}`}</td>
|
||||||
|
<td>${isAll ? `${legendSwatch(neutFillSecondary,false,false,true)}` : `${legendSwatch(undFill,false,false,true)}`}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
legendNode.html(
|
||||||
|
`
|
||||||
|
<svg width="100%" height="20" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="Gradient2" x1="0" x2="1" y1="0" y2="0">
|
||||||
|
<stop offset="0%" stop-color="${d3.interpolateOrRd(0)}"/>
|
||||||
|
<stop offset="100%" stop-color="${d3.interpolateOrRd(1)}"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect x="0" y="0" width="100%" height="20" fill="url(#Gradient2)"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
<table id="legend-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Worst predictions</td>
|
||||||
|
<td style="text-align:right">Best predictions</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding-top:5px">
|
||||||
|
${legendSwatch(noOUFill)} No O/U data
|
||||||
|
</td>
|
||||||
|
<td style="padding-top:5px">
|
||||||
|
${legendSwatch(d3.interpolateOrRd(1),false,false,true)} Playoffs
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return legendNode.node();
|
||||||
|
}
|
||||||
|
|
||||||
|
function legendSwatch(bgFill,cover,win,playoffs)
|
||||||
|
{
|
||||||
|
const blockSize = 15;
|
||||||
|
const strokeWidth = 2;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<svg viewBox="0 0 ${blockSize} ${blockSize}" width="${blockSize}" height="${blockSize}" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="0" y="0" width="${blockSize}" height="${blockSize}" fill="${bgFill}"/>
|
||||||
|
<circle cx="${blockSize/2}" cy="${blockSize/2}" r="${blockSize/4}" fill="${win ? winCircleFill : 'none'}"/>
|
||||||
|
<circle cx="${blockSize/2}" cy="${blockSize/2}" r="${blockSize/6}" fill="${cover ? coverCircleFill : 'none'}"/>
|
||||||
|
<rect x="${strokeWidth/2}" y="${strokeWidth/2}" height="${blockSize-strokeWidth}" width="${blockSize-strokeWidth}" stroke="${playoffs ? playOffStroke : "none"}" fill="none" stroke-width="${strokeWidth}"/>
|
||||||
|
</svg>
|
||||||
|
`
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-2">
|
||||||
<div class="card">${teamSelect}${viewSelect}</div>
|
<div class="card"><div>${teamSelect}</div><div style="padding-top:12px;">${viewSelect}</div></div>
|
||||||
<div class="card">Legend</div>
|
<div class="card">${legend()}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1">
|
<div class="grid grid-cols-1">
|
||||||
<div class="card">${resize((width) => oddsPlot(oddsfile, {width}))}</div>
|
<div class="card">${resize((width) => oddsPlot(oddsfile, {width}))}</div>
|
||||||
@ -378,6 +518,24 @@ function buildToolTip(d)
|
|||||||
border: 2px white;
|
border: 2px white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#legend-table
|
||||||
|
{
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#legend-table td
|
||||||
|
{
|
||||||
|
width:50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#legend-table td:nth-child(1)
|
||||||
|
{
|
||||||
|
width: 50px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.lexend-400 {
|
.lexend-400 {
|
||||||
font-family: "Lexend", serif;
|
font-family: "Lexend", serif;
|
||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user