Make game page like old site
This commit is contained in:
parent
0751ece4da
commit
77be97ac4f
@ -39,7 +39,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="team-pitching-stats">
|
<tbody id="team-pitching-stats">
|
||||||
<tr v-for="stat in pitchingStats">
|
<tr v-for="stat in pitchingStats" :key="stat.player.name">
|
||||||
<td>
|
<td>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
@ -118,7 +118,7 @@ import { aggregatePitchingStats, fetchPitchingStatsBySeasonAndTeamId, type Pitch
|
|||||||
import { outsToInnings, winPercentage, hitsPer9, hrsPer9 } from '@/services/utilities'
|
import { outsToInnings, winPercentage, hitsPer9, hrsPer9 } from '@/services/utilities'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TeamPitchingTable",
|
name: 'TeamPitchingTable',
|
||||||
props: {
|
props: {
|
||||||
seasonNumber: { type: Number, required: true },
|
seasonNumber: { type: Number, required: true },
|
||||||
teamId: { type: Number, required: true },
|
teamId: { type: Number, required: true },
|
||||||
|
|||||||
@ -53,6 +53,12 @@ export const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('../views/ManagerView.vue'),
|
component: () => import('../views/ManagerView.vue'),
|
||||||
props: castManagersRouteParams
|
props: castManagersRouteParams
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/games/:seasonNumber/:weekNumber/:gameNumber/:team1Abbreviation/:team2Abbreviation',
|
||||||
|
name: 'games',
|
||||||
|
component: () => import('../views/GameView.vue'),
|
||||||
|
props: castGamesRouteParams
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function castTeamsRouteParams(route: { params: { teamAbbreviation: string, seasonNumber: string } }) {
|
function castTeamsRouteParams(route: { params: { teamAbbreviation: string, seasonNumber: string } }) {
|
||||||
@ -82,6 +88,16 @@ function castManagersRouteParams(route: { params: { managerName: string } }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function castGamesRouteParams(route: { params: { seasonNumber: string, weekNumber: string, gameNumber: string, team1Abbreviation: string, team2Abbreviation: string } }) {
|
||||||
|
return {
|
||||||
|
seasonNumber: Number(route.params.seasonNumber),
|
||||||
|
weekNumber: Number(route.params.weekNumber),
|
||||||
|
gameNumber: Number(route.params.gameNumber),
|
||||||
|
team1Abbreviation: route.params.team1Abbreviation,
|
||||||
|
team2Abbreviation: route.params.team2Abbreviation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(), //import.meta.env.BASE_URL),
|
history: createWebHistory(), //import.meta.env.BASE_URL),
|
||||||
routes,
|
routes,
|
||||||
|
|||||||
@ -155,6 +155,22 @@ export async function fetchBattingStatsForLastFourGamesBySeasonAndPlayerId(seaso
|
|||||||
return battingStatsResponse.stats
|
return battingStatsResponse.stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchBattingStatsBySeries(seasonNumber: number, weekNumber: number, homeTeamId: number, awayTeamId: number): Promise<BattingStat[]> {
|
||||||
|
// no support for pre-modern games yet
|
||||||
|
if (seasonNumber < MODERN_STAT_ERA_START) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
|
||||||
|
|
||||||
|
const battingStatsResponse: {
|
||||||
|
count: number
|
||||||
|
stats: BattingStat[]
|
||||||
|
} = await response.json()
|
||||||
|
|
||||||
|
return battingStatsResponse.stats
|
||||||
|
}
|
||||||
|
|
||||||
export function aggregateBattingStats(battingStats: BattingStat[]): BattingStat {
|
export function aggregateBattingStats(battingStats: BattingStat[]): BattingStat {
|
||||||
const totalStat: BattingStat = {
|
const totalStat: BattingStat = {
|
||||||
player: battingStats[0].player,
|
player: battingStats[0].player,
|
||||||
|
|||||||
@ -137,6 +137,22 @@ export async function fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId(seas
|
|||||||
return fieldingStatsResponse.stats.map(normalizeFieldingStat)
|
return fieldingStatsResponse.stats.map(normalizeFieldingStat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchFieldingStatsBySeries(seasonNumber: number, weekNumber: number, homeTeamId: number, awayTeamId: number): Promise<FieldingStat[]> {
|
||||||
|
// no support for pre-modern games yet
|
||||||
|
if (seasonNumber < MODERN_STAT_ERA_START) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playerpositiongame`)
|
||||||
|
|
||||||
|
const fieldingStatsResponse: {
|
||||||
|
count: number
|
||||||
|
stats: FieldingStatRaw[]
|
||||||
|
} = await response.json()
|
||||||
|
|
||||||
|
return fieldingStatsResponse.stats.map(normalizeFieldingStat)
|
||||||
|
}
|
||||||
|
|
||||||
export function aggregateFieldingStats(fieldingStats: FieldingStat[]): FieldingStat[] {
|
export function aggregateFieldingStats(fieldingStats: FieldingStat[]): FieldingStat[] {
|
||||||
const fieldingStatsByPosition = fieldingStats.reduce((statsByPos: { [key: string]: FieldingStat }, stat: FieldingStat) => {
|
const fieldingStatsByPosition = fieldingStats.reduce((statsByPos: { [key: string]: FieldingStat }, stat: FieldingStat) => {
|
||||||
if (!statsByPos[stat.pos]) {
|
if (!statsByPos[stat.pos]) {
|
||||||
|
|||||||
@ -32,3 +32,25 @@ export async function fetchGamesBySeasonAndWeek(seasonNumber: number, weekNumber
|
|||||||
|
|
||||||
return gamesResponse.games
|
return gamesResponse.games
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchSingleGame(seasonNumber: number, weekNumber: number, gameNumber: number, homeTeamId: number, awayTeamId: number): Promise<Game | undefined> {
|
||||||
|
if (seasonNumber < MODERN_STAT_ERA_START) {
|
||||||
|
console.warn('Cannot use games endpoint to fetch stats before season 8')
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${SITE_URL}/api/v3/games?season=${seasonNumber}&week=${weekNumber}&game_num=${gameNumber}&team1_id=${homeTeamId}&team2_id=${awayTeamId}`)
|
||||||
|
|
||||||
|
const gamesResponse: {
|
||||||
|
count: number
|
||||||
|
games: Game[]
|
||||||
|
} = await response.json()
|
||||||
|
|
||||||
|
if (gamesResponse.count !== 1) {
|
||||||
|
throw new Error('gameService.fetchSingleGame - Expected one game, return contained none or many')
|
||||||
|
}
|
||||||
|
|
||||||
|
return gamesResponse.games[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// v3/games?season=9&week=1&game_num=1&team1_id=355&team2_id=361&short_output=TRUE
|
||||||
|
|||||||
@ -222,6 +222,22 @@ export async function fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId(seas
|
|||||||
return pitchingStatsResponse.stats.map(normalizePitchingStat)
|
return pitchingStatsResponse.stats.map(normalizePitchingStat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchPitchingStatsBySeries(seasonNumber: number, weekNumber: number, homeTeamId: number, awayTeamId: number): Promise<PitchingStat[]> {
|
||||||
|
// no support for pre-modern games yet
|
||||||
|
if (seasonNumber < MODERN_STAT_ERA_START) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
|
||||||
|
|
||||||
|
const pitchingStatsResponse: {
|
||||||
|
count: number
|
||||||
|
stats: PitchingStat[]
|
||||||
|
} = await response.json()
|
||||||
|
|
||||||
|
return pitchingStatsResponse.stats
|
||||||
|
}
|
||||||
|
|
||||||
export function aggregatePitchingStats(pitchingStats: PitchingStat[]): PitchingStat {
|
export function aggregatePitchingStats(pitchingStats: PitchingStat[]): PitchingStat {
|
||||||
const totalStat: PitchingStat = {
|
const totalStat: PitchingStat = {
|
||||||
player: pitchingStats[0].player,
|
player: pitchingStats[0].player,
|
||||||
|
|||||||
444
src/views/GameView.vue
Normal file
444
src/views/GameView.vue
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
<template>
|
||||||
|
<div class="centerDiv">
|
||||||
|
|
||||||
|
<!-- Teams and Score -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<RouterLink v-if="awayTeamAbbreviation && awayTeamThumbnail"
|
||||||
|
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: awayTeamAbbreviation } }">
|
||||||
|
<img id="thumbnail" height="90" style="float:right; vertical-align:middle; max-height:100%;"
|
||||||
|
:src="awayTeamThumbnail" />
|
||||||
|
</RouterLink>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<h1 class="text-center">{{ finalScore }}</h1>
|
||||||
|
<h2 class="text-center">
|
||||||
|
Season {{ seasonNumber }} - Week {{ weekNumber }} - Game {{ gameNumber }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<RouterLink v-if="homeTeamAbbreviation && homeTeamThumbnail"
|
||||||
|
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: homeTeamAbbreviation } }">
|
||||||
|
<img id="thumbnail" height="90" style="float:right; vertical-align:middle; max-height:100%;"
|
||||||
|
:src="homeTeamThumbnail" />
|
||||||
|
</RouterLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Full Scorecard -->
|
||||||
|
<div class="row" id="scorecard">
|
||||||
|
|
||||||
|
<!-- Away Team -->
|
||||||
|
<div class="col-xl-6">
|
||||||
|
|
||||||
|
<!-- Away Batting -->
|
||||||
|
<h3 id="awayteam-batting-header">{{ awayTeamName }} Batting</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" id="away-batting">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>PA</th>
|
||||||
|
<th>AB</th>
|
||||||
|
<th>R</th>
|
||||||
|
<th>H</th>
|
||||||
|
<th>2B</th>
|
||||||
|
<th>3B</th>
|
||||||
|
<th>HR</th>
|
||||||
|
<th>RBI</th>
|
||||||
|
<th>SB</th>
|
||||||
|
<th>CS</th>
|
||||||
|
<th>BB</th>
|
||||||
|
<th>SO</th>
|
||||||
|
<th>GIDP</th>
|
||||||
|
<th>HBP</th>
|
||||||
|
<th>SAC</th>
|
||||||
|
<th>IBB</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="awayteam-batting-table">
|
||||||
|
<tr v-for="stat in awayTeamBattingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.pa }}</td>
|
||||||
|
<td>{{ stat.ab }}</td>
|
||||||
|
<td>{{ stat.run }}</td>
|
||||||
|
<td>{{ stat.hit }}</td>
|
||||||
|
<td>{{ stat.double }}</td>
|
||||||
|
<td>{{ stat.triple }}</td>
|
||||||
|
<td>{{ stat.hr }}</td>
|
||||||
|
<td>{{ stat.rbi }}</td>
|
||||||
|
<td>{{ stat.sb }}</td>
|
||||||
|
<td>{{ stat.cs }}</td>
|
||||||
|
<td>{{ stat.bb }}</td>
|
||||||
|
<td>{{ stat.so }}</td>
|
||||||
|
<td>{{ stat.gidp }}</td>
|
||||||
|
<td>{{ stat.hbp }}</td>
|
||||||
|
<td>{{ stat.sac }}</td>
|
||||||
|
<td>{{ stat.ibb }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Away Fielding -->
|
||||||
|
<h3 id="awayteam-fielding-header">{{ awayTeamName }} Fielding</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" style="max-width: 25rem" id="away-fielding">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>X-Ch</th>
|
||||||
|
<th>X-Hit</th>
|
||||||
|
<th>Error</th>
|
||||||
|
<th>PB</th>
|
||||||
|
<th>SBa</th>
|
||||||
|
<th>CSc</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="awayteam-fielding-table">
|
||||||
|
<tr v-for="stat in awayTeamFieldingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.xCheckCount }}</td>
|
||||||
|
<td>{{ stat.hit }}</td>
|
||||||
|
<td>{{ stat.error }}</td>
|
||||||
|
<td>{{ stat.passedBallCount }}</td>
|
||||||
|
<td>{{ stat.stolenBaseCheckCount }}</td>
|
||||||
|
<td>{{ stat.caughtStealingCount }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Away Pitching -->
|
||||||
|
<h3 id="awayteam-pitching-header">{{ awayTeamName }} Pitching</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" style="max-width: 50rem" id="away-pitching">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>W</th>
|
||||||
|
<th>L</th>
|
||||||
|
<th>SV</th>
|
||||||
|
<th>HD</th>
|
||||||
|
<th>BSV</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>H</th>
|
||||||
|
<th>R</th>
|
||||||
|
<th>ER</th>
|
||||||
|
<th>HR</th>
|
||||||
|
<th>BB</th>
|
||||||
|
<th>SO</th>
|
||||||
|
<th>HBP</th>
|
||||||
|
<th>BK</th>
|
||||||
|
<th>WP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="awayteam-pitching-table">
|
||||||
|
<tr v-for="stat in awayTeamPitchingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.win }}</td>
|
||||||
|
<td>{{ stat.loss }}</td>
|
||||||
|
<td>{{ stat.save }}</td>
|
||||||
|
<td>{{ stat.hold }}</td>
|
||||||
|
<td>{{ stat.bsave }}</td>
|
||||||
|
<td>{{ outsToInnings(stat) }}</td>
|
||||||
|
<td>{{ stat.hits }}</td>
|
||||||
|
<td>{{ stat.run }}</td>
|
||||||
|
<td>{{ stat.e_run }}</td>
|
||||||
|
<td>{{ stat.hr }}</td>
|
||||||
|
<td>{{ stat.bb }}</td>
|
||||||
|
<td>{{ stat.so }}</td>
|
||||||
|
<td>{{ stat.hbp }}</td>
|
||||||
|
<td>{{ stat.balk }}</td>
|
||||||
|
<td>{{ stat.wp }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Home Team -->
|
||||||
|
<div class="col-xl-6">
|
||||||
|
|
||||||
|
<!-- Home Batting -->
|
||||||
|
<h3 id="hometeam-batting-header">{{ homeTeamName }} Batting</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" id="home-batting">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>PA</th>
|
||||||
|
<th>AB</th>
|
||||||
|
<th>R</th>
|
||||||
|
<th>H</th>
|
||||||
|
<th>2B</th>
|
||||||
|
<th>3B</th>
|
||||||
|
<th>HR</th>
|
||||||
|
<th>RBI</th>
|
||||||
|
<th>SB</th>
|
||||||
|
<th>CS</th>
|
||||||
|
<th>BB</th>
|
||||||
|
<th>SO</th>
|
||||||
|
<th>GIDP</th>
|
||||||
|
<th>HBP</th>
|
||||||
|
<th>SAC</th>
|
||||||
|
<th>IBB</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="hometeam-batting-table">
|
||||||
|
<tr v-for="stat in homeTeamBattingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.pa }}</td>
|
||||||
|
<td>{{ stat.ab }}</td>
|
||||||
|
<td>{{ stat.run }}</td>
|
||||||
|
<td>{{ stat.hit }}</td>
|
||||||
|
<td>{{ stat.double }}</td>
|
||||||
|
<td>{{ stat.triple }}</td>
|
||||||
|
<td>{{ stat.hr }}</td>
|
||||||
|
<td>{{ stat.rbi }}</td>
|
||||||
|
<td>{{ stat.sb }}</td>
|
||||||
|
<td>{{ stat.cs }}</td>
|
||||||
|
<td>{{ stat.bb }}</td>
|
||||||
|
<td>{{ stat.so }}</td>
|
||||||
|
<td>{{ stat.gidp }}</td>
|
||||||
|
<td>{{ stat.hbp }}</td>
|
||||||
|
<td>{{ stat.sac }}</td>
|
||||||
|
<td>{{ stat.ibb }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Home Fielding -->
|
||||||
|
<h3 id="hometeam-fielding-header">{{ homeTeamName }} Fielding</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" style="max-width: 25rem" id="home-fielding">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>X-Ch</th>
|
||||||
|
<th>X-Hit</th>
|
||||||
|
<th>Error</th>
|
||||||
|
<th>PB</th>
|
||||||
|
<th>SBa</th>
|
||||||
|
<th>CSc</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="hometeam-fielding-table">
|
||||||
|
<tr v-for="stat in homeTeamFieldingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.xCheckCount }}</td>
|
||||||
|
<td>{{ stat.hit }}</td>
|
||||||
|
<td>{{ stat.error }}</td>
|
||||||
|
<td>{{ stat.passedBallCount }}</td>
|
||||||
|
<td>{{ stat.stolenBaseCheckCount }}</td>
|
||||||
|
<td>{{ stat.caughtStealingCount }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Home Pitching -->
|
||||||
|
<h3 id="hometeam-pitching-header">{{ homeTeamName }} Pitching</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table class="table table-sm table-striped" style="max-width: 50rem" id="home-pitching">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>W</th>
|
||||||
|
<th>L</th>
|
||||||
|
<th>SV</th>
|
||||||
|
<th>HD</th>
|
||||||
|
<th>BSV</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>H</th>
|
||||||
|
<th>R</th>
|
||||||
|
<th>ER</th>
|
||||||
|
<th>HR</th>
|
||||||
|
<th>BB</th>
|
||||||
|
<th>SO</th>
|
||||||
|
<th>HBP</th>
|
||||||
|
<th>BK</th>
|
||||||
|
<th>WP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="hometeam-pitching-table">
|
||||||
|
<tr v-for="stat in homeTeamPitchingStats" :key="stat.player.name">
|
||||||
|
<td>
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: stat.player.name } }">
|
||||||
|
{{ stat.player.name }}
|
||||||
|
</RouterLink>
|
||||||
|
</td>
|
||||||
|
<td>{{ stat.win }}</td>
|
||||||
|
<td>{{ stat.loss }}</td>
|
||||||
|
<td>{{ stat.save }}</td>
|
||||||
|
<td>{{ stat.hold }}</td>
|
||||||
|
<td>{{ stat.bsave }}</td>
|
||||||
|
<td>{{ outsToInnings(stat) }}</td>
|
||||||
|
<td>{{ stat.hits }}</td>
|
||||||
|
<td>{{ stat.run }}</td>
|
||||||
|
<td>{{ stat.e_run }}</td>
|
||||||
|
<td>{{ stat.hr }}</td>
|
||||||
|
<td>{{ stat.bb }}</td>
|
||||||
|
<td>{{ stat.so }}</td>
|
||||||
|
<td>{{ stat.hbp }}</td>
|
||||||
|
<td>{{ stat.balk }}</td>
|
||||||
|
<td>{{ stat.wp }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot></tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Game, Team } from '@/services/apiResponseTypes'
|
||||||
|
import { fetchBattingStatsBySeries, type BattingStat } from '@/services/battingStatsService'
|
||||||
|
import { fetchFieldingStatsBySeries, type FieldingStat } from '@/services/fieldingStatsService'
|
||||||
|
import { fetchSingleGame } from '@/services/gameService'
|
||||||
|
import { fetchPitchingStatsBySeries, type PitchingStat } from '@/services/pitchingStatsService'
|
||||||
|
import { fetchTeam } from '@/services/teamsService'
|
||||||
|
import { outsToInnings } from '@/services/utilities'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'GameView',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
team1: undefined as Team | undefined,
|
||||||
|
team2: undefined as Team | undefined,
|
||||||
|
game: undefined as Game | undefined,
|
||||||
|
battingStats: [] as BattingStat[],
|
||||||
|
pitchingStats: [] as PitchingStat[],
|
||||||
|
fieldingStats: [] as FieldingStat[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
seasonNumber: { type: Number, required: true },
|
||||||
|
weekNumber: { type: Number, required: true },
|
||||||
|
gameNumber: { type: Number, required: true },
|
||||||
|
team1Abbreviation: { type: String, required: true },
|
||||||
|
team2Abbreviation: { type: String, required: true }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
awayTeamThumbnail(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.away_team.thumbnail
|
||||||
|
},
|
||||||
|
homeTeamThumbnail(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.home_team.thumbnail
|
||||||
|
},
|
||||||
|
awayTeamAbbreviation(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.away_team.abbrev
|
||||||
|
},
|
||||||
|
homeTeamAbbreviation(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.home_team.abbrev
|
||||||
|
},
|
||||||
|
awayTeamName(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.away_team.sname
|
||||||
|
},
|
||||||
|
homeTeamName(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return this.game.home_team.sname
|
||||||
|
},
|
||||||
|
finalScore(): string {
|
||||||
|
if (!this.game) return ''
|
||||||
|
return `${this.awayTeamAbbreviation} ${this.game?.away_score} @ ${this.game?.home_score} ${this.homeTeamAbbreviation}`
|
||||||
|
},
|
||||||
|
homeTeamBattingStats(): BattingStat[] {
|
||||||
|
return this.battingStats.filter(bs => bs.game !== 'TOT'
|
||||||
|
&& bs.game.game_num === this.gameNumber
|
||||||
|
&& bs.team.abbrev === this.homeTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.pa - a.pa)
|
||||||
|
},
|
||||||
|
homeTeamPitchingStats(): PitchingStat[] {
|
||||||
|
return this.pitchingStats.filter(ps => ps.game !== 'TOT'
|
||||||
|
&& ps.game.game_num === this.gameNumber
|
||||||
|
&& ps.team.abbrev === this.homeTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.outs - a.outs)
|
||||||
|
},
|
||||||
|
homeTeamFieldingStats(): FieldingStat[] {
|
||||||
|
return this.fieldingStats.filter(fs => fs.game !== 'TOT'
|
||||||
|
&& fs.game.game_num === this.gameNumber
|
||||||
|
&& fs.team.abbrev === this.homeTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.xCheckCount - a.xCheckCount)
|
||||||
|
},
|
||||||
|
awayTeamBattingStats(): BattingStat[] {
|
||||||
|
return this.battingStats.filter(bs => bs.game !== 'TOT'
|
||||||
|
&& bs.game.game_num === this.gameNumber
|
||||||
|
&& bs.team.abbrev === this.awayTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.pa - a.pa)
|
||||||
|
},
|
||||||
|
awayTeamPitchingStats(): PitchingStat[] {
|
||||||
|
return this.pitchingStats.filter(ps => ps.game !== 'TOT'
|
||||||
|
&& ps.game.game_num === this.gameNumber
|
||||||
|
&& ps.team.abbrev === this.awayTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.outs - a.outs)
|
||||||
|
},
|
||||||
|
awayTeamFieldingStats(): FieldingStat[] {
|
||||||
|
return this.fieldingStats.filter(fs => fs.game !== 'TOT'
|
||||||
|
&& fs.game.game_num === this.gameNumber
|
||||||
|
&& fs.team.abbrev === this.awayTeamAbbreviation)
|
||||||
|
.sort((a, b) => b.xCheckCount - a.xCheckCount)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fetchData(): Promise<void> {
|
||||||
|
[this.team1, this.team2] = await Promise.all(
|
||||||
|
[fetchTeam(this.seasonNumber, this.team1Abbreviation), fetchTeam(this.seasonNumber, this.team2Abbreviation)])
|
||||||
|
|
||||||
|
if (!this.team1 || !this.team2) return
|
||||||
|
|
||||||
|
this.game = await fetchSingleGame(this.seasonNumber, this.weekNumber, this.gameNumber, this.team1.id, this.team2.id)
|
||||||
|
this.battingStats = await fetchBattingStatsBySeries(this.seasonNumber, this.weekNumber, this.team1.id, this.team2.id)
|
||||||
|
this.pitchingStats = await fetchPitchingStatsBySeries(this.seasonNumber, this.weekNumber, this.team1.id, this.team2.id)
|
||||||
|
this.fieldingStats = await fetchFieldingStatsBySeries(this.seasonNumber, this.weekNumber, this.team1.id, this.team2.id)
|
||||||
|
|
||||||
|
console.log(this.battingStats)
|
||||||
|
},
|
||||||
|
outsToInnings(stat: PitchingStat): string {
|
||||||
|
return outsToInnings(stat)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -160,7 +160,7 @@ export default {
|
|||||||
|
|
||||||
for (let week = 1; week <= 21; week++) {
|
for (let week = 1; week <= 21; week++) {
|
||||||
const weekStartDate = currentWeekStartDate
|
const weekStartDate = currentWeekStartDate
|
||||||
const weekEndDate = this.isLongSeries(week, weekStartDate)
|
const weekEndDate = this.isLongSeries(weekStartDate)
|
||||||
? currentWeekStartDate.add(13, 'd')
|
? currentWeekStartDate.add(13, 'd')
|
||||||
: currentWeekStartDate.add(6, 'd')
|
: currentWeekStartDate.add(6, 'd')
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ export default {
|
|||||||
async fetchData(): Promise<void> {
|
async fetchData(): Promise<void> {
|
||||||
this.weekGames = await fetchGamesBySeasonAndWeek(this.seasonNumber, this.selectedWeekNumber)
|
this.weekGames = await fetchGamesBySeasonAndWeek(this.seasonNumber, this.selectedWeekNumber)
|
||||||
},
|
},
|
||||||
isLongSeries(weekNumber: number, weekStartDate: dayjs.Dayjs): boolean {
|
isLongSeries(weekStartDate: dayjs.Dayjs): boolean {
|
||||||
// current 18-week schedule has 2 week series for any game week that falls
|
// current 18-week schedule has 2 week series for any game week that falls
|
||||||
// on the week of Thanksgiving or Christmas
|
// on the week of Thanksgiving or Christmas
|
||||||
return Math.abs(weekStartDate.diff(THANKSGIVING, 'days')) < 6
|
return Math.abs(weekStartDate.diff(THANKSGIVING, 'days')) < 6
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user