Add one rep max calculator for best graphs

I tried out a bunch of formulas as well as
having them as options, and I ended up liking
the Brzycki formula the most.
https://en.wikipedia.org/wiki/One-repetition_maximum#Brzycki
All of them produced similar trends (for me) and the one using
exponents wouldn't work with the SQLite version on android
(can't use POWER function). Also having all the options looked
kind of cluttered. If people ask for it I'll add the other ones
later.
This commit is contained in:
Brandon Presley 2022-10-16 13:39:59 +13:00
parent 0b041f9643
commit 3012b69e00
3 changed files with 40 additions and 8 deletions

View File

@ -11,7 +11,7 @@ import {FileSystem} from 'react-native-file-access';
import {IconButton} from 'react-native-paper';
import Share from 'react-native-share';
import {captureScreen} from 'react-native-view-shot';
import {getVolumes, getWeightsBy} from './best.service';
import {getOneRepMax, getVolumes, getWeightsBy} from './best.service';
import {BestPageParams} from './BestPage';
import Chart from './Chart';
import {PADDING} from './constants';
@ -59,12 +59,18 @@ export default function ViewBest() {
);
useEffect(() => {
if (metric === Metrics.Weight)
getWeightsBy(params.best.name, period).then(setWeights);
else if (metric === Metrics.Volume)
getVolumes(params.best.name, period).then(setVolumes);
console.log(`${ViewBest.name}.useEffect`, {metric});
console.log(`${ViewBest.name}.useEffect`, {period});
switch (metric) {
case Metrics.Weight:
getWeightsBy(params.best.name, period).then(setWeights);
break;
case Metrics.Volume:
getVolumes(params.best.name, period).then(setVolumes);
break;
default:
getOneRepMax({name: params.best.name, period}).then(setWeights);
}
}, [params.best.name, metric, period]);
return (
@ -76,6 +82,7 @@ export default function ViewBest() {
onValueChange={value => setMetric(value)}>
<Picker.Item value={Metrics.Volume} label={Metrics.Volume} />
<Picker.Item value={Metrics.Weight} label={Metrics.Weight} />
<Picker.Item value={Metrics.OneRepMax} label={Metrics.OneRepMax} />
</Picker>
<Picker
style={{color: dark ? 'white' : 'black'}}
@ -86,7 +93,7 @@ export default function ViewBest() {
<Picker.Item value={Periods.Monthly} label={Periods.Monthly} />
<Picker.Item value={Periods.Yearly} label={Periods.Yearly} />
</Picker>
{metric === Metrics.Volume && (
{metric === Metrics.Volume ? (
<Chart
yData={volumes.map(v => v.value)}
yFormat={(value: number) =>
@ -97,8 +104,7 @@ export default function ViewBest() {
xData={weights}
xFormat={(_value, index) => formatMonth(weights[index].created!)}
/>
)}
{metric === Metrics.Weight && (
) : (
<Chart
yData={weights.map(set => set.weight)}
yFormat={value => `${value}${weights[0].unit}`}

View File

@ -4,6 +4,31 @@ import Set from './set';
import {defaultSet} from './set.service';
import Volume from './volume';
export const getOneRepMax = async ({
name,
period,
}: {
name: string;
period: Periods;
}) => {
// Brzycki formula https://en.wikipedia.org/wiki/One-repetition_maximum#Brzycki
const select = `
SELECT max(weight / (1.0278 - 0.0278 * reps)) AS weight,
STRFTIME('%Y-%m-%d', created) as created, unit
FROM sets
WHERE name = ? AND NOT hidden
AND DATE(created) >= DATE('now', 'weekday 0', ?)
GROUP BY name, STRFTIME(?, created)
`;
let difference = '-7 days';
if (period === Periods.Monthly) difference = '-1 months';
else if (period === Periods.Yearly) difference = '-1 years';
let group = '%Y-%m-%d';
if (period === Periods.Yearly) group = '%Y-%m';
const [result] = await db.executeSql(select, [name, difference, group]);
return result.rows.raw();
};
export const getBestSet = async (name: string): Promise<Set> => {
const bestWeight = `
SELECT name, reps, unit, MAX(weight) AS weight

View File

@ -1,4 +1,5 @@
export enum Metrics {
Weight = 'Best weight per day',
Volume = 'Volume per day',
OneRepMax = 'One rep max',
}