{
const ordering_1 = "weekStreak";
const ordering_2 = "gameCountLast30days";
const image_size = 30;
const dx_image = image_size * 0.4;
const bad = d3.schemeTableau10[2];
const good = d3.schemeTableau10[4];
const streakcolor = d3.schemeTableau10[4];
const imagetip_fun = (d) => {
const streakLine =
d.weekStreak > 0
? `Current ${d.weekStreak} week streak`
: `Not active this week :(`;
const matchesLine =
d.gameCountLast30days > 0
? `${d.gameCountLast30days} matches played in the last 30 days`
: `NO matches played in the last 30 days. Terrible`;
return `${d.profile}\n${streakLine}\n${matchesLine}`;
};
const gametip_fun = (d) => {
// "personalPerformance": -0.015066666666666673,
// "map": "de_inferno",
// "teamplay": true
// }
// console.log(d);
return `${d.profile}\n${d.gamedate}\n${d.weeksAgo}`;
};
const x_domain = [today, d3.utcDay.offset(today, -timerange)];
const fy_domain = [
teamname,
...d3
.sort(
profiledata,
(a, b) =>
d3.descending(a[ordering_1], b[ordering_1]) ||
d3.descending(a[ordering_2], b[ordering_2])
)
.map((d) => d.profile)
];
const color_config = {
"Week Streak": {
domain: ["team", "offstreak", "onstreak"],
range: [d3.schemeTableau10[6], "darkgrey", streakcolor],
fun: (d) =>
d.profile == teamname
? "team"
: d.weeksAgo <=
profiledata.find((f) => f.profile == d.profile)?.weekStreak
? "onstreak"
: "offstreak"
},
"Win/Loss": {
type: "categorical",
domain: ["win", "loss", "tie"],
range: [
d3.schemeTableau10[4],
d3.schemeTableau10[2],
d3.schemeTableau10[0]
],
unknown: "darkgrey",
fun: "matchResult"
},
"Overall Perf.": {
type: "diverging",
scheme: "RdYlGn",
fun: "overallPerformance"
// legend: true
},
"Personal Perf.": {
type: "diverging",
scheme: "RdYlGn",
fun: "personalPerformance"
// legend: true
},
Map: {
domain: [
"de_dust2",
"de_overpass",
"de_inferno",
"de_mirage",
"cs_office",
"de_anubis",
"de_ancient"
],
range: [
d3.schemePastel1[4], // "de_dust2",
d3.schemeCategory10[1], // "de_overpass"
d3.schemeCategory10[3], // "de_inferno"
d3.schemeCategory10[5], // "de_mirage"
d3.schemeCategory10[0], // "cs_office"
d3.schemePaired[0], // "de_anubis"
d3.schemeCategory10[2] // "de_ancient"
],
unknown: "darkgrey",
fun: "map"
}
};
const color_range = ["team", "offstreak", "onstreak"];
const color_domain = ["navy", "darkgrey", streakcolor];
const weekLabelFilterFun = (d) => {
const lastWeekOnStreak =
d.weeksAgo + 1 ==
profiledata.find((f) => f.profile == d.profile)?.weekStreak;
const weekInsideStreak =
d.weeksAgo < profiledata.find((f) => f.profile == d.profile)?.weekStreak;
const firstProfile = fy_domain[0] == d.profile;
return lastWeekOnStreak || (weekInsideStreak && firstProfile);
};
const graph = Plot.plot({
width: width,
height: 700,
marginLeft: 150,
insetLeft: 50,
x: {
grid: true,
ticks: "weeks",
domain: x_domain,
type: "utc",
// label: "Date (reversed)",
// labelOffset: -5,
axis: "top"
},
fy: {
marginTop: 25,
label: null,
domain: fy_domain,
tickSize: 0
},
color: {
...color_config[coloring]
},
marks: [
// Profile image
Plot.image(
profiledata,
Plot.selectFirst({
fy: "profile",
frameAnchor: "left",
src: "steamavatar",
dx: dx_image,
height: image_size
})
),
Plot.tickX(d3.unixDay.range(x_domain[1], x_domain[0], 1), {
strokeOpacity: 0.05,
filter: (f) => d3.timeDay.count(f, today) % 7 > 0
}),
// Gameday dots
Plot.dot(
allgamesdata.filter((f) => f.teamplay),
Plot.dodgeY({
x: "gamedate",
r: 3,
fy: "profile",
fill: color_config[coloring].fun,
// dx: -5, // This is to fit better inside the weeks
// dy: -7
anchor: "middle",
tip: true,
title: gametip_fun
})
),
// Non team gameplay
Plot.dot(
allgamesdata.filter((f) => !f.teamplay),
Plot.dodgeY({
x: "gamedate",
r: 3,
fy: "profile",
strokeOpacity: 0.2,
anchor: "middle"
})
),
// Weeks streak text
// Plot.text(
// daysdata,
// // Plot.selectFirst(
// Plot.binX(
// {
// interval: "week",
// text: "first",
// profile: "first"
// },
// {
// x: "date",
// fy: "profile",
// filter: weekLabelFilterFun,
// text: (d) =>
// d.profile == fy_domain[0] &&
// d.weeksAgo + 1 ==
// profiledata.find((f) => f.profile == d.profile)?.weekStreak
// ? `${d.weeksAgo + 1} weeks streak`
// : `${d.weeksAgo + 1}`,
// fontWeight: "bold",
// fill: streakcolor,
// textAnchor: "start",
// fontStyle: "italic",
// dx: -2,
// dy: -18
// }
// )
// ),
// Plot.text(
// // Dirty juggling here
// [
// fy_domain
// .slice(1)
// .map((fy) => ({
// ...profiledata.find((p) => p.profile == fy)
// }))
// .filter((f) => f.weekStreak == 0)[0]
// ],
// {
// frameanchor: "left",
// fy: (d) =>
// d3.max(profiledata, (d) => d.weekStreak) == 0
// ? teamname
// : d.profile,
// x: (d) => x_domain[0],
// text: (d) => "No week\nstreak :'(",
// fontWeight: "bold",
// fill: "darkgrey",
// textAnchor: "start",
// fontStyle: "italic",
// dx: 4
// // dy: -18
// }
// ),
// Today marker
Plot.dot([0], {
frameAnchor: "top-left",
fy: (d) => fy_domain[0],
height: 2,
x: (d) => x_domain[0],
symbol: "star",
r: 2,
dy: -3
}),
Plot.text([0], {
frameAnchor: "top-left",
fy: (d) => fy_domain[0],
height: 2,
x: (d) => x_domain[0],
text: (d) => (todayIsSelected ? "Today" : "Ref Date"),
lineAnchor: "bottom",
textAnchor: "middle",
fontStyle: "italic",
dy: -13
}),
// Tips
Plot.tip(
profiledata,
Plot.pointer(
Plot.selectFirst({
fy: "profile",
frameAnchor: "left",
anchor: "bottom-left",
dx: dx_image + image_size / 2 + 5,
dy: 0, //-image_size / 4,
title: imagetip_fun
})
)
)
]
});
return html`${graph}${Plot.legend({
color: { ...color_config[coloring], label: coloring }
})}`;
}