Skip to content

Commit ad315ce

Browse files
committed
Add salary and player count columns to teams page
1 parent c8108a4 commit ad315ce

2 files changed

Lines changed: 161 additions & 56 deletions

File tree

src/Players.md

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -71,30 +71,28 @@ function getStatsForPeriod(selectedPeriod) {
7171

7272
return latestPeriodData.map(stat => {
7373
// Calculate dstat based on position
74-
let dstat = 0;
74+
let dstat = null;
7575
if (stat.pos === "G") {
76-
dstat = 0;
76+
dstat = null;
7777
} else if (stat.pos === "D") {
7878
dstat = (stat["stats/toi"] || 0) / 20 + (stat["stats/blocks"] || 0) + (stat["stats/take"] || 0) - (stat["stats/give"] || 0);
7979
} else { // Forward positions (F, C, LW, RW, etc.)
8080
dstat = (stat["stats/toi"] || 0) / 30 + (stat["stats/blocks"] || 0) + (stat["stats/take"] || 0) - (stat["stats/give"] || 0);
8181
}
8282

8383
// Calculate gstat based on position
84-
let gstat = 0;
84+
let gstat = null;
8585
if (stat.pos === "G") {
8686
gstat = 2 * (stat["stats/wins"] || 0) + (stat["stats/ties"] || 0) + 2 * (stat["stats/so"] || 0) + 0.15 * (stat["stats/sa"] || 0) - (stat["stats/ga"] || 0);
87-
} else {
88-
gstat = 0;
8987
}
9088

9189
return {
9290
hockeyRef: stat.hockeyRef,
9391
team: stat.team,
9492
pos: stat.pos,
95-
goals: stat["stats/goals"] || 0,
96-
assists: stat["stats/assists"] || 0,
97-
toughness: (stat.pos === "G") ? 0 : ((stat["stats/pim"] || 0) + (stat["stats/hits"] || 0)),
93+
goals: (stat.pos === "G") ? null : (stat["stats/goals"] || 0),
94+
assists: (stat.pos === "G") ? null : (stat["stats/assists"] || 0),
95+
toughness: (stat.pos === "G") ? null : ((stat["stats/pim"] || 0) + (stat["stats/hits"] || 0)),
9896
dstat: dstat,
9997
gstat: gstat,
10098
games_played: stat["stats/gp"] || 0
@@ -134,32 +132,41 @@ function getStatsForPeriod(selectedPeriod) {
134132
}
135133

136134
// Calculate current period gstat
137-
let currentGstat = 0;
135+
let currentGstat = null;
138136
if (stat.pos === "G") {
139137
currentGstat = 2 * (stat["stats/wins"] || 0) + (stat["stats/ties"] || 0) + 2 * (stat["stats/so"] || 0) + 0.15 * (stat["stats/sa"] || 0) - (stat["stats/ga"] || 0);
140-
} else {
141-
currentGstat = 0;
142138
}
143139

144140
// Calculate previous period gstat
145-
let prevGstat = 0;
146-
if (prevStat) {
147-
if (prevStat.pos === "G") {
148-
prevGstat = 2 * (prevStat["stats/wins"] || 0) + (prevStat["stats/ties"] || 0) + 2 * (prevStat["stats/so"] || 0) + 0.15 * (prevStat["stats/sa"] || 0) - (prevStat["stats/ga"] || 0);
149-
} else {
150-
prevGstat = 0;
151-
}
141+
let prevGstat = null;
142+
if (prevStat && prevStat.pos === "G") {
143+
prevGstat = 2 * (prevStat["stats/wins"] || 0) + (prevStat["stats/ties"] || 0) + 2 * (prevStat["stats/so"] || 0) + 0.15 * (prevStat["stats/sa"] || 0) - (prevStat["stats/ga"] || 0);
144+
}
145+
146+
// Calculate gstat difference (only for goalies)
147+
let gstatDiff = null;
148+
if (stat.pos === "G") {
149+
gstatDiff = (currentGstat || 0) - (prevGstat || 0);
150+
}
151+
152+
// Calculate current period toughness
153+
let currentToughness = (stat.pos === "G") ? 0 : ((stat["stats/pim"] || 0) + (stat["stats/hits"] || 0));
154+
155+
// Calculate previous period toughness
156+
let prevToughness = 0;
157+
if (prevStat && prevStat.pos !== "G") {
158+
prevToughness = (prevStat["stats/pim"] || 0) + (prevStat["stats/hits"] || 0);
152159
}
153160

154161
return {
155162
hockeyRef: stat.hockeyRef,
156163
team: stat.team,
157164
pos: stat.pos,
158-
goals: (stat["stats/goals"] || 0) - (prevStat?.["stats/goals"] || 0),
159-
assists: (stat["stats/assists"] || 0) - (prevStat?.["stats/assists"] || 0),
160-
toughness: (stat.pos === "G") ? 0 : (((stat["stats/pim"] || 0) + (stat["stats/hits"] || 0)) - ((prevStat?.["stats/pim"] || 0) + (prevStat?.["stats/hits"] || 0))),
161-
dstat: currentDstat - prevDstat,
162-
gstat: currentGstat - prevGstat,
165+
goals: (stat.pos === "G") ? null : ((stat["stats/goals"] || 0) - (prevStat?.["stats/goals"] || 0)),
166+
assists: (stat.pos === "G") ? null : ((stat["stats/assists"] || 0) - (prevStat?.["stats/assists"] || 0)),
167+
toughness: (stat.pos === "G") ? null : (currentToughness - prevToughness),
168+
dstat: (stat.pos === "G") ? null : (currentDstat - prevDstat),
169+
gstat: gstatDiff,
163170
games_played: (stat["stats/gp"] || 0) - (prevStat?.["stats/gp"] || 0)
164171
};
165172
});
@@ -280,11 +287,11 @@ function createPlayerStatsData(selectedPeriod) {
280287
Team: roster ? roster.ABBR : "N/A",
281288
Position: mapPosition(player.Pos),
282289
Reserve: roster ? roster.RESERVE : "N/A",
283-
Goals: stats ? stats.goals : 0,
284-
Assists: stats ? stats.assists : 0,
285-
Toughness: stats ? stats.toughness : 0,
286-
DStat: stats ? stats.dstat : 0,
287-
GStat: stats ? stats.gstat : 0,
290+
Goals: stats ? stats.goals : (mapPosition(player.Pos) === "G" ? null : 0),
291+
Assists: stats ? stats.assists : (mapPosition(player.Pos) === "G" ? null : 0),
292+
Toughness: stats ? stats.toughness : (mapPosition(player.Pos) === "G" ? null : 0),
293+
DStat: stats ? stats.dstat : (mapPosition(player.Pos) === "G" ? null : 0),
294+
GStat: stats ? (stats.gstat !== null ? stats.gstat : (mapPosition(player.Pos) === "G" ? 0 : null)) : (mapPosition(player.Pos) === "G" ? 0 : null),
288295
GamesPlayed: stats ? stats.games_played : 0,
289296
NHLTeam: player["NHL Team"]
290297
};
@@ -333,21 +340,21 @@ const filteredStatsData = playerStatsData
333340
const activeTotals = filteredStatsData
334341
.filter(player => player.Reserve !== "R" && player.Reserve !== "N/A")
335342
.reduce((totals, player) => ({
336-
goals: totals.goals + (player.Goals || 0),
337-
assists: totals.assists + (player.Assists || 0),
338-
toughness: totals.toughness + (player.Toughness || 0),
343+
goals: totals.goals + (player.Position !== "G" ? (player.Goals || 0) : 0),
344+
assists: totals.assists + (player.Position !== "G" ? (player.Assists || 0) : 0),
345+
toughness: totals.toughness + (player.Position !== "G" ? (player.Toughness || 0) : 0),
339346
dstat: totals.dstat + (player.DStat || 0),
340-
gstat: totals.gstat + (player.GStat || 0)
347+
gstat: totals.gstat + (player.GStat !== null ? player.GStat : 0)
341348
}), { goals: 0, assists: 0, toughness: 0, dstat: 0, gstat: 0 });
342349

343350
const reserveTotals = filteredStatsData
344351
.filter(player => player.Reserve === "R")
345352
.reduce((totals, player) => ({
346-
goals: totals.goals + (player.Goals || 0),
347-
assists: totals.assists + (player.Assists || 0),
348-
toughness: totals.toughness + (player.Toughness || 0),
353+
goals: totals.goals + (player.Position !== "G" ? (player.Goals || 0) : 0),
354+
assists: totals.assists + (player.Position !== "G" ? (player.Assists || 0) : 0),
355+
toughness: totals.toughness + (player.Position !== "G" ? (player.Toughness || 0) : 0),
349356
dstat: totals.dstat + (player.DStat || 0),
350-
gstat: totals.gstat + (player.GStat || 0)
357+
gstat: totals.gstat + (player.GStat !== null ? player.GStat : 0)
351358
}), { goals: 0, assists: 0, toughness: 0, dstat: 0, gstat: 0 });
352359
```
353360
@@ -449,8 +456,11 @@ const reserveTotals = filteredStatsData
449456
},
450457
format: {
451458
Reserve: x => x === "R" ? "" : "",
452-
DStat: x => x ? x.toFixed(2) : "0.00",
453-
GStat: x => x ? x.toFixed(2) : "0.00"
459+
Goals: x => x !== null ? x : "",
460+
Assists: x => x !== null ? x : "",
461+
Toughness: x => x !== null ? x : "",
462+
DStat: x => x !== null ? x.toFixed(2) : "",
463+
GStat: x => x !== null ? x.toFixed(2) : ""
454464
},
455465
sort: null,
456466
rows: Math.min(filteredStatsData.length, 50),
@@ -573,11 +583,11 @@ window.createPlayerStatsData = function(selectedPeriod) {
573583
Team: roster ? roster.ABBR : "N/A",
574584
Position: window.mapPosition(player.Pos),
575585
Reserve: roster ? roster.RESERVE : "N/A",
576-
Goals: stats ? stats.goals : 0,
577-
Assists: stats ? stats.assists : 0,
578-
Toughness: stats ? stats.toughness : 0,
579-
DStat: stats ? stats.dstat : 0,
580-
GStat: stats ? stats.gstat : 0,
586+
Goals: stats ? stats.goals : (window.mapPosition(player.Pos) === "G" ? null : 0),
587+
Assists: stats ? stats.assists : (window.mapPosition(player.Pos) === "G" ? null : 0),
588+
Toughness: stats ? stats.toughness : (window.mapPosition(player.Pos) === "G" ? null : 0),
589+
DStat: stats ? stats.dstat : (window.mapPosition(player.Pos) === "G" ? null : 0),
590+
GStat: stats ? (stats.gstat !== null ? stats.gstat : (window.mapPosition(player.Pos) === "G" ? 0 : null)) : (window.mapPosition(player.Pos) === "G" ? 0 : null),
581591
GamesPlayed: stats ? stats.games_played : 0,
582592
NHLTeam: player["NHL Team"]
583593
};
@@ -676,21 +686,21 @@ function updateTables() {
676686
const activeTotals = filteredStatsData
677687
.filter(player => player.Reserve !== "R" && player.Reserve !== "N/A")
678688
.reduce((totals, player) => ({
679-
goals: totals.goals + (player.Goals || 0),
680-
assists: totals.assists + (player.Assists || 0),
681-
toughness: totals.toughness + (player.Toughness || 0),
689+
goals: totals.goals + (player.Position !== "G" ? (player.Goals || 0) : 0),
690+
assists: totals.assists + (player.Position !== "G" ? (player.Assists || 0) : 0),
691+
toughness: totals.toughness + (player.Position !== "G" ? (player.Toughness || 0) : 0),
682692
dstat: totals.dstat + (player.DStat || 0),
683-
gstat: totals.gstat + (player.GStat || 0)
693+
gstat: totals.gstat + (player.GStat !== null ? player.GStat : 0)
684694
}), { goals: 0, assists: 0, toughness: 0, dstat: 0, gstat: 0 });
685695
686696
const reserveTotals = filteredStatsData
687697
.filter(player => player.Reserve === "R")
688698
.reduce((totals, player) => ({
689-
goals: totals.goals + (player.Goals || 0),
690-
assists: totals.assists + (player.Assists || 0),
691-
toughness: totals.toughness + (player.Toughness || 0),
699+
goals: totals.goals + (player.Position !== "G" ? (player.Goals || 0) : 0),
700+
assists: totals.assists + (player.Position !== "G" ? (player.Assists || 0) : 0),
701+
toughness: totals.toughness + (player.Position !== "G" ? (player.Toughness || 0) : 0),
692702
dstat: totals.dstat + (player.DStat || 0),
693-
gstat: totals.gstat + (player.GStat || 0)
703+
gstat: totals.gstat + (player.GStat !== null ? player.GStat : 0)
694704
}), { goals: 0, assists: 0, toughness: 0, dstat: 0, gstat: 0 });
695705
696706
console.log('Filtered data lengths:', {

src/Teams.md

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,96 @@ toc: false
1010
const teamCash = await FileAttachment("data/team_cash.csv").csv({typed: true});
1111
const teamInfo = await FileAttachment("data/team_info.csv").csv({typed: true});
1212
const owners = await FileAttachment("data/owners.csv").csv({typed: true});
13+
const contracts = await FileAttachment("data/contracts.csv").csv({typed: true});
14+
const latestRoster = await FileAttachment("data/rosters_p03.csv").csv({typed: true});
15+
const playerInfo = await FileAttachment("data/player_info.csv").csv({typed: true});
1316

14-
// Combine team info with cash balances for the first tab
17+
// Calculate total salaries per team
18+
const teamSalaries = teamInfo.map(team => {
19+
const teamRoster = latestRoster.filter(player => player.ABBR === team.ABBR);
20+
const totalSalary = teamRoster.reduce((sum, player) => {
21+
const contract = contracts.find(c => c.ID === player.ID);
22+
return sum + (contract ? (contract.Salary || 0) : 0);
23+
}, 0);
24+
25+
return {
26+
ABBR: team.ABBR,
27+
TOTAL_SALARY: totalSalary
28+
};
29+
});
30+
31+
// Calculate player counts per team by position
32+
const teamPlayerCounts = teamInfo.map(team => {
33+
const teamRoster = latestRoster.filter(player => player.ABBR === team.ABBR);
34+
35+
// Count all players by position
36+
const positionCounts = teamRoster.reduce((counts, player) => {
37+
// Get player info to determine position
38+
const playerDetails = playerInfo.find(p => p.ID === player.ID);
39+
40+
if (playerDetails) {
41+
const pos = playerDetails.Pos;
42+
if (pos === "G") {
43+
counts.G++;
44+
} else if (pos === "D") {
45+
counts.D++;
46+
} else {
47+
counts.F++; // All other positions (C, LW, RW, F, etc.) are forwards
48+
}
49+
}
50+
51+
return counts;
52+
}, { F: 0, D: 0, G: 0 });
53+
54+
// Count active players by position (non-reserve)
55+
const activePositionCounts = teamRoster
56+
.filter(player => player.RESERVE !== "R")
57+
.reduce((counts, player) => {
58+
const playerDetails = playerInfo.find(p => p.ID === player.ID);
59+
60+
if (playerDetails) {
61+
const pos = playerDetails.Pos;
62+
if (pos === "G") {
63+
counts.G++;
64+
} else if (pos === "D") {
65+
counts.D++;
66+
} else {
67+
counts.F++;
68+
}
69+
}
70+
71+
return counts;
72+
}, { F: 0, D: 0, G: 0 });
73+
74+
const total = positionCounts.F + positionCounts.D + positionCounts.G;
75+
const activeTotal = activePositionCounts.F + activePositionCounts.D + activePositionCounts.G;
76+
const playerCountText = `(${positionCounts.F}/${positionCounts.D}/${positionCounts.G}) ${total}`;
77+
const activePlayerCountText = `(${activePositionCounts.F}/${activePositionCounts.D}/${activePositionCounts.G}) ${activeTotal}`;
78+
79+
return {
80+
ABBR: team.ABBR,
81+
PLAYER_COUNT: playerCountText,
82+
ACTIVE_PLAYER_COUNT: activePlayerCountText
83+
};
84+
});
85+
86+
// Combine team info with cash balances and salaries for the first tab
1587
const teamCashData = teamInfo.map(team => {
1688
const cashInfo = teamCash.find(cash => cash.ABBR === team.ABBR);
89+
const salaryInfo = teamSalaries.find(salary => salary.ABBR === team.ABBR);
90+
const playerCountInfo = teamPlayerCounts.find(count => count.ABBR === team.ABBR);
91+
const totalSalary = salaryInfo ? salaryInfo.TOTAL_SALARY : 0;
92+
const calculatedSalaryPerPeriod = totalSalary / 25;
93+
const salaryPerPeriod = Math.max(calculatedSalaryPerPeriod, 13);
1794
return {
1895
ABBR: team.ABBR,
1996
NAME: team.NAME,
20-
CASH: cashInfo ? cashInfo.CASH : 0
97+
CASH: cashInfo ? cashInfo.CASH : 0,
98+
TOTAL_SALARY: totalSalary,
99+
SALARY_PER_PERIOD: salaryPerPeriod,
100+
PLAYER_COUNT: playerCountInfo ? playerCountInfo.PLAYER_COUNT : "(0/0/0) 0",
101+
ACTIVE_PLAYER_COUNT: playerCountInfo ? playerCountInfo.ACTIVE_PLAYER_COUNT : "(0/0/0) 0",
102+
IS_MINIMUM_SALARY: calculatedSalaryPerPeriod < 13
21103
};
22104
});
23105

@@ -46,15 +128,28 @@ const teamOwnerData = teamInfo.map(team => {
46128
columns: [
47129
"ABBR",
48130
"NAME",
49-
"CASH"
131+
"CASH",
132+
"TOTAL_SALARY",
133+
"SALARY_PER_PERIOD",
134+
"PLAYER_COUNT",
135+
"ACTIVE_PLAYER_COUNT"
50136
],
51137
header: {
52138
ABBR: "Team",
53139
NAME: "Team Name",
54-
CASH: "Cash Balance ($)"
140+
CASH: "Cash Balance ($)",
141+
TOTAL_SALARY: "Total Salaries ($)",
142+
SALARY_PER_PERIOD: "Salary per Period ($)",
143+
PLAYER_COUNT: "Players (F/D/G)",
144+
ACTIVE_PLAYER_COUNT: "Active (F/D/G)"
55145
},
56146
format: {
57-
CASH: x => x.toLocaleString("en-US", {minimumFractionDigits: 2, maximumFractionDigits: 2})
147+
CASH: x => x.toLocaleString("en-US", {minimumFractionDigits: 2, maximumFractionDigits: 2}),
148+
TOTAL_SALARY: x => x.toLocaleString("en-US"),
149+
SALARY_PER_PERIOD: (x, i, data) => {
150+
const value = x.toLocaleString("en-US", {minimumFractionDigits: 2, maximumFractionDigits: 2});
151+
return data[i].IS_MINIMUM_SALARY ? html`<span style="background-color: yellow; padding: 2px 4px;">${value}</span>` : value;
152+
}
58153
},
59154
sort: "NAME",
60155
rows: 32,

0 commit comments

Comments
 (0)