From e911801d15befde146d5b442783d9e74a3d9e620 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 15 Nov 2024 17:18:02 -0600 Subject: [PATCH 1/4] First pass at sorting player career stats table --- src/components/PlayerCareerPitchingTable.vue | 138 +++++++++++++------ 1 file changed, 99 insertions(+), 39 deletions(-) diff --git a/src/components/PlayerCareerPitchingTable.vue b/src/components/PlayerCareerPitchingTable.vue index 4e6c135..9361373 100644 --- a/src/components/PlayerCareerPitchingTable.vue +++ b/src/components/PlayerCareerPitchingTable.vue @@ -6,39 +6,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -116,6 +116,14 @@ import { hitsPer9, hrsPer9, outsToInnings, winPercentage } from '@/services/util interface PitchingStatWithSeason extends PitchingStat { seasonNumber: number isRegularSeason: boolean + + sortableSeason: string // constructed to sort S1 -> S1 Playoffs -> S2 -> etc + + // added for sortable table + winPct: string + irsPct: string + hPer9: string + hrPer9: string } export default { @@ -125,6 +133,12 @@ export default { postSeasonPitchingStats: { type: Array, required: true }, showPostSeasonStats: { type: Boolean, required: true } }, + data() { + return { + sortKey: 'sortableSeason' as keyof PitchingStatWithSeason, + sortOrder: 1 + } + }, computed: { hasPitchingStats(): boolean { return !!(this.regularSeasonPitchingStats.length + this.postSeasonPitchingStats.length) @@ -158,7 +172,12 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: true + isRegularSeason: true, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-A-Regular`, + winPct: this.winPercentage(stat), + irsPct: this.formatIRSPercentage(stat), + hPer9: this.hitsPer9(stat), + hrPer9: this.hrsPer9(stat) } })) } @@ -168,21 +187,47 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: false + isRegularSeason: false, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-B-Playoffs`, + winPct: this.winPercentage(stat), + irsPct: this.formatIRSPercentage(stat), + hPer9: this.hitsPer9(stat), + hrPer9: this.hrsPer9(stat) } })) } - return seasonStats.sort((s1, s2) => { - return s1.seasonNumber - s2.seasonNumber === 0 - ? s1.isRegularSeason - ? -1 - : 1 - : s1.seasonNumber - s2.seasonNumber - }) + return seasonStats.sort((s1, s2) => s2[this.sortKey] < s1[this.sortKey] ? this.sortOrder : -1 * this.sortOrder) + + // return seasonStats.sort((s1, s2) => { + // return s1.seasonNumber - s2.seasonNumber === 0 + // ? s1.isRegularSeason + // ? -1 + // : 1 + // : s1.seasonNumber - s2.seasonNumber + // }) }, }, methods: { + // setKey(stat: keyof PitchingStatWithSeason): void { + // this.setKey(stat) + + // this.pitchingStats.sort((s1, s2) => s2[stat] < s1[stat] ? this.sortOrder : -1 * this.sortOrder) + // }, + setKey(stat: keyof PitchingStatWithSeason): void { + if (this.sortKey === stat) { + // if key currently selected, flip sort order + this.sortOrder *= -1 + } else { + this.sortKey = stat + this.sortOrder = stat === 'sortableSeason' ? 1 : -1 + } + }, + getArrow(stat: keyof PitchingStatWithSeason): string { + if (this.sortKey !== stat) return 'faux-arrow' + + return this.sortOrder > 0 ? 'up' : 'down' + }, outsToInnings(stat: PitchingStat): string { return outsToInnings(stat) }, @@ -203,3 +248,18 @@ export default { } } + + From 62ce330d4286438cf34da8f81fbafd23051ba926 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 15 Nov 2024 17:24:29 -0600 Subject: [PATCH 2/4] Clean up comments, single quote component name --- src/components/PlayerBattingSummaryTable.vue | 2 +- src/components/PlayerCareerPitchingTable.vue | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/components/PlayerBattingSummaryTable.vue b/src/components/PlayerBattingSummaryTable.vue index 3d8f027..112f59c 100644 --- a/src/components/PlayerBattingSummaryTable.vue +++ b/src/components/PlayerBattingSummaryTable.vue @@ -74,7 +74,7 @@ import { aggregateBattingStats, type BattingStat } from '@/services/battingStats import type { PropType } from 'vue' export default { - name: "PlayerBattingSummaryTable", + name: 'PlayerBattingSummaryTable', props: { currentSeasonBatting: { type: Object as PropType, required: false }, currentPostSeasonBatting: { type: Object as PropType, required: false }, diff --git a/src/components/PlayerCareerPitchingTable.vue b/src/components/PlayerCareerPitchingTable.vue index 9361373..b7238b6 100644 --- a/src/components/PlayerCareerPitchingTable.vue +++ b/src/components/PlayerCareerPitchingTable.vue @@ -198,22 +198,9 @@ export default { } return seasonStats.sort((s1, s2) => s2[this.sortKey] < s1[this.sortKey] ? this.sortOrder : -1 * this.sortOrder) - - // return seasonStats.sort((s1, s2) => { - // return s1.seasonNumber - s2.seasonNumber === 0 - // ? s1.isRegularSeason - // ? -1 - // : 1 - // : s1.seasonNumber - s2.seasonNumber - // }) }, }, methods: { - // setKey(stat: keyof PitchingStatWithSeason): void { - // this.setKey(stat) - - // this.pitchingStats.sort((s1, s2) => s2[stat] < s1[stat] ? this.sortOrder : -1 * this.sortOrder) - // }, setKey(stat: keyof PitchingStatWithSeason): void { if (this.sortKey === stat) { // if key currently selected, flip sort order From 208cd09c62b80d134807ee60793aeac49be5fe47 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Nov 2024 08:51:25 -0600 Subject: [PATCH 3/4] Sortable player batting stats --- src/components/PlayerCareerBattingTable.vue | 109 +++++++++++++------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/src/components/PlayerCareerBattingTable.vue b/src/components/PlayerCareerBattingTable.vue index 026452f..deeb499 100644 --- a/src/components/PlayerCareerBattingTable.vue +++ b/src/components/PlayerCareerBattingTable.vue @@ -6,33 +6,33 @@
SeasonWLW-L%ERAGGSSVHDBSVIPHRERHRBBSOHBPBKWPIRIRSIRS%WHIPH/9HR/9BB/9SO/9SO/BBSeasonWLW-L%ERAGGSSVHDBSVIPHRERHRBBSOHBPBKWPIRIRSIRS%WHIPH/9HR/9BB/9SO/9SO/BB
S{{ stat.seasonNumber }}{{ stat.isRegularSeason ? '' : ' / Playoffs' }} {{ stat.win }} {{ stat.loss }}
- - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -109,6 +109,10 @@ import { aggregateBattingStats, type BattingStat } from '@/services/battingStats interface BattingStatWithSeason extends BattingStat { seasonNumber: number isRegularSeason: boolean + + sortableSeason: string // constructed to sort S1 -> S1 Playoffs -> S2 -> etc + + kPct: string } export default { @@ -118,6 +122,12 @@ export default { postSeasonBattingStats: { type: Array, required: true }, showPostSeasonStats: { type: Boolean, required: true } }, + data() { + return { + sortKey: 'sortableSeason' as keyof BattingStatWithSeason, + sortOrder: 1 + } + }, computed: { hasBattingStats(): boolean { return !!(this.regularSeasonBattingStats.length + this.postSeasonBattingStats.length) @@ -143,7 +153,9 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: true + isRegularSeason: true, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-A-Regular`, + kPct: this.calculateStrikeoutPercent(stat) } })) } @@ -153,21 +165,31 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: false + isRegularSeason: false, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-B-Playoffs`, + kPct: this.calculateStrikeoutPercent(stat) } })) } - return seasonStats.sort((s1, s2) => { - return s1.seasonNumber - s2.seasonNumber === 0 - ? s1.isRegularSeason - ? -1 - : 1 - : s1.seasonNumber - s2.seasonNumber - }) + return seasonStats.sort((s1, s2) => s2[this.sortKey] < s1[this.sortKey] ? this.sortOrder : -1 * this.sortOrder) }, }, methods: { + setKey(stat: keyof BattingStatWithSeason): void { + if (this.sortKey === stat) { + // if key currently selected, flip sort order + this.sortOrder *= -1 + } else { + this.sortKey = stat + this.sortOrder = stat === 'sortableSeason' ? 1 : -1 + } + }, + getArrow(stat: keyof BattingStatWithSeason): string { + if (this.sortKey !== stat) return 'faux-arrow' + + return this.sortOrder > 0 ? 'up' : 'down' + }, calculateStrikeoutPercent(stat: BattingStat): string { if (!stat.pa) return 'N/A' return (stat.so * 100 / stat.pa).toFixed(1) @@ -175,3 +197,18 @@ export default { } } + + From 6f93c01196b06b9da2c6f8e054418c55bd3b7cc8 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Nov 2024 09:04:52 -0600 Subject: [PATCH 4/4] Add sorting to career fielding table --- src/components/PlayerCareerFieldingTable.vue | 72 +++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/components/PlayerCareerFieldingTable.vue b/src/components/PlayerCareerFieldingTable.vue index f939e46..8962860 100644 --- a/src/components/PlayerCareerFieldingTable.vue +++ b/src/components/PlayerCareerFieldingTable.vue @@ -6,20 +6,20 @@
SeasonPAABRH2B3BHRRBISBCSBBSOBAOBPSLGOPSwOBAK%BPHRBPFOBP1BBPLOGIDPHBPSACIBBSeasonPAABRH2B3BHRRBISBCSBBSOBAOBPSLGOPSwOBAK%BPHRBPFOBP1BBPLOGIDPHBPSACIBB
- - - - - - - - - - + + + + + + + + + + - + @@ -33,7 +33,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -71,31 +71,23 @@ import { POS_MAP } from '@/services/utilities' interface FieldingStatWithSeason extends FieldingStat { seasonNumber: number isRegularSeason: boolean -} -function compareFieldingStats(s1: FieldingStatWithSeason, s2: FieldingStatWithSeason): number { - if (s1.seasonNumber - s2.seasonNumber !== 0) { - return s1.seasonNumber - s2.seasonNumber - } - - if (s1.isRegularSeason !== s2.isRegularSeason) { - return s1.isRegularSeason - ? -1 - : 1 - } - - // at this point stats are same season and also both regular or post season stats - // and must be sorted on position order - return POS_MAP[s1.pos] - POS_MAP[s2.pos] + sortableSeason: string // constructed to sort S1 -> S1 Playoffs -> S2 -> etc } export default { - name: "PlayerCareerFieldingTable", + name: 'PlayerCareerFieldingTable', props: { regularSeasonFieldingStats: { type: Array, required: true }, postSeasonFieldingStats: { type: Array, required: true }, showPostSeasonStats: { type: Boolean, required: true } }, + data() { + return { + sortKey: 'sortableSeason' as keyof FieldingStatWithSeason, + sortOrder: 1 + } + }, computed: { hasFieldingStats(): boolean { return !!(this.regularSeasonFieldingStats.length + this.postSeasonFieldingStats.length) @@ -125,7 +117,8 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: true + isRegularSeason: true, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-A-Regular-${POS_MAP[stat.pos]}` } })) } @@ -135,15 +128,30 @@ export default { return { ...stat, seasonNumber: stat.player.season, - isRegularSeason: false + isRegularSeason: false, + sortableSeason: `${`${stat.player.season}`.padStart(3, '0')}-B-Playoffs-${POS_MAP[stat.pos]}` } })) } - return seasonStats.sort(compareFieldingStats) + return seasonStats.sort((s1, s2) => s2[this.sortKey] < s1[this.sortKey] ? this.sortOrder : -1 * this.sortOrder) }, }, methods: { + setKey(stat: keyof FieldingStatWithSeason): void { + if (this.sortKey === stat) { + // if key currently selected, flip sort order + this.sortOrder *= -1 + } else { + this.sortKey = stat + this.sortOrder = stat === 'sortableSeason' ? 1 : -1 + } + }, + getArrow(stat: keyof FieldingStatWithSeason): string { + if (this.sortKey !== stat) return 'faux-arrow' + + return this.sortOrder > 0 ? 'up' : 'down' + }, formatCaughtStealingPercent(stat: FieldingStat): string { if (stat.stolenBaseCheckCount === 0 || Number.isNaN(stat.caughtStealingPercent)) { return '-'
SeasonPosXChXHEPBSBaCScCS%wF%SeasonPosXChXHEPBSBaCScCS%wF%
S{{ stat.seasonNumber }}{{ stat.isRegularSeason ? '' : ' / Playoffs' }} {{ stat.pos }} {{ stat.xCheckCount }}
Career {{ stat.pos }} {{ stat.xCheckCount }}{{ formatCaughtStealingPercent(stat) }} {{ formatWeightedFieldingPercent(stat) }}
Career / Playoffs {{ stat.pos }} {{ stat.xCheckCount }}