diff --git a/src/views/LeaderboardView.vue b/src/views/LeaderboardView.vue index 844c9d0..1ea9de2 100644 --- a/src/views/LeaderboardView.vue +++ b/src/views/LeaderboardView.vue @@ -82,14 +82,23 @@ interface FlatFieldingStat { caughtStealingCount: number caughtStealingPercent: number passedBallCount: number + xCheckCountPitcher: number weightedFieldingPercentPitcher: number + xCheckCountCatcher: number weightedFieldingPercentCatcher: number + xCheckCountFirstBase: number weightedFieldingPercentFirstBase: number + xCheckCountSecondBase: number weightedFieldingPercentSecondBase: number + xCheckCountThirdBase: number weightedFieldingPercentThirdBase: number + xCheckCountShortstop: number weightedFieldingPercentShortstop: number + xCheckCountLeftField: number weightedFieldingPercentLeftField: number + xCheckCountCenterField: number weightedFieldingPercentCenterField: number + xCheckCountRightField: number weightedFieldingPercentRightField: number } @@ -118,7 +127,7 @@ export default { statMinimum(): string { if (this.statType == 'Batting') return `PA: ${this.plateAppearanceMinimum}` if (this.statType == 'Pitching') return `IP: ${this.inningsPitchedMinimum}` - return 'Coming Soon' + return `${Math.floor(this.weekNumberForCalcs * 2)}/${Math.floor(this.weekNumberForCalcs)}/${Math.floor(this.weekNumberForCalcs * 0.5)}/${Math.floor(this.weekNumberForCalcs * 0.25)}` }, plateAppearanceMinimum(): number { const MIN_PLATE_APPEARANCES_PER_GAME = 3 @@ -225,7 +234,7 @@ export default { { title: 'Passed Balls', columnName: 'PB', statPropertyName: 'passedBallCount' }, { title: 'Steal Attempts Against', columnName: 'SBa', statPropertyName: 'stolenBaseCheckCount' }, { title: 'Runners Thrown Out (C)', columnName: 'CSc', statPropertyName: 'caughtStealingCount' }, - { title: 'Caught Stealing % (C)', columnName: 'CS%', statPropertyName: 'caughtStealingPercent', precision: 1 }, + { title: 'Caught Stealing % (C)', columnName: 'CS%', statPropertyName: 'caughtStealingPercent', precision: 3 }, ] } }, @@ -270,18 +279,35 @@ export default { return statBase.sort((a, b) => sortMultiplier * ((b[stat] as number) - (a[stat] as number))).slice(0, 10) }, getTop10FieldingStatByCategory(stat: keyof FlatFieldingStat): FlatFieldingStat[] { - // High: 2B/SS - 2 XCh/wk - // Med: 1B/3B/CF - 1 XCh/wk - // Low: LF/RF/P/C - 0.5 XCh/wk + // High: 2B/SS - 2 XCh/wk + // Med: 1B/3B/CF - 1 XCh/wk + // Low: LF/RF/C - 0.5 XCh/wk + // X-Low: P - 0.25 XCh/wk const highXCheckGroup: (keyof FlatFieldingStat)[] = ['weightedFieldingPercentSecondBase', 'weightedFieldingPercentShortstop'] const mediumXCheckGroup: (keyof FlatFieldingStat)[] = ['weightedFieldingPercentFirstBase', 'weightedFieldingPercentThirdBase', 'weightedFieldingPercentCenterField'] - const lowXCheckGroup: (keyof FlatFieldingStat)[] = ['weightedFieldingPercentLeftField', 'weightedFieldingPercentRightField', 'weightedFieldingPercentCatcher', 'weightedFieldingPercentCatcher', 'weightedFieldingPercentPitcher'] + const lowXCheckGroup: (keyof FlatFieldingStat)[] = ['weightedFieldingPercentLeftField', 'weightedFieldingPercentRightField', 'weightedFieldingPercentCatcher', 'weightedFieldingPercentCatcher'] - const xCheckCountPerWeek = highXCheckGroup.includes(stat) ? 2 : mediumXCheckGroup.includes(stat) ? 1 : lowXCheckGroup.includes(stat) ? 0.5 : 0 + if ([...highXCheckGroup, ...mediumXCheckGroup, ...lowXCheckGroup, 'weightedFieldingPercentPitcher'].includes(stat)) { + const xCheckCountPerWeek = highXCheckGroup.includes(stat) ? 2 : mediumXCheckGroup.includes(stat) ? 1 : lowXCheckGroup.includes(stat) ? 0.5 : 0.25 + // need to regex check the wF% stat to the xcheckcount stat of the same position to check qualifiers + const position = stat.match(/weightedFieldingPercent(\w+)/) + if (!position?.length) return [] - return this.allPlayersFieldingStats - .filter(stat => stat.xCheckCount >= xCheckCountPerWeek * this.weekNumberForCalcs) - .sort((a, b) => ((b[stat] as number) - (a[stat] as number))).slice(0, 10) + // This is really guaranteed to be the following but I can't figure out how to make TS agree... + // 'xCheckCountPitcher' | 'xCheckCountCatcher' | 'xCheckCountFirstBase' | + // 'xCheckCountSecondBase' | 'xCheckCountThirdBase' | 'xCheckCountShortstop' | + // 'xCheckCountLeftField' | 'xCheckCountCenterField' | 'xCheckCountRightField' + const xCheckCountProperty = `xCheckCount${position[1]}` as keyof FlatFieldingStat + + return this.allPlayersFieldingStats.concat([]) + .filter(stat => (stat[xCheckCountProperty] as number) >= Math.floor(xCheckCountPerWeek * this.weekNumberForCalcs)) + .sort((a, b) => ((b[stat] as number) - (a[stat] as number))).slice(0, 10) + } + + // non-wF% stats currently won't have any qualifying minimum + return this.allPlayersFieldingStats.concat([]) + .sort((a, b) => ((b[stat] as number) - (a[stat] as number))) + .slice(0, 10) }, formatNumericalStat(stat: BattingStat | PitchingStat | FlatFieldingStat, property: keyof BattingStat | keyof PitchingStat | keyof FlatFieldingStat, precision: number): number | string { let numericalStat: number = 0 @@ -320,14 +346,23 @@ export default { caughtStealingCount: 0, caughtStealingPercent: 0, passedBallCount: 0, + xCheckCountPitcher: 0, weightedFieldingPercentPitcher: 0, + xCheckCountCatcher: 0, weightedFieldingPercentCatcher: 0, + xCheckCountFirstBase: 0, weightedFieldingPercentFirstBase: 0, + xCheckCountSecondBase: 0, weightedFieldingPercentSecondBase: 0, + xCheckCountThirdBase: 0, weightedFieldingPercentThirdBase: 0, + xCheckCountShortstop: 0, weightedFieldingPercentShortstop: 0, + xCheckCountLeftField: 0, weightedFieldingPercentLeftField: 0, + xCheckCountCenterField: 0, weightedFieldingPercentCenterField: 0, + xCheckCountRightField: 0, weightedFieldingPercentRightField: 0 } } @@ -337,9 +372,11 @@ export default { aggregatedFieldingStatsByPlayer[stat.player.name].error += stat.error if (stat.pos === 'P') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountPitcher = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentPitcher = stat.weightedFieldingPercent } else if (stat.pos === 'C') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountCatcher = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentCatcher = stat.weightedFieldingPercent // catchers have extra stats aggregatedFieldingStatsByPlayer[stat.player.name].stolenBaseCheckCount = stat.stolenBaseCheckCount @@ -349,28 +386,33 @@ export default { aggregatedFieldingStatsByPlayer[stat.player.name].passedBallCount = stat.passedBallCount } else if (stat.pos === '1B') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountFirstBase = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentFirstBase = stat.weightedFieldingPercent } else if (stat.pos === '2B') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountSecondBase = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentSecondBase = stat.weightedFieldingPercent } else if (stat.pos === '3B') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountThirdBase = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentThirdBase = stat.weightedFieldingPercent } else if (stat.pos === 'SS') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountShortstop = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentShortstop = stat.weightedFieldingPercent } else if (stat.pos === 'LF') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountLeftField = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentLeftField = stat.weightedFieldingPercent } else if (stat.pos === 'CF') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountCenterField = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentCenterField = stat.weightedFieldingPercent } else if (stat.pos === 'RF') { + aggregatedFieldingStatsByPlayer[stat.player.name].xCheckCountRightField = stat.xCheckCount aggregatedFieldingStatsByPlayer[stat.player.name].weightedFieldingPercentRightField = stat.weightedFieldingPercent } - - }) this.allPlayersFieldingStats = Object.values(aggregatedFieldingStatsByPlayer)