From 3012b69e00daacb338c591477a751440047c0ff3 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Sun, 16 Oct 2022 13:39:59 +1300 Subject: [PATCH] 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. --- ViewBest.tsx | 22 ++++++++++++++-------- best.service.ts | 25 +++++++++++++++++++++++++ metrics.ts | 1 + 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/ViewBest.tsx b/ViewBest.tsx index cf59513..b76b59b 100644 --- a/ViewBest.tsx +++ b/ViewBest.tsx @@ -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)}> + - {metric === Metrics.Volume && ( + {metric === Metrics.Volume ? ( 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 && ( + ) : ( set.weight)} yFormat={value => `${value}${weights[0].unit}`} diff --git a/best.service.ts b/best.service.ts index 43eee49..8ff71af 100644 --- a/best.service.ts +++ b/best.service.ts @@ -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 => { const bestWeight = ` SELECT name, reps, unit, MAX(weight) AS weight diff --git a/metrics.ts b/metrics.ts index 0c2998b..cebda6f 100644 --- a/metrics.ts +++ b/metrics.ts @@ -1,4 +1,5 @@ export enum Metrics { Weight = 'Best weight per day', Volume = 'Volume per day', + OneRepMax = 'One rep max', }