Compare commits
No commits in common. "bd164bff25aaeb95d56e6310b21d5abeae887f0e" and "37218e672e2fb763cae1b8d46f29359e3f68d945" have entirely different histories.
bd164bff25
...
37218e672e
|
|
@ -77,75 +77,46 @@ generateItems();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
|
||||||
<ion-label>hallo</ion-label>
|
|
||||||
</div>
|
|
||||||
<ion-list :inset="false">
|
<ion-list :inset="false">
|
||||||
<ion-item v-for="(bullpen, index) in items" :key="index" class="custom-item" lines="none" :button="true" :detail="false">
|
<ion-item v-for="(bullpen, index) in items" :key="index" class="custom-item" :button="true" :detail="false">
|
||||||
<!-- Top-left icon -->
|
<!-- Top-left icon -->
|
||||||
<ion-icon :icon="baseballOutline" slot="start" class="item-icon"></ion-icon>
|
<ion-icon :icon="baseballOutline" slot="start" class="item-icon"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<strong>{{formatDate(bullpen.startedAt)}}</strong>
|
<strong>{{formatDate(bullpen.startedAt)}}</strong>
|
||||||
<ion-label class="item-labels">
|
<ion-label class="item-labels">
|
||||||
<div class="stats-container">
|
|
||||||
<div class="stat-item" :style="{ '--progress': '57%' }">
|
|
||||||
<div class="stat-content">
|
|
||||||
<span class="percentage">57%</span>
|
|
||||||
<span class="label">Precision</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item" :style="{ '--progress': '77%' }">
|
|
||||||
<div class="stat-content">
|
|
||||||
<span class="percentage">77%</span>
|
|
||||||
<span class="label">Strike</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item" :style="{ '--progress': '33%' }">
|
|
||||||
<div class="stat-content">
|
|
||||||
<span class="percentage">33%</span>
|
|
||||||
<span class="label">Balls</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="stat-item" :style="{ '--progress': '45%' }">-->
|
|
||||||
<!-- <div class="stat-content">-->
|
|
||||||
<!-- <span class="percentage">45%</span>-->
|
|
||||||
<!-- <span class="label">Fastballs</span>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</div>
|
|
||||||
<!-- Horizontale Anordnung der Kreise -->
|
<!-- Horizontale Anordnung der Kreise -->
|
||||||
<!-- <div class="circle-container">-->
|
<div class="circle-container">
|
||||||
<!-- <div class="circle-wrapper">-->
|
<div class="circle-wrapper">
|
||||||
<!-- <div class="progress-circle" :class="percentageClass(57)">-->
|
<div class="progress-circle" :class="percentageClass(57)">
|
||||||
<!-- <span>{{ (0.57 * 100).toFixed(0) }}%</span>-->
|
<span>{{ (0.57 * 100).toFixed(0) }}%</span>
|
||||||
<!-- <div class="left-half-clipper">-->
|
<div class="left-half-clipper">
|
||||||
<!-- <div class="first50-bar"></div>-->
|
<div class="first50-bar"></div>
|
||||||
<!-- <div class="value-bar"></div>-->
|
<div class="value-bar"></div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <label>Precision</label>-->
|
<label>Precision</label>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <div class="circle-wrapper">-->
|
<div class="circle-wrapper">
|
||||||
<!-- <div class="progress-circle" :class="percentageClass(77)">-->
|
<div class="progress-circle" :class="percentageClass(77)">
|
||||||
<!-- <span>{{ (0.77 * 100).toFixed(0) }}%</span>-->
|
<span>{{ (0.77 * 100).toFixed(0) }}%</span>
|
||||||
<!-- <div class="left-half-clipper">-->
|
<div class="left-half-clipper">
|
||||||
<!-- <div class="first50-bar"></div>-->
|
<div class="first50-bar"></div>
|
||||||
<!-- <div class="value-bar"></div>-->
|
<div class="value-bar"></div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <label>Strike</label>-->
|
<label>Strike</label>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <div class="circle-wrapper">-->
|
<div class="circle-wrapper">
|
||||||
<!-- <div class="progress-circle" :class="percentageClass(33)">-->
|
<div class="progress-circle" :class="percentageClass(33)">
|
||||||
<!-- <span>{{ (0.33 * 100).toFixed(0) }}%</span>-->
|
<span>{{ (0.33 * 100).toFixed(0) }}%</span>
|
||||||
<!-- <div class="left-half-clipper">-->
|
<div class="left-half-clipper">
|
||||||
<!-- <div class="first50-bar"></div>-->
|
<div class="first50-bar"></div>
|
||||||
<!-- <div class="value-bar"></div>-->
|
<div class="value-bar"></div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <label>Balls</label>-->
|
<label>Balls</label>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<div class="metadata-end-wrapper" slot="end">
|
<div class="metadata-end-wrapper" slot="end">
|
||||||
|
|
@ -227,59 +198,4 @@ ion-label strong{
|
||||||
color: var(--ion-color-medium);
|
color: var(--ion-color-medium);
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: stretch;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 8px;
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-item {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: var(--ion-color-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-item::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: var(--progress);
|
|
||||||
background: var(--ion-color-primary);
|
|
||||||
opacity: 0.15;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-content {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.percentage {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ion-color-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--ion-color-medium);
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
// Migration 2: Remove columns from Users
|
|
||||||
/** @type {import('sequelize-cli').Migration} */
|
|
||||||
module.exports = {
|
|
||||||
async up(queryInterface, Sequelize) {
|
|
||||||
return Promise.all([
|
|
||||||
queryInterface.addColumn('BullpenSessions','precisionRate', {
|
|
||||||
type: Sequelize.INTEGER,
|
|
||||||
allowNull: false
|
|
||||||
}),
|
|
||||||
queryInterface.addColumn('BullpenSessions','strikeRate', {
|
|
||||||
type: Sequelize.INTEGER,
|
|
||||||
allowNull: false
|
|
||||||
}),
|
|
||||||
queryInterface.addColumn('BullpenSessions','ballRate', {
|
|
||||||
type: Sequelize.INTEGER,
|
|
||||||
allowNull: false
|
|
||||||
}),
|
|
||||||
queryInterface.addColumn('BullpenSessions','fastballRate', {
|
|
||||||
type: Sequelize.INTEGER,
|
|
||||||
allowNull: false
|
|
||||||
}),
|
|
||||||
queryInterface.addColumn('BullpenSessions','offSpeedRate', {
|
|
||||||
type: Sequelize.INTEGER,
|
|
||||||
allowNull: false
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
async down(queryInterface, Sequelize) {
|
|
||||||
return Promise.all([
|
|
||||||
queryInterface.removeColumn('BullpenSessions', 'precisionRate'),
|
|
||||||
queryInterface.removeColumn('BullpenSessions', 'strikeRate'),
|
|
||||||
queryInterface.removeColumn('BullpenSessions', 'ballRate'),
|
|
||||||
queryInterface.removeColumn('BullpenSessions', 'fastballRate'),
|
|
||||||
queryInterface.removeColumn('BullpenSessions', 'offSpeedRate')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -25,26 +25,6 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
finishedAt: {
|
finishedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
},
|
|
||||||
precisionRate: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
},
|
|
||||||
strikeRate: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
},
|
|
||||||
ballRate: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
},
|
|
||||||
fastballRate: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
},
|
|
||||||
offSpeedRate: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: false,
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
sequelize,
|
sequelize,
|
||||||
|
|
|
||||||
|
|
@ -10,53 +10,6 @@ const shouldMatch = (percentage) => {
|
||||||
return Math.random() * 100 < percentage;
|
return Math.random() * 100 < percentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateRates = (pitches) => {
|
|
||||||
const bullpenPitches = pitches.reduce((acc, pitch) => {
|
|
||||||
const { bullpenSessionId } = pitch;
|
|
||||||
if (!acc[bullpenSessionId]) {
|
|
||||||
acc[bullpenSessionId] = [];
|
|
||||||
}
|
|
||||||
acc[bullpenSessionId].push(pitch);
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const totalPitches = bullpenPitches.length;
|
|
||||||
if (totalPitches === 0) return {
|
|
||||||
precisionRate: 0,
|
|
||||||
strikeRate: 0,
|
|
||||||
ballRate: 0,
|
|
||||||
fastBallRate: 0,
|
|
||||||
offSpeedRate: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const counts = bullpenPitches.reduce((acc, pitch) => {
|
|
||||||
// Check if it's a strike (hitArea 1-9)
|
|
||||||
const isStrike = pitch.hitArea >= 1 && pitch.hitArea <= 9;
|
|
||||||
|
|
||||||
// Update counts based on conditions
|
|
||||||
acc.precision += pitch.aimedArea === pitch.hitArea ? 1 : 0;
|
|
||||||
acc.strikes += isStrike ? 1 : 0;
|
|
||||||
|
|
||||||
if (isStrike) {
|
|
||||||
if (pitch.pitchTypeId === 1) {
|
|
||||||
acc.fastballs += 1;
|
|
||||||
} else {
|
|
||||||
acc.offspeed += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, { precision: 0, strikes: 0, fastballs: 0, offspeed: 0 });
|
|
||||||
|
|
||||||
return {
|
|
||||||
precisionRate: (counts.precision / totalPitches) * 100,
|
|
||||||
strikeRate: (counts.strikes / totalPitches) * 100,
|
|
||||||
ballRate: ((totalPitches - counts.strikes) / totalPitches) * 100,
|
|
||||||
fastBallRate: (counts.fastballs / totalPitches) * 100,
|
|
||||||
offSpeedRate: (counts.offspeed / totalPitches) * 100
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const createBullpens = async (queryInterface, demoPlayer) => {
|
const createBullpens = async (queryInterface, demoPlayer) => {
|
||||||
const startDate = new Date();
|
const startDate = new Date();
|
||||||
// const endDate = new Date(new Date().setTime(startDate.getTime() + (10 * 60000)));
|
// const endDate = new Date(new Date().setTime(startDate.getTime() + (10 * 60000)));
|
||||||
|
|
@ -69,12 +22,7 @@ const createBullpens = async (queryInterface, demoPlayer) => {
|
||||||
startedAt: startedAt,
|
startedAt: startedAt,
|
||||||
finishedAt: new Date(new Date().setTime(startedAt.getTime() + (10 * 60000))),
|
finishedAt: new Date(new Date().setTime(startedAt.getTime() + (10 * 60000))),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date()
|
||||||
precisionRate: 0,
|
|
||||||
strikeRate: 0,
|
|
||||||
ballRate: 0,
|
|
||||||
fastBallRate: 0,
|
|
||||||
offSpeedRate: 0
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await queryInterface.bulkInsert('BullpenSessions', bullpens);
|
await queryInterface.bulkInsert('BullpenSessions', bullpens);
|
||||||
|
|
@ -116,11 +64,6 @@ const createBullpens = async (queryInterface, demoPlayer) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
await queryInterface.bulkInsert('Pitches', pitches.flat());
|
await queryInterface.bulkInsert('Pitches', pitches.flat());
|
||||||
|
|
||||||
const rates = calculateRates(pitches);
|
|
||||||
|
|
||||||
|
|
||||||
await queryInterface.update(null, 'BullpenSessions', bullpens.map(bullpen => {}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import('sequelize-cli').Migration} */
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@ const bullpenSession = {
|
||||||
pitcherId: 1,
|
pitcherId: 1,
|
||||||
startedAt: new Date(2025, 3, 22, 16, 5, 13),
|
startedAt: new Date(2025, 3, 22, 16, 5, 13),
|
||||||
finishedAt: new Date(2025, 3, 22, 16, 23, 45),
|
finishedAt: new Date(2025, 3, 22, 16, 23, 45),
|
||||||
precisionRate: 33,
|
|
||||||
strikeRate: 24,
|
|
||||||
ballRate: 76,
|
|
||||||
fastballRate: 55,
|
|
||||||
offSpeedRate: 78,
|
|
||||||
pitches: [{
|
pitches: [{
|
||||||
pitchTypeId: 1,
|
pitchTypeId: 1,
|
||||||
pitchTime: new Date(2025, 3, 22, 16, 7, 21),
|
pitchTime: new Date(2025, 3, 22, 16, 7, 21),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue