/** * Display data */ protected function setDataToCode() { $this->Code .= '<table class="fullwidth zebra-style">'; $this->Code .= '<thead><tr>'; $this->Code .= '<th></th>'; $this->Code .= '<th>' . __('Distance') . '</th>'; $this->Code .= '<th>' . __('Time') . '</th>'; $this->Code .= '<th>' . __('Swolf') . '</th>'; $this->Code .= '<th>' . __('Strokes') . '</th>'; $this->Code .= '<th>' . __('Type') . '</th>'; $this->Code .= '</tr></thead>'; $this->Code .= '<tbody>'; $Loop = new Swimdata\Loop($this->Context->swimdata()); $TrackLoop = new Trackdata\Loop($this->Context->trackdata()); $Stroketype = new Stroketype(Stroketype::FREESTYLE); $Distance = new Distance(0); $max = $Loop->num(); for ($i = 1; $i <= $max; ++$i) { $Stroketype->set($Loop->stroketype()); $Distance->set($TrackLoop->distance()); $this->Code .= '<tr class="r">'; $this->Code .= '<td>' . $i . '.</td>'; $this->Code .= '<td>' . $Distance->stringMeter() . '</td>'; $this->Code .= '<td>' . Duration::format($TrackLoop->difference(Trackdata\Object::TIME)) . '</td>'; $this->Code .= '<td>' . $Loop->swolf() . '</td>'; $this->Code .= '<td>' . $Loop->stroke() . '</td>'; $this->Code .= '<td>' . $Stroketype->shortstring() . '</td>'; $this->Code .= '</tr>'; $TrackLoop->nextStep(); $Loop->nextStep(); } $this->Code .= '</tbody>'; $this->Code .= '</table>'; }
/** * @return \Runalyze\Activity\Pace */ public function pace() { if (null == $this->LapPace) { $this->LapPace = new Pace($this->LapDuration->seconds(), $this->LapDistance->kilometer()); } return $this->LapPace; }
/** * Convert data */ private function convertData() { $totalTime = 0; $totalDist = 0; foreach ($this->Data as $Info) { $totalTime += $Info['time']; $totalDist += $Info['distance']; } foreach ($this->Data as $i => $Info) { if ($totalTime > 0) { $percentage = round(100 * $Info['time'] / $totalTime, 1); } elseif ($totalDist > 0) { $percentage = round(100 * $Info['distance'] / $totalDist, 1); } else { $percentage = '-'; } $this->Data[$i]['percentage'] = $percentage; $this->Data[$i]['time'] = $totalTime > 0 ? Duration::format($Info['time']) : '-'; $this->Data[$i]['distance'] = $totalDist > 0 ? Distance::format($Info['distance']) : '-'; } }
/** * Display additional columns * @param array $data */ protected function displayAdditionalColumns($data) { if ($this->AdditionalColumns) { $weekFactor = 52; $monthFactor = 12; if ($data['timerange'] == 0) { $weekFactor = (date('z') + 1) / 7; $monthFactor = (date('z') + 1) / 30.4; } elseif ($data['timerange'] == date('Y') - START_YEAR && date('Y', START_TIME) == START_YEAR) { $weekFactor = 53 - date("W", START_TIME); $monthFactor = 13 - date("n", START_TIME); } if ($data['distance'] > 0) { $weekString = Distance::format($data['distance'] / $weekFactor, true, 0) . __('/week'); $monthString = Distance::format($data['distance'] / $monthFactor, true, 0) . __('/month'); } else { $weekString = NBSP; $monthString = NBSP; } echo '<td class="small">' . $weekString . '<br>' . $monthString . '</td>'; } }
/** * Add tab for general statistics */ protected function addTabForGeneralStatistics() { $User = $this->FrontendSharedList->getUser(); $Stats = DB::getInstance()->query(' SELECT SUM(1) as num, SUM(distance) as dist_sum, SUM(s) as time_sum FROM `' . PREFIX . 'training` WHERE `accountid`="' . $User['id'] . '" GROUP BY `accountid` LIMIT 1 ')->fetch(); $Content = ' <table class="fullwidth"> <tbody> <tr> <td class="b">' . __('Total distance:') . '</td> <td>' . Distance::format($Stats['dist_sum']) . '</td> <td class="b">' . __('Number of activities:') . '</td> <td>' . $Stats['num'] . 'x</td> <td class="b">' . __('Registered since:') . '</td> <td>' . date('d.m.Y', $User['registerdate']) . '</td> </tr> <tr> <td class="b">' . __('Total duration:') . '</td> <td>' . Duration::format($Stats['time_sum']) . '</td> <td class="b">' . __('First activity:') . '</td> <td>' . date('d.m.Y', START_TIME) . '</td> <td class="b">' . __('Last login:'******'</td> <td>' . date('d.m.Y', $User['lastaction']) . '</td> </tr> </tbody> </table>'; $this->StatisticTabs->addTab(__('General statistics'), 'statistics-general', $Content); }
/** * Display the table with summed data for every month */ private function displayData() { echo '<table class="analysis-table fullwidth zebra-style r">'; echo '<thead>' . HTML::monthTr(8, 1) . '</thead>'; echo '<tbody>'; if (empty($this->KmData)) { echo '<tr><td colspan="13" class="c"><em>' . __('No activities found.') . '</em></td></tr>'; } foreach ($this->KmData as $y => $Data) { echo '<tr><td class="b l">' . $y . '</td>'; for ($m = 1; $m <= 12; $m++) { if (isset($Data[$m])) { if ($this->dat == 'km') { echo '<td title="' . Distance::format($Data[$m]['distance']) . '">' . Distance::format($Data[$m]['distance']) . $this->getCircleFor(100 * $Data[$m]['distance'] / $this->maxKm) . '</td>'; //echo '<td style="vertical-align: bottom;">' . $tooltip . $circle . '</td>'; } else { if ($this->dat == 's') { echo '<td title="' . $Data[$m]['s'] . '">' . Duration::format($Data[$m]['s']) . $this->getCircleFor(100 * $Data[$m]['s'] / $this->maxs) . '</td>'; } else { if ($this->dat == 'em') { echo '<td title="' . Elevation::format($Data[$m]['elevation']) . '">' . Elevation::format($Data[$m]['elevation']) . $this->getCircleFor(100 * $Data[$m]['elevation'] / $this->maxEm) . '</td>'; } else { if ($this->dat == 'kcal') { echo '<td title="' . $Data[$m]['kcal'] . ' kcal">' . $Data[$m]['kcal'] . ' kcal' . $this->getCircleFor(100 * $Data[$m]['kcal'] / $this->maxKcal) . '</td>'; } else { if ($this->dat == 'trimp') { echo '<td title="' . $Data[$m]['trimp'] . '">' . $Data[$m]['trimp'] . $this->getCircleFor(100 * $Data[$m]['trimp'] / $this->maxTrimp) . '</td>'; } else { if ($this->dat == 'n') { echo '<td title="' . $Data[$m]['n'] . '">' . $Data[$m]['n'] . $this->getCircleFor(100 * $Data[$m]['n'] / $this->maxN) . '</td>'; } } } } } } } else { echo HTML::emptyTD(); } } echo '</tr>'; } echo '</tbody></table>'; }
/** * Parse post data for equipment */ protected function parsePostDataForSingleEquipment() { $DB = DB::getInstance(); $accountId = SessionAccountHandler::getId(); $Equipments = $this->Model->allEquipments(); $Equipments[] = new Equipment\Entity(); foreach ($Equipments as $Equipment) { $isNew = !$Equipment->hasID(); $id = $isNew ? -1 : $Equipment->id(); $AdditionalDistance = new Distance(); $AdditionalDistance->setInPreferredUnit($_POST['equipment']['additional_km'][$id]); $NewEquipment = clone $Equipment; $NewEquipment->set(Equipment\Entity::NAME, $_POST['equipment']['name'][$id]); $NewEquipment->set(Equipment\Entity::TYPEID, (int) $_POST['equipment']['typeid'][$id]); $NewEquipment->set(Equipment\Entity::ADDITIONAL_KM, $AdditionalDistance->kilometer()); $NewEquipment->set(Equipment\Entity::DATE_START, $this->stringToDatetime($_POST['equipment']['date_start'][$id])); $NewEquipment->set(Equipment\Entity::DATE_END, $this->stringToDatetime($_POST['equipment']['date_end'][$id])); $NewEquipment->set(Equipment\Entity::NOTES, $_POST['equipment']['notes'][$id]); if ($isNew) { if ($NewEquipment->name() != '') { $Inserter = new Equipment\Inserter($DB, $NewEquipment); $Inserter->setAccountID($accountId); $Inserter->insert(); } } elseif (isset($_POST['equipment']['delete'][$id])) { $DB->deleteByID('equipment', (int) $id); } else { $Updater = new Equipment\Updater($DB, $NewEquipment, $Equipment); $Updater->setAccountID($accountId); $Updater->update(); } } $this->Model->clearCache('equipment'); }
/** * Display comparison for all years for personal bests */ private function displayPersonalBestYears() { $year = array(); $dists = array(); $kms = is_array($this->Configuration()->value('pb_distances')) ? $this->Configuration()->value('pb_distances') : array(3, 5, 10, 21.1, 42.2); foreach ($kms as $km) { $dists[$km] = array('sum' => 0, 'pb' => INFINITY); } if ($this->RaceContainer->num() == 0) { return; } foreach ($this->RaceContainer->allRaces() as $wk) { $wk['y'] = date('Y', $wk['time']); if (!isset($year[$wk['y']])) { $year[$wk['y']] = $dists; $year[$wk['y']]['sum'] = 0; $year['sum'] = 0; } $year[$wk['y']]['sum']++; foreach ($kms as $km) { if ($km == $wk['distance']) { $year[$wk['y']][$km]['sum']++; if ($wk['s'] < $year[$wk['y']][$km]['pb']) { $year[$wk['y']][$km]['pb'] = $wk['s']; } } } } echo '<table class="fullwidth zebra-style">'; echo '<thead>'; echo '<tr>'; echo '<th></th>'; $Years = array_keys($year); sort($Years); foreach ($Years as $y) { if ($y != 'sum') { echo '<th>' . $y . '</th>'; } } echo '</tr>'; echo '</thead>'; echo '<tbody>'; PersonalBest::activateStaticCache(); PersonalBest::lookupDistances($kms); foreach ($kms as $i => $km) { echo '<tr class="r"><td class="b">' . Distance::format($km, $km <= 3, 1) . '</td>'; foreach ($Years as $key) { $y = $year[$key]; if ($key != 'sum') { if ($y[$km]['sum'] != 0) { $PB = new PersonalBest($km); $distance = Duration::format($y[$km]['pb']); if ($PB->seconds() == $y[$km]['pb']) { $distance = '<strong>' . $distance . '</strong>'; } echo '<td>' . $distance . ' <small>' . $y[$km]['sum'] . 'x</small></td>'; } else { echo '<td><em><small>---</small></em></td>'; } } } echo '</tr>'; } echo '<tr class="top-spacer no-zebra r">'; echo '<td class="b">' . __('In total') . '</td>'; foreach ($Years as $key) { if ($key != 'sum') { $y = $year[$key]; echo '<td>' . $year[$key]['sum'] . 'x</td>'; } } echo '</tr>'; echo '</tbody>'; echo '</table>'; }
/** * Get distance * @return string */ public function distance($decimals = null) { if (is_null($decimals)) { $decimals = Configuration::ActivityView()->decimals(); } if ($this->Activity->distance() > 0) { if ($this->Activity->isTrack()) { return (new Distance($this->Activity->distance()))->stringMeter(); } return Distance::format($this->Activity->distance(), true, $decimals); } return ''; }
/** * Init calculations */ protected function runCalculations() { foreach ($this->Distances as $km) { $Prognosis = $this->PrognosisObject->inSeconds($km); $PB = new PersonalBest($km, DB::getInstance(), false); $PB->lookupWithDetails(); $VDOTprognosis = new VDOT(); $VDOTprognosis->fromPace($km, $Prognosis); $VDOTpb = new VDOT(); $VDOTpb->fromPace($km, $PB->seconds()); $PacePrognosis = new Pace($Prognosis, $km, Pace::MIN_PER_KM); $PacePB = new Pace($PB->seconds(), $km, Pace::MIN_PER_KM); $DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true); $this->Prognoses[] = array('distance' => Distance::format($km, $km <= 3), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-'); } }
/** * Add icon for current pause */ protected function addCurrentPauseIcon() { $Pause = $this->Trackdata->pauses()->at($this->PauseIndex); $Index = $this->RouteLoop->index(); $Tooltip = sprintf(__('<strong>Pause</strong> of %s'), Duration::format($Pause->duration())); $Tooltip .= '<br>' . sprintf(__('<strong>Distance:</strong> %s'), Distance::format($this->Trackdata->at($Index, Trackdata\Entity::DISTANCE))); $Tooltip .= '<br>' . sprintf(__('<strong>Time:</strong> %s'), Duration::format($this->Trackdata->at($Index, Trackdata\Entity::TIME))); if ($Pause->hasHeartRateInfo()) { $Tooltip .= '<br>' . sprintf(__('<strong>Heart rate:</strong>') . ' ' . __('%s to %s'), $Pause->hrStart(), $Pause->hrEnd() . ' bpm'); } $this->addMarkerGeohash($this->Route->at($Index, Route\Entity::GEOHASHES), $this->pauseIcon(), $Tooltip); }
/** * Display table */ public function displayTable() { if (is_null($this->Equipment)) { $this->initTableData(); } echo '<table id="list-of-all-equipment" class="fullwidth zebra-style"> <thead> <tr> <th class="{sorter: \'x\'} small">' . __('x-times') . '</th> <th>' . __('Name') . '</th> <th class="{sorter: \'germandate\'} small">' . __('since') . '</th> <th class="{sorter: \'distance\'}">Ø ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th> <th>Ø ' . __('Pace') . '</th> <th class="{sorter: \'distance\'} small"><small>' . __('max.') . '</small> ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th> <th class="small"><small>' . __('min.') . '</small> ' . __('Pace') . '</th> <th class="{sorter: \'resulttime\'}">' . __('Time') . '</th> <th class="{sorter: \'distance\'}">' . __('Distance') . '</th> <th>' . __('Notes') . '</th> </tr> </thead> <tbody>'; if (!empty($this->Equipment)) { foreach ($this->Equipment as $data) { $Object = new Model\Equipment\Object($data); $in_use = $Object->isInUse() ? '' : ' unimportant'; $Pace = new Pace($Object->duration(), $Object->distance()); $MaxPace = new Pace($data['pace_in_s'], 1); echo '<tr class="' . $in_use . ' r" style="position: relative"> <td class="small">' . $data['num'] . 'x</td> <td class="b l">' . SearchLink::to('equipmentid', $Object->id(), $Object->name()) . '</td> <td class="small">' . $this->formatData($Object->startDate()) . '</td> <td>' . ($data['num'] != 0 ? Distance::format($Object->distance() / $data['num']) : '-') . '</td> <td>' . ($Object->duration() > 0 ? $Pace->asMinPerKm() . '/km' : '-') . '</td> <td class="small">' . Distance::format($data['dist']) . '</td> <td class="small">' . $MaxPace->asMinPerKm() . '/km' . '</td> <td>' . Duration::format($Object->duration()) . '</td> <td>' . Distance::format($Object->totalDistance()) . '</td> <td class="small">' . $Object->notes() . '</td> </tr>'; } } else { echo '<tr><td colspan="9">' . __('You don\'t have any shoes') . '</td></tr>'; } echo '</tbody>'; echo '</table>'; Ajax::createTablesorterFor("#list-of-all-equipment", true); }
/** * Distance * @return string */ public function distance() { return Distance::format($this->Activity->distance()); }
/** * Display routes */ private function displayRoutes() { if ($this->Configuration()->value('analyze_cities')) { echo '<table style="width:70%;" class="left zebra-style">'; } else { echo '<table style="width:100%;" class="zebra-style">'; } echo '<thead><tr><th colspan="3">' . __('Most frequent routes') . '</th></tr></thead>'; echo '<tbody class="r">'; $i = 0; $statement = DB::getInstance()->query(' SELECT `' . PREFIX . 'route`.`name`, SUM(`' . PREFIX . 'training`.`distance`) as `km`, SUM(1) as `num` FROM `' . PREFIX . 'training` LEFT JOIN `' . PREFIX . 'route` ON `' . PREFIX . 'training`.`routeid`=`' . PREFIX . 'route`.`id` WHERE 1 ' . $this->getSportAndYearDependenceForQuery() . ' AND `' . PREFIX . 'training`.`accountid`=' . SessionAccountHandler::getId() . ' AND `routeid`!=0 AND `name`!="" GROUP BY `name` ORDER BY `num` DESC LIMIT 10'); while ($data = $statement->fetch()) { echo '<tr> <td>' . $data['num'] . 'x</td> <td class="l">' . SearchLink::to('route', $data['name'], Helper::Cut($data['name'], 100)) . '</td> <td>' . Distance::format($data['km']) . '</td> </tr>'; $i++; } echo '</tbody>'; echo '</table>'; }
<?php use Runalyze\Activity\Duration; use Runalyze\Activity\Distance; $Duration = new Duration(); ?> <table id="jd-tables-prognosis" class="zebra-style r" style="width: 700px;"> <thead> <tr> <?php foreach ($this->Configuration()->value('pace_distances') as $km) { ?> <th><?php echo Distance::format($km, $km <= 3, 1); ?> </th> <?php } ?> </tr> </thead> <tbody> <?php foreach ($this->Range as $sPer400m) { ?> <tr> <?php foreach ($this->Configuration()->value('pace_distances') as $km) { ?> <?php $Duration->fromSeconds($km * $sPer400m / 0.4);
`typeid`="' . Configuration::General()->competitionType() . '" AND `distance`="' . $distance . '" ORDER BY `time` ASC')->fetchAll(); Cache::set('prognosePlotDistanceData' . $distance, $ResultsData, '600'); } foreach ($ResultsData as $dat) { if (!isset($WKplugin) || !$WKplugin->isFunCompetition($dat['id'])) { $Results[$dat['time'] . '000'] = $dat['s'] * 1000; } } } else { $DataFailed = true; } $Plot = new Plot("formverlauf_" . str_replace('.', '_', $distance), 800, 450); $Plot->Data[] = array('label' => __('Prognosis'), 'color' => '#880000', 'data' => $Prognosis, 'lines' => array('show' => true), 'points' => array('show' => false)); $Plot->Data[] = array('label' => __('Result'), 'color' => '#000000', 'data' => $Results, 'lines' => array('show' => false), 'points' => array('show' => true), 'curvedLines' => array('apply' => false)); $Plot->setZeroPointsToNull(); $Plot->setMarginForGrid(5); $Plot->setXAxisAsTime(); $Plot->addYAxis(1, 'left'); if (!empty($Prognosis) && max($Prognosis) > 1000 * 3600) { $Plot->setYAxisTimeFormat('%H:%M:%S'); } else { $Plot->setYAxisTimeFormat('%M:%S'); } $Plot->setTitle(__('Prognosis trend') . ' ' . Distance::format($distance)); if ($DataFailed || empty($Data)) { $Plot->raiseError(__('No data available.')); } $Plot->outputJavaScript();
/** * Initialize line-data-array for 'KM' * @param array $dat */ private function initKMData($dat) { $WeekFactor = 52; $MonthFactor = 12; if ($dat['i'] == date("Y")) { $WeekFactor = (date('z') + 1) / 7; $MonthFactor = (date('z') + 1) / 30.4; } elseif ($dat['i'] == date('Y') + 1) { $WeekFactor = ceil((time() - START_TIME) / DAY_IN_S / 7); $MonthFactor = ceil((time() - START_TIME) / DAY_IN_S / 30.4); } elseif ($dat['i'] == START_YEAR && date("0", START_TIME) == START_YEAR) { $WeekFactor = 53 - date("W", START_TIME); $MonthFactor = 13 - date("n", START_TIME); } $text = $dat['distance'] == 0 ? NBSP : Distance::format($dat['distance'], false, 0); $textWeek = $dat['distance'] == 0 ? NBSP : Distance::format($dat['distance'] / $WeekFactor, false, 0); $textMonth = $dat['distance'] == 0 ? NBSP : Distance::format($dat['distance'] / $MonthFactor, false, 0); $this->KMData[] = array('i' => $dat['i'], 'text' => $text); $this->KMDataWeek[] = array('i' => $dat['i'], 'text' => $textWeek); $this->KMDataMonth[] = array('i' => $dat['i'], 'text' => $textMonth); }
/** * Set default values */ protected function setDefaultValues() { $Strategy = new Prognosis\Bock(); $TopResults = $Strategy->getTopResults(2); $CurrentShape = Configuration::Data()->vdotShape(); if (empty($_POST)) { $Factory = new PluginFactory(); $Plugin = $Factory->newInstance('RunalyzePluginPanel_Prognose'); $_POST['model'] = 'jack-daniels'; $_POST['distances'] = implode(', ', $Plugin->getDistances()); $_POST['vdot'] = $CurrentShape; $_POST['endurance'] = true; $_POST['endurance-value'] = BasicEndurance::getConst(); $_POST['best-result-km'] = !empty($TopResults) ? $TopResults[0]['distance'] : '5.0'; $_POST['best-result-time'] = !empty($TopResults) ? Duration::format($TopResults[0]['s']) : '0:26:00'; $_POST['second-best-result-km'] = !empty($TopResults) ? $TopResults[1]['distance'] : '10.0'; $_POST['second-best-result-time'] = !empty($TopResults) ? Duration::format($TopResults[1]['s']) : '1:00:00'; } $this->InfoLines['jack-daniels'] = __('Your current VDOT:') . ' ' . $CurrentShape . '. '; $this->InfoLines['jack-daniels'] .= __('Your current basic endurance:') . ' ' . BasicEndurance::getConst() . '.'; $ResultLine = empty($TopResults) ? __('none') : sprintf(__('%s in %s <small>(%s)</small> and %s in %s <small>(%s)</small>'), Distance::format($TopResults[0]['distance']), Duration::format($TopResults[0]['s']), date('d.m.Y', $TopResults[0]['time']), Distance::format($TopResults[1]['distance']), Duration::format($TopResults[1]['s']), date('d.m.Y', $TopResults[1]['time'])); $this->InfoLines['robert-bock'] = __('Your two best results:') . ' ' . $ResultLine; $this->setupJackDanielsStrategy(); $this->setupBockStrategy(); $this->setupSteffnyStrategy(); $this->setupCameronStrategy(); }
/** * Get fieldset for basic endurance * @return \FormularFieldset */ public function getFieldsetBasicEndurance() { $BasicEndurance = new BasicEndurance(); $BasicEndurance->readSettingsFromConfiguration(); $BEresults = $BasicEndurance->asArray(); $Strategy = new Prognosis\Daniels(); $Strategy->setupFromDatabase(); $Strategy->adjustVDOT(false); $Prognosis = new Prognosis\Prognosis(); $Prognosis->setStrategy($Strategy); $GeneralTable = ' <table class="fullwidth zebra-style"> <tbody class="top-and-bottom-border"> <tr> <td>' . __('<strong>Current VDOT</strong> <small>(based on heart rate)</small>') . '</td> <td class="r">' . round(Configuration::Data()->vdot(), 2) . '</td> <td> </td> <td>' . sprintf(__('<strong>Target kilometer per week</strong> <small>(%s weeks)</small>'), round($BasicEndurance->getDaysForWeekKm() / 7)) . '</td> <td class="r">' . Distance::format($BasicEndurance->getTargetWeekKm(), false, 0) . '</td> <td class="small">' . sprintf(__('done by %s%'), round(100 * $BEresults['weekkm-percentage'])) . '</td> <td class="small">(ø ' . Distance::format($BEresults['weekkm-result'] / $BasicEndurance->getDaysForWeekKm() * 7, false, 0) . ')</td> <td class="small">x' . $BasicEndurance->getPercentageForWeekKilometer() . '</td> <td rowspan="2" class="bottom-spacer b" style="vertical-align:middle;">= ' . round($BEresults['percentage']) . '%</td> </tr> <tr> <td>' . __('<strong>Marathon time</strong> <small>(optimal)</small>') . '</td> <td class="r">' . Duration::format($Prognosis->inSeconds(42.195)) . '</td> <td> </td> <td>' . sprintf(__('<strong>Target long run</strong> <small>(%s weeks)</small>'), round($BasicEndurance->getDaysToRecognizeForLongjogs() / 7)) . '</td> <td class="r">' . Distance::format($BasicEndurance->getRealTargetLongjogKmPerWeek(), false, 0) . '</td> <td class="small">' . sprintf(__('done by %s%'), round(100 * $BEresults['longjog-percentage'])) . '</td> <td class="small">(' . round($BEresults['longjog-result'], 1) . ' points)</td> <td class="small">x' . $BasicEndurance->getPercentageForLongjogs() . '</td> </tr> </tbody> </table>'; $LongjogTable = '<table class="fullwidth zebra-style c"> <thead> <tr> <th>' . __('Date') . '*</th> <th>' . __('Distance') . '</th> <th>' . __('Points') . '</th> </tr> </thead> <tbody>'; $IgnoredLongjogs = 0; $Longjogs = DB::getInstance()->query($BasicEndurance->getQuery(0, true))->fetchAll(); foreach ($Longjogs as $Longjog) { if ($Longjog['points'] >= 0.2) { $LongjogTable .= '<tr> <td>' . Ajax::trainingLink($Longjog['id'], date('d.m.Y', $Longjog['time'])) . '</td> <td>' . Distance::format($Longjog['distance']) . '</td> <td>' . round($Longjog['points'], 1) . ' points</td> </tr>'; } else { $IgnoredLongjogs++; } } $LongjogTable .= '<tr class="top-spacer no-zebra"> <td></td> <td></td> <td class="b">= ' . round($BEresults['longjog-result'], 1) . ' points</td> </tr> </tbody> </table>'; $LongjogTable .= '<p class="small">' . sprintf(__('* %s "long" jogs do not show up, ' . 'because they have less than 0.2 points.'), $IgnoredLongjogs) . '</p>'; $LongjogTable .= '<p class="small">' . sprintf(__('* In general, all runs with more than %s are being considered.'), Distance::format($BasicEndurance->getMinimalDistanceForLongjogs())) . '</p>'; $Fieldset = new FormularFieldset(__('Basic endurance')); $Fieldset->addBlock(__('Your basic endurance is based on your weekly kilometers and your long jogs.<br>' . 'The target is derived from the possible marathon time based on your current shape.') . '<br> '); $Fieldset->addBlock($GeneralTable); $Fieldset->addBlock(__('The points for your long runs are weighted by time and quadratic in distance. ' . 'That means, a long jog yesterday gives more points than a long jog two weeks ago ' . 'and a 30k-jog gives more points than two 20k-jogs.') . '<br> '); $Fieldset->addBlock($LongjogTable); $Fieldset->addBlock(__('The basic endurance is <strong>not</strong> from Jack Daniels.<br>' . 'It\'s our own attempt to adjust the prognosis for long distances based on your current endurance.')); return $Fieldset; }
/** * Subtract another distance * @param \Runalyze\Activity\Distance $object * @return \Runalyze\Activity\Distance $this-reference */ public function subtract(Distance $object) { $this->Kilometer -= $object->kilometer(); return $this; }
/** * Display table */ public function displayTable() { if (is_null($this->schuhe)) { $this->initTableData(); } echo '<table id="list-of-all-shoes" class="fullwidth zebra-style"> <thead> <tr> <th class="{sorter: \'x\'} small">' . __('x-times') . '</th> <th class="{sorter: false}"></th> <th>' . __('Name') . '</th> <th class="{sorter: \'germandate\'} small">' . __('since') . '</th> <th class="{sorter: \'distance\'}">Ø km</th> <th>Ø ' . __('Pace') . '</th> <th class="{sorter: \'distance\'} small"><small>' . __('max.') . '</small> km</th> <th class="small"><small>' . __('min.') . '</small> ' . __('Pace') . '</th> <th class="{sorter: \'resulttime\'}">' . __('Time') . '</th> <th class="{sorter: \'distance\'}">' . __('Distance') . '</th> <th>' . __('Weight') . '</th> </tr> </thead> <tbody>'; if (!empty($this->schuhe)) { foreach ($this->schuhe as $schuh) { $Shoe = new Shoe($schuh); $in_use = $Shoe->isInUse() ? '' : ' unimportant'; $Pace = new Pace($Shoe->getTime(), $Shoe->getKmInDatabase()); $MaxPace = new Pace($schuh['pace_in_s'], 1); echo '<tr class="' . $in_use . ' r" style="position: relative"> <td class="small">' . $schuh['num'] . 'x</td> <td>' . $this->editLinkFor($schuh['id']) . '</td> <td class="b l">' . ShoeFactory::getSearchLink($schuh['id']) . '</td> <td class="small">' . $Shoe->getSince() . '</td> <td>' . ($schuh['num'] != 0 ? Distance::format($Shoe->getKmInDatabase() / $schuh['num']) : '-') . '</td> <td>' . ($schuh['num'] != 0 ? $Pace->asMinPerKm() . '/km' : '-') . '</td> <td class="small">' . Distance::format($schuh['dist']) . '</td> <td class="small">' . $MaxPace->asMinPerKm() . '/km' . '</td> <td>' . $Shoe->getTimeString() . '</td> <td>' . $Shoe->getKmString() . '</td> <td class="small">' . $Shoe->getWeightString() . '</td> </tr>'; } } else { echo '<tr><td colspan="9">' . __('You don\'t have any shoes') . '</td></tr>'; } echo '</tbody>'; echo '</table>'; Ajax::createTablesorterFor("#list-of-all-shoes", true); }
/** * Parse all trackpoints for one lap * @param SimpleXMLElement $Lap */ protected function parseTrackpoints(&$Lap) { $this->lastPoint = 0; foreach ($Lap->Track as $Track) { if ($this->lastPoint > 0) { $this->lastPointWasEmpty = true; } if (count($Track->xpath('./Trackpoint')) > 0) { $this->distancesAreEmpty = count($Track->xpath('./Trackpoint/DistanceMeters')) == 0; if (strtotime((string) $Lap['StartTime']) + 8 < strtotime((string) $Track->Trackpoint[0]->Time)) { $this->lastPointWasEmpty = true; } foreach ($Track->Trackpoint as $Trackpoint) { $this->parseTrackpoint($Trackpoint); } } } if (self::$DEBUG_SPLITS) { Error::getInstance()->addDebug('computed: ' . Duration::format(end($this->gps['time_in_s'])) . ', ' . Distance::format(end($this->gps['km']))); } }
/** * Get string for km * @return string */ public function getKmString() { return Distance::format($this->getKm()); }
/** * Set boxed values */ protected function setBoxedValues() { $Distance = new Distance($this->Context->activity()->distance()); $this->BoxedValues = array(new BoxedValue(Helper::Unknown($Distance->string(false, false), '-.--'), $Distance->unit(), __('Distance')), new BoxedValue($this->Context->dataview()->duration()->string(), '', __('Time')), new BoxedValue($this->Context->dataview()->elapsedTime(), '', __('Elapsed time')), new BoxedValue($this->Context->dataview()->pace()->value(), $this->Context->dataview()->pace()->appendix(), __('Pace')), new BoxedValue(Helper::Unknown($this->Context->activity()->hrAvg(), '-'), 'bpm', __('ø Heartrate')), new BoxedValue(Helper::Unknown($this->Context->activity()->hrMax(), '-'), 'bpm', __('max. Heartrate')), new BoxedValue($this->Context->activity()->calories(), 'kcal', __('Calories')), new BoxedValue(Helper::Unknown($this->Context->dataview()->vdot()->value(), '-'), '', __('VDOT'), $this->Context->dataview()->vdotIcon()), new BoxedValue($this->Context->activity()->trimp(), '', __('TRIMP')), new Box\Elevation($this->Context)); }
/** * Display the table with most kilometer for each year/month/week */ private function displayMostKilometer() { echo '<table class="fullwidth zebra-style">'; echo '<thead><tr><th colspan="11" class="l">' . __('Most kilometers') . '</th></tr></thead>'; echo '<tbody>'; if (empty($this->weeks)) { echo '<tr><td colspan="11"><em>' . __('No data available') . '</em></td></tr>'; echo HTML::spaceTR(11); echo '</tbody>'; echo '</table>'; return; } // Years if ($this->year == -1) { echo '<tr class="r"><td class="c b">' . __('per year') . '</td>'; foreach ($this->years as $i => $year) { $link = DataBrowserLinker::link(Distance::format($year['km']), mktime(0, 0, 0, 1, 1, $year['year']), mktime(23, 59, 50, 12, 31, $year['year'])); echo '<td class="small"><span title="' . $year['year'] . '">' . $link . '</span></td>'; } for (; $i < 9; $i++) { echo HTML::emptyTD(); } echo '</tr>'; } // Months echo '<tr class="r"><td class="c b">' . __('per month') . '</td>'; foreach ($this->months as $i => $month) { $link = DataBrowserLinker::link(Distance::format($month['km']), mktime(0, 0, 0, $month['month'], 1, $month['year']), mktime(23, 59, 50, $month['month'] + 1, 0, $month['year'])); echo '<td class="small"><span title="' . Time::Month($month['month']) . ' ' . $month['year'] . '">' . $link . '</span></td>'; } for (; $i < 9; $i++) { echo HTML::emptyTD(); } echo '</tr>'; // Weeks echo '<tr class="r"><td class="c b">' . __('per week') . '</td>'; foreach ($this->weeks as $i => $week) { $link = DataBrowserLinker::link(Distance::format($week['km']), Time::Weekstart($week['time']), Time::Weekend($week['time'])); echo '<td class="small"><span title="' . __('Week') . ' ' . $week['week'] . ' ' . $week['year'] . '">' . $link . '</span></td>'; } for (; $i < 9; $i++) { echo HTML::emptyTD(); } echo '</tr>'; echo '</tbody>'; echo '</table>'; }
/** * Show prognosis for a given distance * @param double $distance */ protected function showPrognosis($distance) { $PB = new PersonalBest($distance); $PB->lookupWithDetails(); $PBTime = $PB->exists() ? Duration::format($PB->seconds()) : '-'; $PBString = $PB->exists() ? Ajax::trainingLink($PB->activityId(), $PBTime, true) : $PBTime; $Prognosis = new Duration($this->Prognosis->inSeconds($distance)); $Distance = new Distance($distance); $Pace = new Pace($Prognosis->seconds(), $distance, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); echo '<p> <span class="right"> ' . sprintf(__('<small>from</small> %s <small>to</small> <strong>%s</strong>'), $PBString, $Prognosis->string(Duration::FORMAT_AUTO, 0)) . ' <small>(' . $Pace->valueWithAppendix() . ')</small> </span> <strong>' . $Distance->stringAuto(true, 1) . '</strong> </p>'; }
/** * Show prognosis for a given distance * @param double $distance */ protected function showPrognosis($distance) { $PB = new PersonalBest($distance); $PBTime = $PB->exists() ? Duration::format($PB->seconds()) : '-'; $Prognosis = new Duration($this->Prognosis->inSeconds($distance)); $Distance = new Distance($distance); $Pace = new Pace($Prognosis->seconds(), $distance, Pace::MIN_PER_KM); echo '<p> <span class="right"> ' . sprintf(__('<small>from</small> %s <small>to</small> <strong>%s</strong>'), $PBTime, $Prognosis->string(Duration::FORMAT_AUTO, 0)) . ' <small>(' . $Pace->valueWithAppendix() . ')</small> </span> <strong>' . $Distance->string(Distance::FORMAT_AUTO, 1) . '</strong> </p>'; }
/** * Add line for average and goal */ protected function addAverage() { if ($this->showsAverage()) { $BasicEndurance = new BasicEndurance(); $BasicEndurance->readSettingsFromConfiguration(); $Result = $BasicEndurance->asArray(); $Avg = new Distance($this->factorForWeekKm() * $Result['weekkm-percentage'] * $BasicEndurance->getTargetWeekKm()); $Goal = new Distance($this->factorForWeekKm() * $BasicEndurance->getTargetWeekKm()); $LabelKeys = array_keys($this->getXLabels()); $this->addThreshold('y', round($Avg->valueInPreferredUnit()), '#999'); $this->addThreshold('y', round($Goal->valueInPreferredUnit()), '#999'); $this->addAnnotation(-1, round($Avg->valueInPreferredUnit()), __('avg:') . ' ' . $Avg->string(true, 0), 0, -10); $this->addAnnotation(end($LabelKeys), round($Goal->valueInPreferredUnit()), __('goal:') . ' ' . $Goal->string(true, 0), 0, -10); } }
/** * Show line * @param array $Line */ private function showLine(&$Line) { $span_format = isset($Line['lvl']) ? $this->getLevelStyle($Line['lvl']) : 0; $p_format = isset($Line['sep']) && $Line['sep'] ? ' style="border-top:1px solid #ccc;"' : ''; $NumberOfActivities = isset($Line['anz']) && $Line['anz'] > 0 ? '<small><small>(' . round($Line['anz'], 1) . 'x)</small></small>' : ''; $Distance = isset($Line['km']) && $Line['km'] > 0 ? '<span ' . ($Line['lvl'] == 1 ? $span_format : '') . '>' . Distance::format($Line['km'], true, 1) . '</span>' : ''; echo '<p' . $p_format . '>' . '<span class="right">' . $NumberOfActivities . ' ' . $Distance . '</span>' . '<span' . $span_format . '>' . $Line['name'] . '</span>' . '</p>'; }
/** * Display with corrector */ protected function displayWithElevation() { if ($this->Context->hasRoute() && ($this->Context->route()->elevationUp() > 0 || $this->Context->route()->elevationDown())) { $up = $this->Context->route()->elevationUp(); $down = $this->Context->route()->elevationDown(); } else { $up = $this->Context->activity()->elevation(); $down = $up; } $Modifier = new Elevation\DistanceModifier($this->Context->activity()->distance(), $up, $down, Configuration::Vdot()); $VDOT = new JD\VDOT(0, new JD\VDOTCorrector(Configuration::Data()->vdotFactor())); $VDOT->fromPaceAndHR($Modifier->correctedDistance(), $this->Context->activity()->duration(), $this->Context->activity()->hrAvg() / Configuration::Data()->HRmax()); $Fieldset = new FormularFieldset(__('Correction: considering elevation')); $Fieldset->setHtmlCode(' <p class="warning small ' . (Configuration::Vdot()->useElevationCorrection() ? 'hide' : '') . '"> ' . __('This correction method is currently unused.') . ' </p> <div class="w50"> <label>' . __('Up/Down') . '</label> <span class="as-input">+' . $up . '/-' . $down . ' m</span> </div> <div class="w50 double-height-right"> <label>⇒ ' . __('VDOT') . '</label> <span class="as-input ' . (!Configuration::Vdot()->useElevationCorrection() ? '' : 'highlight') . '">' . $VDOT->value() . '</span> </div> <div class="w50"> <label>' . __('Influence') . '</label> <span class="as-input">' . sprintf("%+d", 1000 * $Modifier->additionalDistance()) . 'm = ' . Distance::format($Modifier->correctedDistance(), false, 3) . '</span> </div> '); $Fieldset->display(); }